├── .cargo └── config.toml ├── .editorconfig ├── .gitattributes ├── .github └── workflows │ ├── check.yml │ ├── publish.yml │ └── release.yml ├── .gitignore ├── .vscode └── launch.json ├── CHANGELOG.md ├── Cargo.lock ├── Cargo.toml ├── LICENSE ├── README.md ├── cliff.toml ├── justfile ├── rust-toolchain.toml ├── rustfmt.toml ├── src ├── app.rs ├── common │ ├── mod.rs │ ├── point.rs │ ├── position.rs │ └── tetromino_kind.rs ├── consts.rs ├── global │ ├── assets │ │ ├── bg_music.mp3 │ │ ├── clear.mp3 │ │ ├── game_over.wav │ │ ├── lock.wav │ │ ├── menu.wav │ │ └── move.wav │ ├── audio.rs │ ├── mod.rs │ └── setting.rs ├── handler.rs ├── main.rs ├── save.rs ├── state │ ├── bag.rs │ ├── focus.rs │ ├── game_over_menu.rs │ ├── ghost_tetromino.rs │ ├── main_board.rs │ ├── mod.rs │ ├── next_board.rs │ ├── particles.rs │ ├── pause_menu.rs │ ├── scores.rs │ ├── setting_menu.rs │ ├── start_menu.rs │ ├── stats.rs │ └── tetromino.rs ├── term.rs └── ui │ ├── about.rs │ ├── board.rs │ ├── cell.rs │ ├── count_down.rs │ ├── game_over_menu.rs │ ├── help.rs │ ├── loading.rs │ ├── menu.rs │ ├── mod.rs │ ├── next_board.rs │ ├── particles.rs │ ├── pause_menu.rs │ ├── scores.rs │ ├── setting_menu.rs │ ├── sidebar.rs │ ├── start_menu.rs │ └── utils.rs └── taplo.toml /.cargo/config.toml: -------------------------------------------------------------------------------- 1 | [cargo-new] 2 | vcs = "none" 3 | -------------------------------------------------------------------------------- /.editorconfig: -------------------------------------------------------------------------------- 1 | root = true 2 | 3 | [*] 4 | charset = utf-8 5 | end_of_line = lf 6 | 7 | [*.{rs,toml}] 8 | indent_style = tab 9 | 10 | [justfile] 11 | indent_style = tab 12 | -------------------------------------------------------------------------------- /.gitattributes: -------------------------------------------------------------------------------- 1 | * text=auto eol=lf 2 | -------------------------------------------------------------------------------- /.github/workflows/check.yml: -------------------------------------------------------------------------------- 1 | name: Check 2 | 3 | on: 4 | workflow_dispatch: 5 | pull_request: 6 | push: 7 | branches: 8 | - main 9 | 10 | env: 11 | CARGO_TERM_COLOR: always 12 | CARGO_INCREMENTAL: 0 13 | 14 | jobs: 15 | check: 16 | runs-on: ${{ matrix.os }} 17 | name: check (${{ matrix.os }}) 18 | 19 | strategy: 20 | fail-fast: false 21 | matrix: 22 | include: 23 | - os: ubuntu-latest 24 | - os: windows-latest 25 | 26 | steps: 27 | - uses: actions/checkout@v4 28 | 29 | - uses: dtolnay/rust-toolchain@stable 30 | 31 | - name: Install Nightly 32 | run: cargo --version 33 | 34 | - uses: taiki-e/install-action@v2 35 | with: 36 | tool: just,taplo-cli 37 | 38 | - name: Extra 39 | if: matrix.os == 'ubuntu-latest' 40 | run: | 41 | sudo apt-get update 42 | sudo apt-get install libasound2-dev 43 | export PKG_CONFIG_PATH=$PKG_CONFIG_PATH:/usr/lib/pkgconfig:/usr/lib/x86_64-linux-gnu/pkgconfig 44 | 45 | - name: Run Check 46 | run: just check 47 | 48 | build: 49 | needs: check 50 | runs-on: ${{ matrix.os }} 51 | name: build (${{ matrix.target }}) 52 | 53 | strategy: 54 | fail-fast: false 55 | matrix: 56 | include: 57 | - os: macos-latest 58 | target: x86_64-apple-darwin 59 | - os: macos-latest 60 | target: aarch64-apple-darwin 61 | - os: ubuntu-latest 62 | target: x86_64-unknown-linux-gnu 63 | - os: windows-latest 64 | target: x86_64-pc-windows-msvc 65 | 66 | steps: 67 | - uses: actions/checkout@v4 68 | 69 | - name: Extra 70 | if: matrix.os == 'ubuntu-latest' 71 | run: | 72 | sudo apt-get update 73 | sudo apt-get install libasound2-dev 74 | export PKG_CONFIG_PATH=$PKG_CONFIG_PATH:/usr/lib/pkgconfig:/usr/lib/x86_64-linux-gnu/pkgconfig 75 | 76 | - name: Cargo Build 77 | run: | 78 | rustup +stable target add ${{ matrix.target }} 79 | cargo +stable build --target ${{ matrix.target }} 80 | -------------------------------------------------------------------------------- /.github/workflows/publish.yml: -------------------------------------------------------------------------------- 1 | name: Publish 2 | 3 | permissions: 4 | contents: write 5 | 6 | on: 7 | workflow_dispatch: 8 | 9 | env: 10 | CARGO_TERM_COLOR: always 11 | CARGO_INCREMENTAL: 0 12 | 13 | jobs: 14 | publish-crate: 15 | runs-on: ubuntu-latest 16 | 17 | steps: 18 | - uses: actions/checkout@v4 19 | 20 | - uses: dtolnay/rust-toolchain@stable 21 | 22 | - name: Extra 23 | run: | 24 | sudo apt-get update 25 | sudo apt-get install libasound2-dev 26 | export PKG_CONFIG_PATH=$PKG_CONFIG_PATH:/usr/lib/pkgconfig:/usr/lib/x86_64-linux-gnu/pkgconfig 27 | 28 | - name: Publish 29 | run: cargo +stable publish --token ${{ secrets.CARGO_REGISTRY_TOKEN }} 30 | -------------------------------------------------------------------------------- /.github/workflows/release.yml: -------------------------------------------------------------------------------- 1 | name: Release 2 | 3 | permissions: 4 | contents: write 5 | 6 | on: 7 | push: 8 | tags: 9 | - "[0-9]+.*" 10 | 11 | env: 12 | CARGO_TERM_COLOR: always 13 | CARGO_INCREMENTAL: 0 14 | 15 | jobs: 16 | create-release: 17 | runs-on: ubuntu-latest 18 | 19 | steps: 20 | - uses: actions/checkout@v4 21 | - uses: taiki-e/create-gh-release-action@v1 22 | with: 23 | changelog: CHANGELOG.md 24 | token: ${{ secrets.GITHUB_TOKEN }} 25 | 26 | upload-assets: 27 | needs: create-release 28 | runs-on: ${{ matrix.os }} 29 | name: upload-assets (${{ matrix.target }}) 30 | 31 | strategy: 32 | matrix: 33 | include: 34 | - os: macos-latest 35 | target: x86_64-apple-darwin 36 | - os: macos-latest 37 | target: aarch64-apple-darwin 38 | - os: ubuntu-latest 39 | target: x86_64-unknown-linux-gnu 40 | - os: windows-latest 41 | target: x86_64-pc-windows-msvc 42 | 43 | steps: 44 | - uses: actions/checkout@v4 45 | 46 | - uses: dtolnay/rust-toolchain@stable 47 | 48 | - name: Extra 49 | if: matrix.os == 'ubuntu-latest' 50 | run: | 51 | sudo apt-get update 52 | sudo apt-get install libasound2-dev 53 | export PKG_CONFIG_PATH=$PKG_CONFIG_PATH:/usr/lib/pkgconfig:/usr/lib/x86_64-linux-gnu/pkgconfig 54 | 55 | - uses: taiki-e/upload-rust-binary-action@v1 56 | with: 57 | bin: sxtetris 58 | target: ${{ matrix.target }} 59 | build-tool: cargo 60 | token: ${{ secrets.GITHUB_TOKEN }} 61 | archive: $bin-$tag-$target 62 | include: LICENSE,README.md 63 | 64 | publish-crate: 65 | needs: upload-assets 66 | runs-on: ubuntu-latest 67 | 68 | steps: 69 | - uses: actions/checkout@v4 70 | 71 | - uses: dtolnay/rust-toolchain@stable 72 | 73 | - name: Extra 74 | run: | 75 | sudo apt-get update 76 | sudo apt-get install libasound2-dev 77 | export PKG_CONFIG_PATH=$PKG_CONFIG_PATH:/usr/lib/pkgconfig:/usr/lib/x86_64-linux-gnu/pkgconfig 78 | 79 | - name: Publish 80 | run: cargo +stable publish --token ${{ secrets.CARGO_REGISTRY_TOKEN }} 81 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | .DS_Store 2 | /target 3 | /trace.log 4 | /save.json 5 | /bugs.md 6 | -------------------------------------------------------------------------------- /.vscode/launch.json: -------------------------------------------------------------------------------- 1 | { 2 | "version": "0.2.0", 3 | "configurations": [ 4 | { 5 | "type": "lldb", 6 | "request": "launch", 7 | "name": "debug", 8 | "cargo": { 9 | "args": ["run", "-F", "_dev"] 10 | }, 11 | "cwd": "${workspaceFolder}" 12 | } 13 | ] 14 | } 15 | -------------------------------------------------------------------------------- /CHANGELOG.md: -------------------------------------------------------------------------------- 1 | # Changelog 2 | 3 | All notable changes to this project will be documented in this file. 4 | 5 | ## [1.3.1] - 2024-07-21 6 | 7 | [ea59c2f](ea59c2fe5e3735d7e0c3d048e8ef9690de5e575d)...[449cefc](449cefcfd908fdfe1eaf9f5110cb87c8730badd2) 8 | 9 | ### Bug Fixes 10 | 11 | - Fix bug where there was always only one score (#26) ([0019767](00197670e38af39582d5a9e5d63fcba538508e91)) 12 | - Missed some sounds when stoping sound playback (#27) ([449cefc](449cefcfd908fdfe1eaf9f5110cb87c8730badd2)) 13 | 14 | ### Miscellaneous Tasks 15 | 16 | - Fix name (#24) ([61cd6ef](61cd6ef50bc7cb330f1902001eafed5317dba087)) 17 | - Remove needs (#25) ([a870fa3](a870fa3ef9f5dd7b42c49630e3ef05cdf459f1a5)) 18 | 19 | ## [1.3.0] - 2024-07-20 20 | 21 | [0c04f11](0c04f117159417eda4910e9687781392f6577e31)...[ea59c2f](ea59c2fe5e3735d7e0c3d048e8ef9690de5e575d) 22 | 23 | ### Features 24 | 25 | - Add background music and sound effects (#17) ([4a7cd9f](4a7cd9f0ecbfda115d412e1aa5bfce53ce3c1580)) 26 | - Add setting popup to turn particle effects, music and sound effects on or off (#18) ([ec2f740](ec2f740969bb8616e2752d7e2dbc5b69f73146e9)) 27 | - Add `--show-save-path` argument to see the save location when launch game (#21) ([3210a2e](3210a2ee4c47bf34ca8985fab4b7dc4cf76d27d4)) 28 | 29 | ### Refactor 30 | 31 | - Use json as save file format and it is not compatible for old save (#19) ([02f4a85](02f4a8507111fed6b333d1de76fa206d11b908d5)) 32 | - Refactor the logic of most parts of the code and elevate some state to global (#20) ([ddf0ba5](ddf0ba5b42be0ee3fcecaa7bae7555357fef5f24)) 33 | 34 | ## [1.2.0] - 2024-06-30 35 | 36 | [aad8989](aad8989a1dba85300bea4765357bbe835b7db6d1)...[0c04f11](0c04f117159417eda4910e9687781392f6577e31) 37 | 38 | ### Documentation 39 | 40 | - Add AUR instructions ([cfc965c](cfc965c1e2de5504f23d0758022e4d84e75d2ec0)) 41 | - Update demo video ([2663e2f](2663e2ff237da6f41700bb7032ac72aa70413467)) 42 | 43 | ### Features 44 | 45 | - Added animation and particle effects when clearing rows, tetriminos color improvement (#15) ([d416caf](d416cafee1da5e47d16a854b3e0b5bc955907ff3)) 46 | 47 | ### Refactor 48 | 49 | - Add popup builder and improve code some else (#14) ([b5140f9](b5140f94953317538d6ebedca03e5c64de439348)) 50 | 51 | ## [1.1.0] - 2024-06-23 52 | 53 | ### Bug Fixes 54 | 55 | - Bag shuffle ([127a738](127a7380ada4a31bd2c53365d31f71dd56ea8877)) 56 | 57 | ### Documentation 58 | 59 | - Update demo video ([e370f8e](e370f8e4bdbf1d76a088b012f9bc30df2c6dd440)) 60 | 61 | ### Features 62 | 63 | - Display version ([3f8e554](3f8e554f5d25b30fbe6fa37b311986e843eee244)) 64 | - Space key throttle ([dfcc3f1](dfcc3f1bd18825d1922bc625ff246506fd5de1eb)) 65 | 66 | 67 | -------------------------------------------------------------------------------- /Cargo.lock: -------------------------------------------------------------------------------- 1 | # This file is automatically @generated by Cargo. 2 | # It is not intended for manual editing. 3 | version = 3 4 | 5 | [[package]] 6 | name = "addr2line" 7 | version = "0.21.0" 8 | source = "registry+https://github.com/rust-lang/crates.io-index" 9 | checksum = "8a30b2e23b9e17a9f90641c7ab1549cd9b44f296d3ccbf309d2863cfe398a0cb" 10 | dependencies = [ 11 | "gimli", 12 | ] 13 | 14 | [[package]] 15 | name = "adler" 16 | version = "1.0.2" 17 | source = "registry+https://github.com/rust-lang/crates.io-index" 18 | checksum = "f26201604c87b1e01bd3d98f8d5d9a8fcbb815e8cedb41ffccbeb4bf593a35fe" 19 | 20 | [[package]] 21 | name = "ahash" 22 | version = "0.8.11" 23 | source = "registry+https://github.com/rust-lang/crates.io-index" 24 | checksum = "e89da841a80418a9b391ebaea17f5c112ffaaa96f621d2c285b5174da76b9011" 25 | dependencies = [ 26 | "cfg-if", 27 | "once_cell", 28 | "version_check", 29 | "zerocopy", 30 | ] 31 | 32 | [[package]] 33 | name = "aho-corasick" 34 | version = "1.1.3" 35 | source = "registry+https://github.com/rust-lang/crates.io-index" 36 | checksum = "8e60d3430d3a69478ad0993f19238d2df97c507009a52b3c10addcd7f6bcb916" 37 | dependencies = [ 38 | "memchr", 39 | ] 40 | 41 | [[package]] 42 | name = "allocator-api2" 43 | version = "0.2.16" 44 | source = "registry+https://github.com/rust-lang/crates.io-index" 45 | checksum = "0942ffc6dcaadf03badf6e6a2d0228460359d5e34b57ccdc720b7382dfbd5ec5" 46 | 47 | [[package]] 48 | name = "alsa" 49 | version = "0.9.0" 50 | source = "registry+https://github.com/rust-lang/crates.io-index" 51 | checksum = "37fe60779335388a88c01ac6c3be40304d1e349de3ada3b15f7808bb90fa9dce" 52 | dependencies = [ 53 | "alsa-sys", 54 | "bitflags 2.5.0", 55 | "libc", 56 | ] 57 | 58 | [[package]] 59 | name = "alsa-sys" 60 | version = "0.3.1" 61 | source = "registry+https://github.com/rust-lang/crates.io-index" 62 | checksum = "db8fee663d06c4e303404ef5f40488a53e062f89ba8bfed81f42325aafad1527" 63 | dependencies = [ 64 | "libc", 65 | "pkg-config", 66 | ] 67 | 68 | [[package]] 69 | name = "anyhow" 70 | version = "1.0.81" 71 | source = "registry+https://github.com/rust-lang/crates.io-index" 72 | checksum = "0952808a6c2afd1aa8947271f3a60f1a6763c7b912d210184c5149b5cf147247" 73 | 74 | [[package]] 75 | name = "arrayvec" 76 | version = "0.7.4" 77 | source = "registry+https://github.com/rust-lang/crates.io-index" 78 | checksum = "96d30a06541fbafbc7f82ed10c06164cfbd2c401138f6addd8404629c4b16711" 79 | 80 | [[package]] 81 | name = "autocfg" 82 | version = "1.1.0" 83 | source = "registry+https://github.com/rust-lang/crates.io-index" 84 | checksum = "d468802bab17cbc0cc575e9b053f41e72aa36bfa6b7f55e3529ffa43161b97fa" 85 | 86 | [[package]] 87 | name = "backtrace" 88 | version = "0.3.71" 89 | source = "registry+https://github.com/rust-lang/crates.io-index" 90 | checksum = "26b05800d2e817c8b3b4b54abd461726265fa9789ae34330622f2db9ee696f9d" 91 | dependencies = [ 92 | "addr2line", 93 | "cc", 94 | "cfg-if", 95 | "libc", 96 | "miniz_oxide", 97 | "object", 98 | "rustc-demangle", 99 | ] 100 | 101 | [[package]] 102 | name = "bindgen" 103 | version = "0.69.4" 104 | source = "registry+https://github.com/rust-lang/crates.io-index" 105 | checksum = "a00dc851838a2120612785d195287475a3ac45514741da670b735818822129a0" 106 | dependencies = [ 107 | "bitflags 2.5.0", 108 | "cexpr", 109 | "clang-sys", 110 | "itertools", 111 | "lazy_static", 112 | "lazycell", 113 | "proc-macro2", 114 | "quote", 115 | "regex", 116 | "rustc-hash", 117 | "shlex", 118 | "syn 2.0.55", 119 | ] 120 | 121 | [[package]] 122 | name = "bitflags" 123 | version = "1.3.2" 124 | source = "registry+https://github.com/rust-lang/crates.io-index" 125 | checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a" 126 | 127 | [[package]] 128 | name = "bitflags" 129 | version = "2.5.0" 130 | source = "registry+https://github.com/rust-lang/crates.io-index" 131 | checksum = "cf4b9d6a944f767f8e5e0db018570623c85f3d925ac718db4e06d0187adb21c1" 132 | 133 | [[package]] 134 | name = "bumpalo" 135 | version = "3.16.0" 136 | source = "registry+https://github.com/rust-lang/crates.io-index" 137 | checksum = "79296716171880943b8470b5f8d03aa55eb2e645a4874bdbb28adb49162e012c" 138 | 139 | [[package]] 140 | name = "bytemuck" 141 | version = "1.16.1" 142 | source = "registry+https://github.com/rust-lang/crates.io-index" 143 | checksum = "b236fc92302c97ed75b38da1f4917b5cdda4984745740f153a5d3059e48d725e" 144 | 145 | [[package]] 146 | name = "bytes" 147 | version = "1.6.0" 148 | source = "registry+https://github.com/rust-lang/crates.io-index" 149 | checksum = "514de17de45fdb8dc022b1a7975556c53c86f9f0aa5f534b98977b171857c2c9" 150 | 151 | [[package]] 152 | name = "cassowary" 153 | version = "0.3.0" 154 | source = "registry+https://github.com/rust-lang/crates.io-index" 155 | checksum = "df8670b8c7b9dae1793364eafadf7239c40d669904660c5960d74cfd80b46a53" 156 | 157 | [[package]] 158 | name = "castaway" 159 | version = "0.2.2" 160 | source = "registry+https://github.com/rust-lang/crates.io-index" 161 | checksum = "8a17ed5635fc8536268e5d4de1e22e81ac34419e5f052d4d51f4e01dcc263fcc" 162 | dependencies = [ 163 | "rustversion", 164 | ] 165 | 166 | [[package]] 167 | name = "cc" 168 | version = "1.0.90" 169 | source = "registry+https://github.com/rust-lang/crates.io-index" 170 | checksum = "8cd6604a82acf3039f1144f54b8eb34e91ffba622051189e71b781822d5ee1f5" 171 | dependencies = [ 172 | "jobserver", 173 | "libc", 174 | ] 175 | 176 | [[package]] 177 | name = "cesu8" 178 | version = "1.1.0" 179 | source = "registry+https://github.com/rust-lang/crates.io-index" 180 | checksum = "6d43a04d8753f35258c91f8ec639f792891f748a1edbd759cf1dcea3382ad83c" 181 | 182 | [[package]] 183 | name = "cexpr" 184 | version = "0.6.0" 185 | source = "registry+https://github.com/rust-lang/crates.io-index" 186 | checksum = "6fac387a98bb7c37292057cffc56d62ecb629900026402633ae9160df93a8766" 187 | dependencies = [ 188 | "nom", 189 | ] 190 | 191 | [[package]] 192 | name = "cfg-if" 193 | version = "1.0.0" 194 | source = "registry+https://github.com/rust-lang/crates.io-index" 195 | checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" 196 | 197 | [[package]] 198 | name = "clang-sys" 199 | version = "1.8.1" 200 | source = "registry+https://github.com/rust-lang/crates.io-index" 201 | checksum = "0b023947811758c97c59bf9d1c188fd619ad4718dcaa767947df1cadb14f39f4" 202 | dependencies = [ 203 | "glob", 204 | "libc", 205 | "libloading", 206 | ] 207 | 208 | [[package]] 209 | name = "combine" 210 | version = "4.6.7" 211 | source = "registry+https://github.com/rust-lang/crates.io-index" 212 | checksum = "ba5a308b75df32fe02788e748662718f03fde005016435c444eea572398219fd" 213 | dependencies = [ 214 | "bytes", 215 | "memchr", 216 | ] 217 | 218 | [[package]] 219 | name = "compact_str" 220 | version = "0.7.1" 221 | source = "registry+https://github.com/rust-lang/crates.io-index" 222 | checksum = "f86b9c4c00838774a6d902ef931eff7470720c51d90c2e32cfe15dc304737b3f" 223 | dependencies = [ 224 | "castaway", 225 | "cfg-if", 226 | "itoa", 227 | "ryu", 228 | "static_assertions", 229 | ] 230 | 231 | [[package]] 232 | name = "core-foundation-sys" 233 | version = "0.8.6" 234 | source = "registry+https://github.com/rust-lang/crates.io-index" 235 | checksum = "06ea2b9bc92be3c2baa9334a323ebca2d6f074ff852cd1d7b11064035cd3868f" 236 | 237 | [[package]] 238 | name = "coreaudio-rs" 239 | version = "0.11.3" 240 | source = "registry+https://github.com/rust-lang/crates.io-index" 241 | checksum = "321077172d79c662f64f5071a03120748d5bb652f5231570141be24cfcd2bace" 242 | dependencies = [ 243 | "bitflags 1.3.2", 244 | "core-foundation-sys", 245 | "coreaudio-sys", 246 | ] 247 | 248 | [[package]] 249 | name = "coreaudio-sys" 250 | version = "0.2.15" 251 | source = "registry+https://github.com/rust-lang/crates.io-index" 252 | checksum = "7f01585027057ff5f0a5bf276174ae4c1594a2c5bde93d5f46a016d76270f5a9" 253 | dependencies = [ 254 | "bindgen", 255 | ] 256 | 257 | [[package]] 258 | name = "cpal" 259 | version = "0.15.3" 260 | source = "registry+https://github.com/rust-lang/crates.io-index" 261 | checksum = "873dab07c8f743075e57f524c583985fbaf745602acbe916a01539364369a779" 262 | dependencies = [ 263 | "alsa", 264 | "core-foundation-sys", 265 | "coreaudio-rs", 266 | "dasp_sample", 267 | "jni", 268 | "js-sys", 269 | "libc", 270 | "mach2", 271 | "ndk", 272 | "ndk-context", 273 | "oboe", 274 | "wasm-bindgen", 275 | "wasm-bindgen-futures", 276 | "web-sys", 277 | "windows", 278 | ] 279 | 280 | [[package]] 281 | name = "crossterm" 282 | version = "0.27.0" 283 | source = "registry+https://github.com/rust-lang/crates.io-index" 284 | checksum = "f476fe445d41c9e991fd07515a6f463074b782242ccf4a5b7b1d1012e70824df" 285 | dependencies = [ 286 | "bitflags 2.5.0", 287 | "crossterm_winapi", 288 | "futures-core", 289 | "libc", 290 | "mio", 291 | "parking_lot", 292 | "signal-hook", 293 | "signal-hook-mio", 294 | "winapi", 295 | ] 296 | 297 | [[package]] 298 | name = "crossterm_winapi" 299 | version = "0.9.1" 300 | source = "registry+https://github.com/rust-lang/crates.io-index" 301 | checksum = "acdd7c62a3665c7f6830a51635d9ac9b23ed385797f70a83bb8bafe9c572ab2b" 302 | dependencies = [ 303 | "winapi", 304 | ] 305 | 306 | [[package]] 307 | name = "darling" 308 | version = "0.20.8" 309 | source = "registry+https://github.com/rust-lang/crates.io-index" 310 | checksum = "54e36fcd13ed84ffdfda6f5be89b31287cbb80c439841fe69e04841435464391" 311 | dependencies = [ 312 | "darling_core", 313 | "darling_macro", 314 | ] 315 | 316 | [[package]] 317 | name = "darling_core" 318 | version = "0.20.8" 319 | source = "registry+https://github.com/rust-lang/crates.io-index" 320 | checksum = "9c2cf1c23a687a1feeb728783b993c4e1ad83d99f351801977dd809b48d0a70f" 321 | dependencies = [ 322 | "fnv", 323 | "ident_case", 324 | "proc-macro2", 325 | "quote", 326 | "strsim", 327 | "syn 2.0.55", 328 | ] 329 | 330 | [[package]] 331 | name = "darling_macro" 332 | version = "0.20.8" 333 | source = "registry+https://github.com/rust-lang/crates.io-index" 334 | checksum = "a668eda54683121533a393014d8692171709ff57a7d61f187b6e782719f8933f" 335 | dependencies = [ 336 | "darling_core", 337 | "quote", 338 | "syn 2.0.55", 339 | ] 340 | 341 | [[package]] 342 | name = "dasp_sample" 343 | version = "0.11.0" 344 | source = "registry+https://github.com/rust-lang/crates.io-index" 345 | checksum = "0c87e182de0887fd5361989c677c4e8f5000cd9491d6d563161a8f3a5519fc7f" 346 | 347 | [[package]] 348 | name = "deranged" 349 | version = "0.3.11" 350 | source = "registry+https://github.com/rust-lang/crates.io-index" 351 | checksum = "b42b6fa04a440b495c8b04d0e71b707c585f83cb9cb28cf8cd0d976c315e31b4" 352 | dependencies = [ 353 | "powerfmt", 354 | ] 355 | 356 | [[package]] 357 | name = "derive_builder" 358 | version = "0.20.0" 359 | source = "registry+https://github.com/rust-lang/crates.io-index" 360 | checksum = "0350b5cb0331628a5916d6c5c0b72e97393b8b6b03b47a9284f4e7f5a405ffd7" 361 | dependencies = [ 362 | "derive_builder_macro", 363 | ] 364 | 365 | [[package]] 366 | name = "derive_builder_core" 367 | version = "0.20.0" 368 | source = "registry+https://github.com/rust-lang/crates.io-index" 369 | checksum = "d48cda787f839151732d396ac69e3473923d54312c070ee21e9effcaa8ca0b1d" 370 | dependencies = [ 371 | "darling", 372 | "proc-macro2", 373 | "quote", 374 | "syn 2.0.55", 375 | ] 376 | 377 | [[package]] 378 | name = "derive_builder_macro" 379 | version = "0.20.0" 380 | source = "registry+https://github.com/rust-lang/crates.io-index" 381 | checksum = "206868b8242f27cecce124c19fd88157fbd0dd334df2587f36417bafbc85097b" 382 | dependencies = [ 383 | "derive_builder_core", 384 | "syn 2.0.55", 385 | ] 386 | 387 | [[package]] 388 | name = "directories" 389 | version = "5.0.1" 390 | source = "registry+https://github.com/rust-lang/crates.io-index" 391 | checksum = "9a49173b84e034382284f27f1af4dcbbd231ffa358c0fe316541a7337f376a35" 392 | dependencies = [ 393 | "dirs-sys", 394 | ] 395 | 396 | [[package]] 397 | name = "dirs-sys" 398 | version = "0.4.1" 399 | source = "registry+https://github.com/rust-lang/crates.io-index" 400 | checksum = "520f05a5cbd335fae5a99ff7a6ab8627577660ee5cfd6a94a6a929b52ff0321c" 401 | dependencies = [ 402 | "libc", 403 | "option-ext", 404 | "redox_users", 405 | "windows-sys 0.48.0", 406 | ] 407 | 408 | [[package]] 409 | name = "either" 410 | version = "1.10.0" 411 | source = "registry+https://github.com/rust-lang/crates.io-index" 412 | checksum = "11157ac094ffbdde99aa67b23417ebdd801842852b500e395a45a9c0aac03e4a" 413 | 414 | [[package]] 415 | name = "encoding_rs" 416 | version = "0.8.34" 417 | source = "registry+https://github.com/rust-lang/crates.io-index" 418 | checksum = "b45de904aa0b010bce2ab45264d0631681847fa7b6f2eaa7dab7619943bc4f59" 419 | dependencies = [ 420 | "cfg-if", 421 | ] 422 | 423 | [[package]] 424 | name = "equivalent" 425 | version = "1.0.1" 426 | source = "registry+https://github.com/rust-lang/crates.io-index" 427 | checksum = "5443807d6dff69373d433ab9ef5378ad8df50ca6298caf15de6e52e24aaf54d5" 428 | 429 | [[package]] 430 | name = "fastrand" 431 | version = "2.0.2" 432 | source = "registry+https://github.com/rust-lang/crates.io-index" 433 | checksum = "658bd65b1cf4c852a3cc96f18a8ce7b5640f6b703f905c7d74532294c2a63984" 434 | 435 | [[package]] 436 | name = "fnv" 437 | version = "1.0.7" 438 | source = "registry+https://github.com/rust-lang/crates.io-index" 439 | checksum = "3f9eec918d3f24069decb9af1554cad7c880e2da24a9afd88aca000531ab82c1" 440 | 441 | [[package]] 442 | name = "font8x8" 443 | version = "0.3.1" 444 | source = "registry+https://github.com/rust-lang/crates.io-index" 445 | checksum = "875488b8711a968268c7cf5d139578713097ca4635a76044e8fe8eedf831d07e" 446 | 447 | [[package]] 448 | name = "futures-core" 449 | version = "0.3.30" 450 | source = "registry+https://github.com/rust-lang/crates.io-index" 451 | checksum = "dfc6580bb841c5a68e9ef15c77ccc837b40a7504914d52e47b8b0e9bbda25a1d" 452 | 453 | [[package]] 454 | name = "futures-macro" 455 | version = "0.3.30" 456 | source = "registry+https://github.com/rust-lang/crates.io-index" 457 | checksum = "87750cf4b7a4c0625b1529e4c543c2182106e4dedc60a2a6455e00d212c489ac" 458 | dependencies = [ 459 | "proc-macro2", 460 | "quote", 461 | "syn 2.0.55", 462 | ] 463 | 464 | [[package]] 465 | name = "futures-task" 466 | version = "0.3.30" 467 | source = "registry+https://github.com/rust-lang/crates.io-index" 468 | checksum = "38d84fa142264698cdce1a9f9172cf383a0c82de1bddcf3092901442c4097004" 469 | 470 | [[package]] 471 | name = "futures-util" 472 | version = "0.3.30" 473 | source = "registry+https://github.com/rust-lang/crates.io-index" 474 | checksum = "3d6401deb83407ab3da39eba7e33987a73c3df0c82b4bb5813ee871c19c41d48" 475 | dependencies = [ 476 | "futures-core", 477 | "futures-macro", 478 | "futures-task", 479 | "pin-project-lite", 480 | "pin-utils", 481 | "slab", 482 | ] 483 | 484 | [[package]] 485 | name = "getrandom" 486 | version = "0.2.14" 487 | source = "registry+https://github.com/rust-lang/crates.io-index" 488 | checksum = "94b22e06ecb0110981051723910cbf0b5f5e09a2062dd7663334ee79a9d1286c" 489 | dependencies = [ 490 | "cfg-if", 491 | "libc", 492 | "wasi", 493 | ] 494 | 495 | [[package]] 496 | name = "gimli" 497 | version = "0.28.1" 498 | source = "registry+https://github.com/rust-lang/crates.io-index" 499 | checksum = "4271d37baee1b8c7e4b708028c57d816cf9d2434acb33a549475f78c181f6253" 500 | 501 | [[package]] 502 | name = "glob" 503 | version = "0.3.1" 504 | source = "registry+https://github.com/rust-lang/crates.io-index" 505 | checksum = "d2fabcfbdc87f4758337ca535fb41a6d701b65693ce38287d856d1674551ec9b" 506 | 507 | [[package]] 508 | name = "hashbrown" 509 | version = "0.14.3" 510 | source = "registry+https://github.com/rust-lang/crates.io-index" 511 | checksum = "290f1a1d9242c78d09ce40a5e87e7554ee637af1351968159f4952f028f75604" 512 | dependencies = [ 513 | "ahash", 514 | "allocator-api2", 515 | ] 516 | 517 | [[package]] 518 | name = "heck" 519 | version = "0.4.1" 520 | source = "registry+https://github.com/rust-lang/crates.io-index" 521 | checksum = "95505c38b4572b2d910cecb0281560f54b440a19336cbbcb27bf6ce6adc6f5a8" 522 | 523 | [[package]] 524 | name = "hermit-abi" 525 | version = "0.3.9" 526 | source = "registry+https://github.com/rust-lang/crates.io-index" 527 | checksum = "d231dfb89cfffdbc30e7fc41579ed6066ad03abda9e567ccafae602b97ec5024" 528 | 529 | [[package]] 530 | name = "hound" 531 | version = "3.5.1" 532 | source = "registry+https://github.com/rust-lang/crates.io-index" 533 | checksum = "62adaabb884c94955b19907d60019f4e145d091c75345379e70d1ee696f7854f" 534 | 535 | [[package]] 536 | name = "ident_case" 537 | version = "1.0.1" 538 | source = "registry+https://github.com/rust-lang/crates.io-index" 539 | checksum = "b9e0384b61958566e926dc50660321d12159025e767c18e043daf26b70104c39" 540 | 541 | [[package]] 542 | name = "indexmap" 543 | version = "2.2.6" 544 | source = "registry+https://github.com/rust-lang/crates.io-index" 545 | checksum = "168fb715dda47215e360912c096649d23d58bf392ac62f73919e831745e40f26" 546 | dependencies = [ 547 | "equivalent", 548 | "hashbrown", 549 | ] 550 | 551 | [[package]] 552 | name = "indoc" 553 | version = "2.0.5" 554 | source = "registry+https://github.com/rust-lang/crates.io-index" 555 | checksum = "b248f5224d1d606005e02c97f5aa4e88eeb230488bcc03bc9ca4d7991399f2b5" 556 | 557 | [[package]] 558 | name = "itertools" 559 | version = "0.12.1" 560 | source = "registry+https://github.com/rust-lang/crates.io-index" 561 | checksum = "ba291022dbbd398a455acf126c1e341954079855bc60dfdda641363bd6922569" 562 | dependencies = [ 563 | "either", 564 | ] 565 | 566 | [[package]] 567 | name = "itoa" 568 | version = "1.0.10" 569 | source = "registry+https://github.com/rust-lang/crates.io-index" 570 | checksum = "b1a46d1a171d865aa5f83f92695765caa047a9b4cbae2cbf37dbd613a793fd4c" 571 | 572 | [[package]] 573 | name = "jni" 574 | version = "0.21.1" 575 | source = "registry+https://github.com/rust-lang/crates.io-index" 576 | checksum = "1a87aa2bb7d2af34197c04845522473242e1aa17c12f4935d5856491a7fb8c97" 577 | dependencies = [ 578 | "cesu8", 579 | "cfg-if", 580 | "combine", 581 | "jni-sys", 582 | "log", 583 | "thiserror", 584 | "walkdir", 585 | "windows-sys 0.45.0", 586 | ] 587 | 588 | [[package]] 589 | name = "jni-sys" 590 | version = "0.3.0" 591 | source = "registry+https://github.com/rust-lang/crates.io-index" 592 | checksum = "8eaf4bc02d17cbdd7ff4c7438cafcdf7fb9a4613313ad11b4f8fefe7d3fa0130" 593 | 594 | [[package]] 595 | name = "jobserver" 596 | version = "0.1.31" 597 | source = "registry+https://github.com/rust-lang/crates.io-index" 598 | checksum = "d2b099aaa34a9751c5bf0878add70444e1ed2dd73f347be99003d4577277de6e" 599 | dependencies = [ 600 | "libc", 601 | ] 602 | 603 | [[package]] 604 | name = "js-sys" 605 | version = "0.3.69" 606 | source = "registry+https://github.com/rust-lang/crates.io-index" 607 | checksum = "29c15563dc2726973df627357ce0c9ddddbea194836909d655df6a75d2cf296d" 608 | dependencies = [ 609 | "wasm-bindgen", 610 | ] 611 | 612 | [[package]] 613 | name = "lazy_static" 614 | version = "1.5.0" 615 | source = "registry+https://github.com/rust-lang/crates.io-index" 616 | checksum = "bbd2bcb4c963f2ddae06a2efc7e9f3591312473c50c6685e1f298068316e66fe" 617 | 618 | [[package]] 619 | name = "lazycell" 620 | version = "1.3.0" 621 | source = "registry+https://github.com/rust-lang/crates.io-index" 622 | checksum = "830d08ce1d1d941e6b30645f1a0eb5643013d835ce3779a5fc208261dbe10f55" 623 | 624 | [[package]] 625 | name = "libc" 626 | version = "0.2.153" 627 | source = "registry+https://github.com/rust-lang/crates.io-index" 628 | checksum = "9c198f91728a82281a64e1f4f9eeb25d82cb32a5de251c6bd1b5154d63a8e7bd" 629 | 630 | [[package]] 631 | name = "libloading" 632 | version = "0.8.4" 633 | source = "registry+https://github.com/rust-lang/crates.io-index" 634 | checksum = "e310b3a6b5907f99202fcdb4960ff45b93735d7c7d96b760fcff8db2dc0e103d" 635 | dependencies = [ 636 | "cfg-if", 637 | "windows-targets 0.52.4", 638 | ] 639 | 640 | [[package]] 641 | name = "libredox" 642 | version = "0.1.3" 643 | source = "registry+https://github.com/rust-lang/crates.io-index" 644 | checksum = "c0ff37bd590ca25063e35af745c343cb7a0271906fb7b37e4813e8f79f00268d" 645 | dependencies = [ 646 | "bitflags 2.5.0", 647 | "libc", 648 | ] 649 | 650 | [[package]] 651 | name = "lock_api" 652 | version = "0.4.11" 653 | source = "registry+https://github.com/rust-lang/crates.io-index" 654 | checksum = "3c168f8615b12bc01f9c17e2eb0cc07dcae1940121185446edc3744920e8ef45" 655 | dependencies = [ 656 | "autocfg", 657 | "scopeguard", 658 | ] 659 | 660 | [[package]] 661 | name = "log" 662 | version = "0.4.21" 663 | source = "registry+https://github.com/rust-lang/crates.io-index" 664 | checksum = "90ed8c1e510134f979dbc4f070f87d4313098b704861a105fe34231c70a3901c" 665 | 666 | [[package]] 667 | name = "lru" 668 | version = "0.12.3" 669 | source = "registry+https://github.com/rust-lang/crates.io-index" 670 | checksum = "d3262e75e648fce39813cb56ac41f3c3e3f65217ebf3844d818d1f9398cfb0dc" 671 | dependencies = [ 672 | "hashbrown", 673 | ] 674 | 675 | [[package]] 676 | name = "mach2" 677 | version = "0.4.2" 678 | source = "registry+https://github.com/rust-lang/crates.io-index" 679 | checksum = "19b955cdeb2a02b9117f121ce63aa52d08ade45de53e48fe6a38b39c10f6f709" 680 | dependencies = [ 681 | "libc", 682 | ] 683 | 684 | [[package]] 685 | name = "memchr" 686 | version = "2.7.2" 687 | source = "registry+https://github.com/rust-lang/crates.io-index" 688 | checksum = "6c8640c5d730cb13ebd907d8d04b52f55ac9a2eec55b440c8892f40d56c76c1d" 689 | 690 | [[package]] 691 | name = "minimal-lexical" 692 | version = "0.2.1" 693 | source = "registry+https://github.com/rust-lang/crates.io-index" 694 | checksum = "68354c5c6bd36d73ff3feceb05efa59b6acb7626617f4962be322a825e61f79a" 695 | 696 | [[package]] 697 | name = "miniz_oxide" 698 | version = "0.7.2" 699 | source = "registry+https://github.com/rust-lang/crates.io-index" 700 | checksum = "9d811f3e15f28568be3407c8e7fdb6514c1cda3cb30683f15b6a1a1dc4ea14a7" 701 | dependencies = [ 702 | "adler", 703 | ] 704 | 705 | [[package]] 706 | name = "mio" 707 | version = "0.8.11" 708 | source = "registry+https://github.com/rust-lang/crates.io-index" 709 | checksum = "a4a650543ca06a924e8b371db273b2756685faae30f8487da1b56505a8f78b0c" 710 | dependencies = [ 711 | "libc", 712 | "log", 713 | "wasi", 714 | "windows-sys 0.48.0", 715 | ] 716 | 717 | [[package]] 718 | name = "ndk" 719 | version = "0.8.0" 720 | source = "registry+https://github.com/rust-lang/crates.io-index" 721 | checksum = "2076a31b7010b17a38c01907c45b945e8f11495ee4dd588309718901b1f7a5b7" 722 | dependencies = [ 723 | "bitflags 2.5.0", 724 | "jni-sys", 725 | "log", 726 | "ndk-sys", 727 | "num_enum", 728 | "thiserror", 729 | ] 730 | 731 | [[package]] 732 | name = "ndk-context" 733 | version = "0.1.1" 734 | source = "registry+https://github.com/rust-lang/crates.io-index" 735 | checksum = "27b02d87554356db9e9a873add8782d4ea6e3e58ea071a9adb9a2e8ddb884a8b" 736 | 737 | [[package]] 738 | name = "ndk-sys" 739 | version = "0.5.0+25.2.9519653" 740 | source = "registry+https://github.com/rust-lang/crates.io-index" 741 | checksum = "8c196769dd60fd4f363e11d948139556a344e79d451aeb2fa2fd040738ef7691" 742 | dependencies = [ 743 | "jni-sys", 744 | ] 745 | 746 | [[package]] 747 | name = "nom" 748 | version = "7.1.3" 749 | source = "registry+https://github.com/rust-lang/crates.io-index" 750 | checksum = "d273983c5a657a70a3e8f2a01329822f3b8c8172b73826411a55751e404a0a4a" 751 | dependencies = [ 752 | "memchr", 753 | "minimal-lexical", 754 | ] 755 | 756 | [[package]] 757 | name = "num-conv" 758 | version = "0.1.0" 759 | source = "registry+https://github.com/rust-lang/crates.io-index" 760 | checksum = "51d515d32fb182ee37cda2ccdcb92950d6a3c2893aa280e540671c2cd0f3b1d9" 761 | 762 | [[package]] 763 | name = "num-derive" 764 | version = "0.4.2" 765 | source = "registry+https://github.com/rust-lang/crates.io-index" 766 | checksum = "ed3955f1a9c7c0c15e092f9c887db08b1fc683305fdf6eb6684f22555355e202" 767 | dependencies = [ 768 | "proc-macro2", 769 | "quote", 770 | "syn 2.0.55", 771 | ] 772 | 773 | [[package]] 774 | name = "num-traits" 775 | version = "0.2.19" 776 | source = "registry+https://github.com/rust-lang/crates.io-index" 777 | checksum = "071dfc062690e90b734c0b2273ce72ad0ffa95f0c74596bc250dcfd960262841" 778 | dependencies = [ 779 | "autocfg", 780 | ] 781 | 782 | [[package]] 783 | name = "num_cpus" 784 | version = "1.16.0" 785 | source = "registry+https://github.com/rust-lang/crates.io-index" 786 | checksum = "4161fcb6d602d4d2081af7c3a45852d875a03dd337a6bfdd6e06407b61342a43" 787 | dependencies = [ 788 | "hermit-abi", 789 | "libc", 790 | ] 791 | 792 | [[package]] 793 | name = "num_enum" 794 | version = "0.7.2" 795 | source = "registry+https://github.com/rust-lang/crates.io-index" 796 | checksum = "02339744ee7253741199f897151b38e72257d13802d4ee837285cc2990a90845" 797 | dependencies = [ 798 | "num_enum_derive", 799 | ] 800 | 801 | [[package]] 802 | name = "num_enum_derive" 803 | version = "0.7.2" 804 | source = "registry+https://github.com/rust-lang/crates.io-index" 805 | checksum = "681030a937600a36906c185595136d26abfebb4aa9c65701cefcaf8578bb982b" 806 | dependencies = [ 807 | "proc-macro-crate", 808 | "proc-macro2", 809 | "quote", 810 | "syn 2.0.55", 811 | ] 812 | 813 | [[package]] 814 | name = "num_threads" 815 | version = "0.1.7" 816 | source = "registry+https://github.com/rust-lang/crates.io-index" 817 | checksum = "5c7398b9c8b70908f6371f47ed36737907c87c52af34c268fed0bf0ceb92ead9" 818 | dependencies = [ 819 | "libc", 820 | ] 821 | 822 | [[package]] 823 | name = "object" 824 | version = "0.32.2" 825 | source = "registry+https://github.com/rust-lang/crates.io-index" 826 | checksum = "a6a622008b6e321afc04970976f62ee297fdbaa6f95318ca343e3eebb9648441" 827 | dependencies = [ 828 | "memchr", 829 | ] 830 | 831 | [[package]] 832 | name = "oboe" 833 | version = "0.6.1" 834 | source = "registry+https://github.com/rust-lang/crates.io-index" 835 | checksum = "e8b61bebd49e5d43f5f8cc7ee2891c16e0f41ec7954d36bcb6c14c5e0de867fb" 836 | dependencies = [ 837 | "jni", 838 | "ndk", 839 | "ndk-context", 840 | "num-derive", 841 | "num-traits", 842 | "oboe-sys", 843 | ] 844 | 845 | [[package]] 846 | name = "oboe-sys" 847 | version = "0.6.1" 848 | source = "registry+https://github.com/rust-lang/crates.io-index" 849 | checksum = "6c8bb09a4a2b1d668170cfe0a7d5bc103f8999fb316c98099b6a9939c9f2e79d" 850 | dependencies = [ 851 | "cc", 852 | ] 853 | 854 | [[package]] 855 | name = "once_cell" 856 | version = "1.19.0" 857 | source = "registry+https://github.com/rust-lang/crates.io-index" 858 | checksum = "3fdb12b2476b595f9358c5161aa467c2438859caa136dec86c26fdd2efe17b92" 859 | 860 | [[package]] 861 | name = "option-ext" 862 | version = "0.2.0" 863 | source = "registry+https://github.com/rust-lang/crates.io-index" 864 | checksum = "04744f49eae99ab78e0d5c0b603ab218f515ea8cfe5a456d7629ad883a3b6e7d" 865 | 866 | [[package]] 867 | name = "parking_lot" 868 | version = "0.12.1" 869 | source = "registry+https://github.com/rust-lang/crates.io-index" 870 | checksum = "3742b2c103b9f06bc9fff0a37ff4912935851bee6d36f3c02bcc755bcfec228f" 871 | dependencies = [ 872 | "lock_api", 873 | "parking_lot_core", 874 | ] 875 | 876 | [[package]] 877 | name = "parking_lot_core" 878 | version = "0.9.9" 879 | source = "registry+https://github.com/rust-lang/crates.io-index" 880 | checksum = "4c42a9226546d68acdd9c0a280d17ce19bfe27a46bf68784e4066115788d008e" 881 | dependencies = [ 882 | "cfg-if", 883 | "libc", 884 | "redox_syscall", 885 | "smallvec", 886 | "windows-targets 0.48.5", 887 | ] 888 | 889 | [[package]] 890 | name = "paste" 891 | version = "1.0.14" 892 | source = "registry+https://github.com/rust-lang/crates.io-index" 893 | checksum = "de3145af08024dea9fa9914f381a17b8fc6034dfb00f3a84013f7ff43f29ed4c" 894 | 895 | [[package]] 896 | name = "pin-project-lite" 897 | version = "0.2.13" 898 | source = "registry+https://github.com/rust-lang/crates.io-index" 899 | checksum = "8afb450f006bf6385ca15ef45d71d2288452bc3683ce2e2cacc0d18e4be60b58" 900 | 901 | [[package]] 902 | name = "pin-utils" 903 | version = "0.1.0" 904 | source = "registry+https://github.com/rust-lang/crates.io-index" 905 | checksum = "8b870d8c151b6f2fb93e84a13146138f05d02ed11c7e7c54f8826aaaf7c9f184" 906 | 907 | [[package]] 908 | name = "pkg-config" 909 | version = "0.3.30" 910 | source = "registry+https://github.com/rust-lang/crates.io-index" 911 | checksum = "d231b230927b5e4ad203db57bbcbee2802f6bce620b1e4a9024a07d94e2907ec" 912 | 913 | [[package]] 914 | name = "powerfmt" 915 | version = "0.2.0" 916 | source = "registry+https://github.com/rust-lang/crates.io-index" 917 | checksum = "439ee305def115ba05938db6eb1644ff94165c5ab5e9420d1c1bcedbba909391" 918 | 919 | [[package]] 920 | name = "proc-macro-crate" 921 | version = "3.1.0" 922 | source = "registry+https://github.com/rust-lang/crates.io-index" 923 | checksum = "6d37c51ca738a55da99dc0c4a34860fd675453b8b36209178c2249bb13651284" 924 | dependencies = [ 925 | "toml_edit", 926 | ] 927 | 928 | [[package]] 929 | name = "proc-macro2" 930 | version = "1.0.79" 931 | source = "registry+https://github.com/rust-lang/crates.io-index" 932 | checksum = "e835ff2298f5721608eb1a980ecaee1aef2c132bf95ecc026a11b7bf3c01c02e" 933 | dependencies = [ 934 | "unicode-ident", 935 | ] 936 | 937 | [[package]] 938 | name = "quote" 939 | version = "1.0.35" 940 | source = "registry+https://github.com/rust-lang/crates.io-index" 941 | checksum = "291ec9ab5efd934aaf503a6466c5d5251535d108ee747472c3977cc5acc868ef" 942 | dependencies = [ 943 | "proc-macro2", 944 | ] 945 | 946 | [[package]] 947 | name = "ratatui" 948 | version = "0.26.1" 949 | source = "registry+https://github.com/rust-lang/crates.io-index" 950 | checksum = "bcb12f8fbf6c62614b0d56eb352af54f6a22410c3b079eb53ee93c7b97dd31d8" 951 | dependencies = [ 952 | "bitflags 2.5.0", 953 | "cassowary", 954 | "compact_str", 955 | "crossterm", 956 | "indoc", 957 | "itertools", 958 | "lru", 959 | "paste", 960 | "stability", 961 | "strum", 962 | "unicode-segmentation", 963 | "unicode-width", 964 | ] 965 | 966 | [[package]] 967 | name = "redox_syscall" 968 | version = "0.4.1" 969 | source = "registry+https://github.com/rust-lang/crates.io-index" 970 | checksum = "4722d768eff46b75989dd134e5c353f0d6296e5aaa3132e776cbdb56be7731aa" 971 | dependencies = [ 972 | "bitflags 1.3.2", 973 | ] 974 | 975 | [[package]] 976 | name = "redox_users" 977 | version = "0.4.5" 978 | source = "registry+https://github.com/rust-lang/crates.io-index" 979 | checksum = "bd283d9651eeda4b2a83a43c1c91b266c40fd76ecd39a50a8c630ae69dc72891" 980 | dependencies = [ 981 | "getrandom", 982 | "libredox", 983 | "thiserror", 984 | ] 985 | 986 | [[package]] 987 | name = "regex" 988 | version = "1.10.5" 989 | source = "registry+https://github.com/rust-lang/crates.io-index" 990 | checksum = "b91213439dad192326a0d7c6ee3955910425f441d7038e0d6933b0aec5c4517f" 991 | dependencies = [ 992 | "aho-corasick", 993 | "memchr", 994 | "regex-automata", 995 | "regex-syntax", 996 | ] 997 | 998 | [[package]] 999 | name = "regex-automata" 1000 | version = "0.4.7" 1001 | source = "registry+https://github.com/rust-lang/crates.io-index" 1002 | checksum = "38caf58cc5ef2fed281f89292ef23f6365465ed9a41b7a7754eb4e26496c92df" 1003 | dependencies = [ 1004 | "aho-corasick", 1005 | "memchr", 1006 | "regex-syntax", 1007 | ] 1008 | 1009 | [[package]] 1010 | name = "regex-syntax" 1011 | version = "0.8.4" 1012 | source = "registry+https://github.com/rust-lang/crates.io-index" 1013 | checksum = "7a66a03ae7c801facd77a29370b4faec201768915ac14a721ba36f20bc9c209b" 1014 | 1015 | [[package]] 1016 | name = "rodio" 1017 | version = "0.19.0" 1018 | source = "registry+https://github.com/rust-lang/crates.io-index" 1019 | checksum = "6006a627c1a38d37f3d3a85c6575418cfe34a5392d60a686d0071e1c8d427acb" 1020 | dependencies = [ 1021 | "cpal", 1022 | "hound", 1023 | "symphonia", 1024 | "thiserror", 1025 | ] 1026 | 1027 | [[package]] 1028 | name = "rustc-demangle" 1029 | version = "0.1.23" 1030 | source = "registry+https://github.com/rust-lang/crates.io-index" 1031 | checksum = "d626bb9dae77e28219937af045c257c28bfd3f69333c512553507f5f9798cb76" 1032 | 1033 | [[package]] 1034 | name = "rustc-hash" 1035 | version = "1.1.0" 1036 | source = "registry+https://github.com/rust-lang/crates.io-index" 1037 | checksum = "08d43f7aa6b08d49f382cde6a7982047c3426db949b1424bc4b7ec9ae12c6ce2" 1038 | 1039 | [[package]] 1040 | name = "rustversion" 1041 | version = "1.0.14" 1042 | source = "registry+https://github.com/rust-lang/crates.io-index" 1043 | checksum = "7ffc183a10b4478d04cbbbfc96d0873219d962dd5accaff2ffbd4ceb7df837f4" 1044 | 1045 | [[package]] 1046 | name = "ryu" 1047 | version = "1.0.17" 1048 | source = "registry+https://github.com/rust-lang/crates.io-index" 1049 | checksum = "e86697c916019a8588c99b5fac3cead74ec0b4b819707a682fd4d23fa0ce1ba1" 1050 | 1051 | [[package]] 1052 | name = "same-file" 1053 | version = "1.0.6" 1054 | source = "registry+https://github.com/rust-lang/crates.io-index" 1055 | checksum = "93fc1dc3aaa9bfed95e02e6eadabb4baf7e3078b0bd1b4d7b6b0b68378900502" 1056 | dependencies = [ 1057 | "winapi-util", 1058 | ] 1059 | 1060 | [[package]] 1061 | name = "scopeguard" 1062 | version = "1.2.0" 1063 | source = "registry+https://github.com/rust-lang/crates.io-index" 1064 | checksum = "94143f37725109f92c262ed2cf5e59bce7498c01bcc1502d7b9afe439a4e9f49" 1065 | 1066 | [[package]] 1067 | name = "serde" 1068 | version = "1.0.204" 1069 | source = "registry+https://github.com/rust-lang/crates.io-index" 1070 | checksum = "bc76f558e0cbb2a839d37354c575f1dc3fdc6546b5be373ba43d95f231bf7c12" 1071 | dependencies = [ 1072 | "serde_derive", 1073 | ] 1074 | 1075 | [[package]] 1076 | name = "serde_derive" 1077 | version = "1.0.204" 1078 | source = "registry+https://github.com/rust-lang/crates.io-index" 1079 | checksum = "e0cd7e117be63d3c3678776753929474f3b04a43a080c744d6b0ae2a8c28e222" 1080 | dependencies = [ 1081 | "proc-macro2", 1082 | "quote", 1083 | "syn 2.0.55", 1084 | ] 1085 | 1086 | [[package]] 1087 | name = "serde_json" 1088 | version = "1.0.120" 1089 | source = "registry+https://github.com/rust-lang/crates.io-index" 1090 | checksum = "4e0d21c9a8cae1235ad58a00c11cb40d4b1e5c784f1ef2c537876ed6ffd8b7c5" 1091 | dependencies = [ 1092 | "itoa", 1093 | "ryu", 1094 | "serde", 1095 | ] 1096 | 1097 | [[package]] 1098 | name = "shlex" 1099 | version = "1.3.0" 1100 | source = "registry+https://github.com/rust-lang/crates.io-index" 1101 | checksum = "0fda2ff0d084019ba4d7c6f371c95d8fd75ce3524c3cb8fb653a3023f6323e64" 1102 | 1103 | [[package]] 1104 | name = "signal-hook" 1105 | version = "0.3.17" 1106 | source = "registry+https://github.com/rust-lang/crates.io-index" 1107 | checksum = "8621587d4798caf8eb44879d42e56b9a93ea5dcd315a6487c357130095b62801" 1108 | dependencies = [ 1109 | "libc", 1110 | "signal-hook-registry", 1111 | ] 1112 | 1113 | [[package]] 1114 | name = "signal-hook-mio" 1115 | version = "0.2.3" 1116 | source = "registry+https://github.com/rust-lang/crates.io-index" 1117 | checksum = "29ad2e15f37ec9a6cc544097b78a1ec90001e9f71b81338ca39f430adaca99af" 1118 | dependencies = [ 1119 | "libc", 1120 | "mio", 1121 | "signal-hook", 1122 | ] 1123 | 1124 | [[package]] 1125 | name = "signal-hook-registry" 1126 | version = "1.4.1" 1127 | source = "registry+https://github.com/rust-lang/crates.io-index" 1128 | checksum = "d8229b473baa5980ac72ef434c4415e70c4b5e71b423043adb4ba059f89c99a1" 1129 | dependencies = [ 1130 | "libc", 1131 | ] 1132 | 1133 | [[package]] 1134 | name = "simplelog" 1135 | version = "0.12.2" 1136 | source = "registry+https://github.com/rust-lang/crates.io-index" 1137 | checksum = "16257adbfaef1ee58b1363bdc0664c9b8e1e30aed86049635fb5f147d065a9c0" 1138 | dependencies = [ 1139 | "log", 1140 | "termcolor", 1141 | "time", 1142 | ] 1143 | 1144 | [[package]] 1145 | name = "slab" 1146 | version = "0.4.9" 1147 | source = "registry+https://github.com/rust-lang/crates.io-index" 1148 | checksum = "8f92a496fb766b417c996b9c5e57daf2f7ad3b0bebe1ccfca4856390e3d3bb67" 1149 | dependencies = [ 1150 | "autocfg", 1151 | ] 1152 | 1153 | [[package]] 1154 | name = "smallvec" 1155 | version = "1.13.2" 1156 | source = "registry+https://github.com/rust-lang/crates.io-index" 1157 | checksum = "3c5e1a9a646d36c3599cd173a41282daf47c44583ad367b8e6837255952e5c67" 1158 | 1159 | [[package]] 1160 | name = "stability" 1161 | version = "0.1.1" 1162 | source = "registry+https://github.com/rust-lang/crates.io-index" 1163 | checksum = "ebd1b177894da2a2d9120208c3386066af06a488255caabc5de8ddca22dbc3ce" 1164 | dependencies = [ 1165 | "quote", 1166 | "syn 1.0.109", 1167 | ] 1168 | 1169 | [[package]] 1170 | name = "static_assertions" 1171 | version = "1.1.0" 1172 | source = "registry+https://github.com/rust-lang/crates.io-index" 1173 | checksum = "a2eb9349b6444b326872e140eb1cf5e7c522154d69e7a0ffb0fb81c06b37543f" 1174 | 1175 | [[package]] 1176 | name = "strsim" 1177 | version = "0.10.0" 1178 | source = "registry+https://github.com/rust-lang/crates.io-index" 1179 | checksum = "73473c0e59e6d5812c5dfe2a064a6444949f089e20eec9a2e5506596494e4623" 1180 | 1181 | [[package]] 1182 | name = "strum" 1183 | version = "0.26.2" 1184 | source = "registry+https://github.com/rust-lang/crates.io-index" 1185 | checksum = "5d8cec3501a5194c432b2b7976db6b7d10ec95c253208b45f83f7136aa985e29" 1186 | dependencies = [ 1187 | "strum_macros", 1188 | ] 1189 | 1190 | [[package]] 1191 | name = "strum_macros" 1192 | version = "0.26.2" 1193 | source = "registry+https://github.com/rust-lang/crates.io-index" 1194 | checksum = "c6cf59daf282c0a494ba14fd21610a0325f9f90ec9d1231dea26bcb1d696c946" 1195 | dependencies = [ 1196 | "heck", 1197 | "proc-macro2", 1198 | "quote", 1199 | "rustversion", 1200 | "syn 2.0.55", 1201 | ] 1202 | 1203 | [[package]] 1204 | name = "sxtetris" 1205 | version = "1.3.1" 1206 | dependencies = [ 1207 | "anyhow", 1208 | "crossterm", 1209 | "directories", 1210 | "fastrand", 1211 | "futures-util", 1212 | "log", 1213 | "ratatui", 1214 | "rodio", 1215 | "serde", 1216 | "serde_json", 1217 | "simplelog", 1218 | "tokio", 1219 | "tui-big-text", 1220 | ] 1221 | 1222 | [[package]] 1223 | name = "symphonia" 1224 | version = "0.5.4" 1225 | source = "registry+https://github.com/rust-lang/crates.io-index" 1226 | checksum = "815c942ae7ee74737bb00f965fa5b5a2ac2ce7b6c01c0cc169bbeaf7abd5f5a9" 1227 | dependencies = [ 1228 | "lazy_static", 1229 | "symphonia-bundle-mp3", 1230 | "symphonia-core", 1231 | "symphonia-metadata", 1232 | ] 1233 | 1234 | [[package]] 1235 | name = "symphonia-bundle-mp3" 1236 | version = "0.5.4" 1237 | source = "registry+https://github.com/rust-lang/crates.io-index" 1238 | checksum = "c01c2aae70f0f1fb096b6f0ff112a930b1fb3626178fba3ae68b09dce71706d4" 1239 | dependencies = [ 1240 | "lazy_static", 1241 | "log", 1242 | "symphonia-core", 1243 | "symphonia-metadata", 1244 | ] 1245 | 1246 | [[package]] 1247 | name = "symphonia-core" 1248 | version = "0.5.4" 1249 | source = "registry+https://github.com/rust-lang/crates.io-index" 1250 | checksum = "798306779e3dc7d5231bd5691f5a813496dc79d3f56bf82e25789f2094e022c3" 1251 | dependencies = [ 1252 | "arrayvec", 1253 | "bitflags 1.3.2", 1254 | "bytemuck", 1255 | "lazy_static", 1256 | "log", 1257 | ] 1258 | 1259 | [[package]] 1260 | name = "symphonia-metadata" 1261 | version = "0.5.4" 1262 | source = "registry+https://github.com/rust-lang/crates.io-index" 1263 | checksum = "bc622b9841a10089c5b18e99eb904f4341615d5aa55bbf4eedde1be721a4023c" 1264 | dependencies = [ 1265 | "encoding_rs", 1266 | "lazy_static", 1267 | "log", 1268 | "symphonia-core", 1269 | ] 1270 | 1271 | [[package]] 1272 | name = "syn" 1273 | version = "1.0.109" 1274 | source = "registry+https://github.com/rust-lang/crates.io-index" 1275 | checksum = "72b64191b275b66ffe2469e8af2c1cfe3bafa67b529ead792a6d0160888b4237" 1276 | dependencies = [ 1277 | "proc-macro2", 1278 | "quote", 1279 | "unicode-ident", 1280 | ] 1281 | 1282 | [[package]] 1283 | name = "syn" 1284 | version = "2.0.55" 1285 | source = "registry+https://github.com/rust-lang/crates.io-index" 1286 | checksum = "002a1b3dbf967edfafc32655d0f377ab0bb7b994aa1d32c8cc7e9b8bf3ebb8f0" 1287 | dependencies = [ 1288 | "proc-macro2", 1289 | "quote", 1290 | "unicode-ident", 1291 | ] 1292 | 1293 | [[package]] 1294 | name = "termcolor" 1295 | version = "1.4.1" 1296 | source = "registry+https://github.com/rust-lang/crates.io-index" 1297 | checksum = "06794f8f6c5c898b3275aebefa6b8a1cb24cd2c6c79397ab15774837a0bc5755" 1298 | dependencies = [ 1299 | "winapi-util", 1300 | ] 1301 | 1302 | [[package]] 1303 | name = "thiserror" 1304 | version = "1.0.61" 1305 | source = "registry+https://github.com/rust-lang/crates.io-index" 1306 | checksum = "c546c80d6be4bc6a00c0f01730c08df82eaa7a7a61f11d656526506112cc1709" 1307 | dependencies = [ 1308 | "thiserror-impl", 1309 | ] 1310 | 1311 | [[package]] 1312 | name = "thiserror-impl" 1313 | version = "1.0.61" 1314 | source = "registry+https://github.com/rust-lang/crates.io-index" 1315 | checksum = "46c3384250002a6d5af4d114f2845d37b57521033f30d5c3f46c4d70e1197533" 1316 | dependencies = [ 1317 | "proc-macro2", 1318 | "quote", 1319 | "syn 2.0.55", 1320 | ] 1321 | 1322 | [[package]] 1323 | name = "time" 1324 | version = "0.3.36" 1325 | source = "registry+https://github.com/rust-lang/crates.io-index" 1326 | checksum = "5dfd88e563464686c916c7e46e623e520ddc6d79fa6641390f2e3fa86e83e885" 1327 | dependencies = [ 1328 | "deranged", 1329 | "itoa", 1330 | "libc", 1331 | "num-conv", 1332 | "num_threads", 1333 | "powerfmt", 1334 | "serde", 1335 | "time-core", 1336 | "time-macros", 1337 | ] 1338 | 1339 | [[package]] 1340 | name = "time-core" 1341 | version = "0.1.2" 1342 | source = "registry+https://github.com/rust-lang/crates.io-index" 1343 | checksum = "ef927ca75afb808a4d64dd374f00a2adf8d0fcff8e7b184af886c3c87ec4a3f3" 1344 | 1345 | [[package]] 1346 | name = "time-macros" 1347 | version = "0.2.18" 1348 | source = "registry+https://github.com/rust-lang/crates.io-index" 1349 | checksum = "3f252a68540fde3a3877aeea552b832b40ab9a69e318efd078774a01ddee1ccf" 1350 | dependencies = [ 1351 | "num-conv", 1352 | "time-core", 1353 | ] 1354 | 1355 | [[package]] 1356 | name = "tokio" 1357 | version = "1.37.0" 1358 | source = "registry+https://github.com/rust-lang/crates.io-index" 1359 | checksum = "1adbebffeca75fcfd058afa480fb6c0b81e165a0323f9c9d39c9697e37c46787" 1360 | dependencies = [ 1361 | "backtrace", 1362 | "num_cpus", 1363 | "pin-project-lite", 1364 | "tokio-macros", 1365 | ] 1366 | 1367 | [[package]] 1368 | name = "tokio-macros" 1369 | version = "2.2.0" 1370 | source = "registry+https://github.com/rust-lang/crates.io-index" 1371 | checksum = "5b8a1e28f2deaa14e508979454cb3a223b10b938b45af148bc0986de36f1923b" 1372 | dependencies = [ 1373 | "proc-macro2", 1374 | "quote", 1375 | "syn 2.0.55", 1376 | ] 1377 | 1378 | [[package]] 1379 | name = "toml_datetime" 1380 | version = "0.6.6" 1381 | source = "registry+https://github.com/rust-lang/crates.io-index" 1382 | checksum = "4badfd56924ae69bcc9039335b2e017639ce3f9b001c393c1b2d1ef846ce2cbf" 1383 | 1384 | [[package]] 1385 | name = "toml_edit" 1386 | version = "0.21.1" 1387 | source = "registry+https://github.com/rust-lang/crates.io-index" 1388 | checksum = "6a8534fd7f78b5405e860340ad6575217ce99f38d4d5c8f2442cb5ecb50090e1" 1389 | dependencies = [ 1390 | "indexmap", 1391 | "toml_datetime", 1392 | "winnow", 1393 | ] 1394 | 1395 | [[package]] 1396 | name = "tui-big-text" 1397 | version = "0.4.2" 1398 | source = "registry+https://github.com/rust-lang/crates.io-index" 1399 | checksum = "800784c2ec32293c259c42bfb7352061dcfc672ae8f317e4d08e5292c49c19bb" 1400 | dependencies = [ 1401 | "derive_builder", 1402 | "font8x8", 1403 | "itertools", 1404 | "ratatui", 1405 | ] 1406 | 1407 | [[package]] 1408 | name = "unicode-ident" 1409 | version = "1.0.12" 1410 | source = "registry+https://github.com/rust-lang/crates.io-index" 1411 | checksum = "3354b9ac3fae1ff6755cb6db53683adb661634f67557942dea4facebec0fee4b" 1412 | 1413 | [[package]] 1414 | name = "unicode-segmentation" 1415 | version = "1.11.0" 1416 | source = "registry+https://github.com/rust-lang/crates.io-index" 1417 | checksum = "d4c87d22b6e3f4a18d4d40ef354e97c90fcb14dd91d7dc0aa9d8a1172ebf7202" 1418 | 1419 | [[package]] 1420 | name = "unicode-width" 1421 | version = "0.1.11" 1422 | source = "registry+https://github.com/rust-lang/crates.io-index" 1423 | checksum = "e51733f11c9c4f72aa0c160008246859e340b00807569a0da0e7a1079b27ba85" 1424 | 1425 | [[package]] 1426 | name = "version_check" 1427 | version = "0.9.4" 1428 | source = "registry+https://github.com/rust-lang/crates.io-index" 1429 | checksum = "49874b5167b65d7193b8aba1567f5c7d93d001cafc34600cee003eda787e483f" 1430 | 1431 | [[package]] 1432 | name = "walkdir" 1433 | version = "2.5.0" 1434 | source = "registry+https://github.com/rust-lang/crates.io-index" 1435 | checksum = "29790946404f91d9c5d06f9874efddea1dc06c5efe94541a7d6863108e3a5e4b" 1436 | dependencies = [ 1437 | "same-file", 1438 | "winapi-util", 1439 | ] 1440 | 1441 | [[package]] 1442 | name = "wasi" 1443 | version = "0.11.0+wasi-snapshot-preview1" 1444 | source = "registry+https://github.com/rust-lang/crates.io-index" 1445 | checksum = "9c8d87e72b64a3b4db28d11ce29237c246188f4f51057d65a7eab63b7987e423" 1446 | 1447 | [[package]] 1448 | name = "wasm-bindgen" 1449 | version = "0.2.92" 1450 | source = "registry+https://github.com/rust-lang/crates.io-index" 1451 | checksum = "4be2531df63900aeb2bca0daaaddec08491ee64ceecbee5076636a3b026795a8" 1452 | dependencies = [ 1453 | "cfg-if", 1454 | "wasm-bindgen-macro", 1455 | ] 1456 | 1457 | [[package]] 1458 | name = "wasm-bindgen-backend" 1459 | version = "0.2.92" 1460 | source = "registry+https://github.com/rust-lang/crates.io-index" 1461 | checksum = "614d787b966d3989fa7bb98a654e369c762374fd3213d212cfc0251257e747da" 1462 | dependencies = [ 1463 | "bumpalo", 1464 | "log", 1465 | "once_cell", 1466 | "proc-macro2", 1467 | "quote", 1468 | "syn 2.0.55", 1469 | "wasm-bindgen-shared", 1470 | ] 1471 | 1472 | [[package]] 1473 | name = "wasm-bindgen-futures" 1474 | version = "0.4.42" 1475 | source = "registry+https://github.com/rust-lang/crates.io-index" 1476 | checksum = "76bc14366121efc8dbb487ab05bcc9d346b3b5ec0eaa76e46594cabbe51762c0" 1477 | dependencies = [ 1478 | "cfg-if", 1479 | "js-sys", 1480 | "wasm-bindgen", 1481 | "web-sys", 1482 | ] 1483 | 1484 | [[package]] 1485 | name = "wasm-bindgen-macro" 1486 | version = "0.2.92" 1487 | source = "registry+https://github.com/rust-lang/crates.io-index" 1488 | checksum = "a1f8823de937b71b9460c0c34e25f3da88250760bec0ebac694b49997550d726" 1489 | dependencies = [ 1490 | "quote", 1491 | "wasm-bindgen-macro-support", 1492 | ] 1493 | 1494 | [[package]] 1495 | name = "wasm-bindgen-macro-support" 1496 | version = "0.2.92" 1497 | source = "registry+https://github.com/rust-lang/crates.io-index" 1498 | checksum = "e94f17b526d0a461a191c78ea52bbce64071ed5c04c9ffe424dcb38f74171bb7" 1499 | dependencies = [ 1500 | "proc-macro2", 1501 | "quote", 1502 | "syn 2.0.55", 1503 | "wasm-bindgen-backend", 1504 | "wasm-bindgen-shared", 1505 | ] 1506 | 1507 | [[package]] 1508 | name = "wasm-bindgen-shared" 1509 | version = "0.2.92" 1510 | source = "registry+https://github.com/rust-lang/crates.io-index" 1511 | checksum = "af190c94f2773fdb3729c55b007a722abb5384da03bc0986df4c289bf5567e96" 1512 | 1513 | [[package]] 1514 | name = "web-sys" 1515 | version = "0.3.69" 1516 | source = "registry+https://github.com/rust-lang/crates.io-index" 1517 | checksum = "77afa9a11836342370f4817622a2f0f418b134426d91a82dfb48f532d2ec13ef" 1518 | dependencies = [ 1519 | "js-sys", 1520 | "wasm-bindgen", 1521 | ] 1522 | 1523 | [[package]] 1524 | name = "winapi" 1525 | version = "0.3.9" 1526 | source = "registry+https://github.com/rust-lang/crates.io-index" 1527 | checksum = "5c839a674fcd7a98952e593242ea400abe93992746761e38641405d28b00f419" 1528 | dependencies = [ 1529 | "winapi-i686-pc-windows-gnu", 1530 | "winapi-x86_64-pc-windows-gnu", 1531 | ] 1532 | 1533 | [[package]] 1534 | name = "winapi-i686-pc-windows-gnu" 1535 | version = "0.4.0" 1536 | source = "registry+https://github.com/rust-lang/crates.io-index" 1537 | checksum = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6" 1538 | 1539 | [[package]] 1540 | name = "winapi-util" 1541 | version = "0.1.8" 1542 | source = "registry+https://github.com/rust-lang/crates.io-index" 1543 | checksum = "4d4cc384e1e73b93bafa6fb4f1df8c41695c8a91cf9c4c64358067d15a7b6c6b" 1544 | dependencies = [ 1545 | "windows-sys 0.52.0", 1546 | ] 1547 | 1548 | [[package]] 1549 | name = "winapi-x86_64-pc-windows-gnu" 1550 | version = "0.4.0" 1551 | source = "registry+https://github.com/rust-lang/crates.io-index" 1552 | checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f" 1553 | 1554 | [[package]] 1555 | name = "windows" 1556 | version = "0.54.0" 1557 | source = "registry+https://github.com/rust-lang/crates.io-index" 1558 | checksum = "9252e5725dbed82865af151df558e754e4a3c2c30818359eb17465f1346a1b49" 1559 | dependencies = [ 1560 | "windows-core", 1561 | "windows-targets 0.52.4", 1562 | ] 1563 | 1564 | [[package]] 1565 | name = "windows-core" 1566 | version = "0.54.0" 1567 | source = "registry+https://github.com/rust-lang/crates.io-index" 1568 | checksum = "12661b9c89351d684a50a8a643ce5f608e20243b9fb84687800163429f161d65" 1569 | dependencies = [ 1570 | "windows-result", 1571 | "windows-targets 0.52.4", 1572 | ] 1573 | 1574 | [[package]] 1575 | name = "windows-result" 1576 | version = "0.1.0" 1577 | source = "registry+https://github.com/rust-lang/crates.io-index" 1578 | checksum = "cd19df78e5168dfb0aedc343d1d1b8d422ab2db6756d2dc3fef75035402a3f64" 1579 | dependencies = [ 1580 | "windows-targets 0.52.4", 1581 | ] 1582 | 1583 | [[package]] 1584 | name = "windows-sys" 1585 | version = "0.45.0" 1586 | source = "registry+https://github.com/rust-lang/crates.io-index" 1587 | checksum = "75283be5efb2831d37ea142365f009c02ec203cd29a3ebecbc093d52315b66d0" 1588 | dependencies = [ 1589 | "windows-targets 0.42.2", 1590 | ] 1591 | 1592 | [[package]] 1593 | name = "windows-sys" 1594 | version = "0.48.0" 1595 | source = "registry+https://github.com/rust-lang/crates.io-index" 1596 | checksum = "677d2418bec65e3338edb076e806bc1ec15693c5d0104683f2efe857f61056a9" 1597 | dependencies = [ 1598 | "windows-targets 0.48.5", 1599 | ] 1600 | 1601 | [[package]] 1602 | name = "windows-sys" 1603 | version = "0.52.0" 1604 | source = "registry+https://github.com/rust-lang/crates.io-index" 1605 | checksum = "282be5f36a8ce781fad8c8ae18fa3f9beff57ec1b52cb3de0789201425d9a33d" 1606 | dependencies = [ 1607 | "windows-targets 0.52.4", 1608 | ] 1609 | 1610 | [[package]] 1611 | name = "windows-targets" 1612 | version = "0.42.2" 1613 | source = "registry+https://github.com/rust-lang/crates.io-index" 1614 | checksum = "8e5180c00cd44c9b1c88adb3693291f1cd93605ded80c250a75d472756b4d071" 1615 | dependencies = [ 1616 | "windows_aarch64_gnullvm 0.42.2", 1617 | "windows_aarch64_msvc 0.42.2", 1618 | "windows_i686_gnu 0.42.2", 1619 | "windows_i686_msvc 0.42.2", 1620 | "windows_x86_64_gnu 0.42.2", 1621 | "windows_x86_64_gnullvm 0.42.2", 1622 | "windows_x86_64_msvc 0.42.2", 1623 | ] 1624 | 1625 | [[package]] 1626 | name = "windows-targets" 1627 | version = "0.48.5" 1628 | source = "registry+https://github.com/rust-lang/crates.io-index" 1629 | checksum = "9a2fa6e2155d7247be68c096456083145c183cbbbc2764150dda45a87197940c" 1630 | dependencies = [ 1631 | "windows_aarch64_gnullvm 0.48.5", 1632 | "windows_aarch64_msvc 0.48.5", 1633 | "windows_i686_gnu 0.48.5", 1634 | "windows_i686_msvc 0.48.5", 1635 | "windows_x86_64_gnu 0.48.5", 1636 | "windows_x86_64_gnullvm 0.48.5", 1637 | "windows_x86_64_msvc 0.48.5", 1638 | ] 1639 | 1640 | [[package]] 1641 | name = "windows-targets" 1642 | version = "0.52.4" 1643 | source = "registry+https://github.com/rust-lang/crates.io-index" 1644 | checksum = "7dd37b7e5ab9018759f893a1952c9420d060016fc19a472b4bb20d1bdd694d1b" 1645 | dependencies = [ 1646 | "windows_aarch64_gnullvm 0.52.4", 1647 | "windows_aarch64_msvc 0.52.4", 1648 | "windows_i686_gnu 0.52.4", 1649 | "windows_i686_msvc 0.52.4", 1650 | "windows_x86_64_gnu 0.52.4", 1651 | "windows_x86_64_gnullvm 0.52.4", 1652 | "windows_x86_64_msvc 0.52.4", 1653 | ] 1654 | 1655 | [[package]] 1656 | name = "windows_aarch64_gnullvm" 1657 | version = "0.42.2" 1658 | source = "registry+https://github.com/rust-lang/crates.io-index" 1659 | checksum = "597a5118570b68bc08d8d59125332c54f1ba9d9adeedeef5b99b02ba2b0698f8" 1660 | 1661 | [[package]] 1662 | name = "windows_aarch64_gnullvm" 1663 | version = "0.48.5" 1664 | source = "registry+https://github.com/rust-lang/crates.io-index" 1665 | checksum = "2b38e32f0abccf9987a4e3079dfb67dcd799fb61361e53e2882c3cbaf0d905d8" 1666 | 1667 | [[package]] 1668 | name = "windows_aarch64_gnullvm" 1669 | version = "0.52.4" 1670 | source = "registry+https://github.com/rust-lang/crates.io-index" 1671 | checksum = "bcf46cf4c365c6f2d1cc93ce535f2c8b244591df96ceee75d8e83deb70a9cac9" 1672 | 1673 | [[package]] 1674 | name = "windows_aarch64_msvc" 1675 | version = "0.42.2" 1676 | source = "registry+https://github.com/rust-lang/crates.io-index" 1677 | checksum = "e08e8864a60f06ef0d0ff4ba04124db8b0fb3be5776a5cd47641e942e58c4d43" 1678 | 1679 | [[package]] 1680 | name = "windows_aarch64_msvc" 1681 | version = "0.48.5" 1682 | source = "registry+https://github.com/rust-lang/crates.io-index" 1683 | checksum = "dc35310971f3b2dbbf3f0690a219f40e2d9afcf64f9ab7cc1be722937c26b4bc" 1684 | 1685 | [[package]] 1686 | name = "windows_aarch64_msvc" 1687 | version = "0.52.4" 1688 | source = "registry+https://github.com/rust-lang/crates.io-index" 1689 | checksum = "da9f259dd3bcf6990b55bffd094c4f7235817ba4ceebde8e6d11cd0c5633b675" 1690 | 1691 | [[package]] 1692 | name = "windows_i686_gnu" 1693 | version = "0.42.2" 1694 | source = "registry+https://github.com/rust-lang/crates.io-index" 1695 | checksum = "c61d927d8da41da96a81f029489353e68739737d3beca43145c8afec9a31a84f" 1696 | 1697 | [[package]] 1698 | name = "windows_i686_gnu" 1699 | version = "0.48.5" 1700 | source = "registry+https://github.com/rust-lang/crates.io-index" 1701 | checksum = "a75915e7def60c94dcef72200b9a8e58e5091744960da64ec734a6c6e9b3743e" 1702 | 1703 | [[package]] 1704 | name = "windows_i686_gnu" 1705 | version = "0.52.4" 1706 | source = "registry+https://github.com/rust-lang/crates.io-index" 1707 | checksum = "b474d8268f99e0995f25b9f095bc7434632601028cf86590aea5c8a5cb7801d3" 1708 | 1709 | [[package]] 1710 | name = "windows_i686_msvc" 1711 | version = "0.42.2" 1712 | source = "registry+https://github.com/rust-lang/crates.io-index" 1713 | checksum = "44d840b6ec649f480a41c8d80f9c65108b92d89345dd94027bfe06ac444d1060" 1714 | 1715 | [[package]] 1716 | name = "windows_i686_msvc" 1717 | version = "0.48.5" 1718 | source = "registry+https://github.com/rust-lang/crates.io-index" 1719 | checksum = "8f55c233f70c4b27f66c523580f78f1004e8b5a8b659e05a4eb49d4166cca406" 1720 | 1721 | [[package]] 1722 | name = "windows_i686_msvc" 1723 | version = "0.52.4" 1724 | source = "registry+https://github.com/rust-lang/crates.io-index" 1725 | checksum = "1515e9a29e5bed743cb4415a9ecf5dfca648ce85ee42e15873c3cd8610ff8e02" 1726 | 1727 | [[package]] 1728 | name = "windows_x86_64_gnu" 1729 | version = "0.42.2" 1730 | source = "registry+https://github.com/rust-lang/crates.io-index" 1731 | checksum = "8de912b8b8feb55c064867cf047dda097f92d51efad5b491dfb98f6bbb70cb36" 1732 | 1733 | [[package]] 1734 | name = "windows_x86_64_gnu" 1735 | version = "0.48.5" 1736 | source = "registry+https://github.com/rust-lang/crates.io-index" 1737 | checksum = "53d40abd2583d23e4718fddf1ebec84dbff8381c07cae67ff7768bbf19c6718e" 1738 | 1739 | [[package]] 1740 | name = "windows_x86_64_gnu" 1741 | version = "0.52.4" 1742 | source = "registry+https://github.com/rust-lang/crates.io-index" 1743 | checksum = "5eee091590e89cc02ad514ffe3ead9eb6b660aedca2183455434b93546371a03" 1744 | 1745 | [[package]] 1746 | name = "windows_x86_64_gnullvm" 1747 | version = "0.42.2" 1748 | source = "registry+https://github.com/rust-lang/crates.io-index" 1749 | checksum = "26d41b46a36d453748aedef1486d5c7a85db22e56aff34643984ea85514e94a3" 1750 | 1751 | [[package]] 1752 | name = "windows_x86_64_gnullvm" 1753 | version = "0.48.5" 1754 | source = "registry+https://github.com/rust-lang/crates.io-index" 1755 | checksum = "0b7b52767868a23d5bab768e390dc5f5c55825b6d30b86c844ff2dc7414044cc" 1756 | 1757 | [[package]] 1758 | name = "windows_x86_64_gnullvm" 1759 | version = "0.52.4" 1760 | source = "registry+https://github.com/rust-lang/crates.io-index" 1761 | checksum = "77ca79f2451b49fa9e2af39f0747fe999fcda4f5e241b2898624dca97a1f2177" 1762 | 1763 | [[package]] 1764 | name = "windows_x86_64_msvc" 1765 | version = "0.42.2" 1766 | source = "registry+https://github.com/rust-lang/crates.io-index" 1767 | checksum = "9aec5da331524158c6d1a4ac0ab1541149c0b9505fde06423b02f5ef0106b9f0" 1768 | 1769 | [[package]] 1770 | name = "windows_x86_64_msvc" 1771 | version = "0.48.5" 1772 | source = "registry+https://github.com/rust-lang/crates.io-index" 1773 | checksum = "ed94fce61571a4006852b7389a063ab983c02eb1bb37b47f8272ce92d06d9538" 1774 | 1775 | [[package]] 1776 | name = "windows_x86_64_msvc" 1777 | version = "0.52.4" 1778 | source = "registry+https://github.com/rust-lang/crates.io-index" 1779 | checksum = "32b752e52a2da0ddfbdbcc6fceadfeede4c939ed16d13e648833a61dfb611ed8" 1780 | 1781 | [[package]] 1782 | name = "winnow" 1783 | version = "0.5.40" 1784 | source = "registry+https://github.com/rust-lang/crates.io-index" 1785 | checksum = "f593a95398737aeed53e489c785df13f3618e41dbcd6718c6addbf1395aa6876" 1786 | dependencies = [ 1787 | "memchr", 1788 | ] 1789 | 1790 | [[package]] 1791 | name = "zerocopy" 1792 | version = "0.7.32" 1793 | source = "registry+https://github.com/rust-lang/crates.io-index" 1794 | checksum = "74d4d3961e53fa4c9a25a8637fc2bfaf2595b3d3ae34875568a5cf64787716be" 1795 | dependencies = [ 1796 | "zerocopy-derive", 1797 | ] 1798 | 1799 | [[package]] 1800 | name = "zerocopy-derive" 1801 | version = "0.7.32" 1802 | source = "registry+https://github.com/rust-lang/crates.io-index" 1803 | checksum = "9ce1b18ccd8e73a9321186f97e46f9f04b778851177567b1975109d26a08d2a6" 1804 | dependencies = [ 1805 | "proc-macro2", 1806 | "quote", 1807 | "syn 2.0.55", 1808 | ] 1809 | -------------------------------------------------------------------------------- /Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "sxtetris" 3 | version = "1.3.1" 4 | edition = "2021" 5 | authors = ["shixinhuang99 "] 6 | description = "A terminal Tetris game" 7 | repository = "https://github.com/shixinhuang99/sxtetris" 8 | license = "MIT" 9 | categories = ["games"] 10 | keywords = ["tetris", "tui"] 11 | include = ["Cargo.toml", "Cargo.lock", "README.md", "LICENSE", "src/**"] 12 | 13 | [dependencies] 14 | anyhow = "1.0.81" 15 | crossterm = { version = "=0.27.0", features = ["event-stream"] } 16 | directories = "5.0.1" 17 | fastrand = "2.0.2" 18 | futures-util = "=0.3.30" 19 | log = { version = "0.4.21", optional = true } 20 | ratatui = "=0.26.1" 21 | rodio = { version = "0.19.0", default-features = false, features = [ 22 | "wav", 23 | "mp3", 24 | ] } 25 | serde = { version = "1.0.204", features = ["derive"] } 26 | serde_json = "1.0.120" 27 | simplelog = { version = "0.12.2", optional = true } 28 | tokio = { version = "=1.37.0", features = [ 29 | "rt", 30 | "rt-multi-thread", 31 | "time", 32 | "macros", 33 | "sync", 34 | ] } 35 | tui-big-text = "0.4.2" 36 | 37 | [profile.release] 38 | strip = true 39 | lto = true 40 | panic = "abort" 41 | codegen-units = 1 42 | 43 | [features] 44 | _dev = ["dep:log", "dep:simplelog"] 45 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2024 ShiXin Huang 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Sxtetris 2 | 3 | A terminal Tetris game written in Rust, based on [ratatui](https://github.com/ratatui-org/ratatui) and [tokio](https://github.com/tokio-rs/tokio) 4 | 5 | https://github.com/shixinhuang99/sxtetris/assets/31186725/1eb95c10-e57e-4239-8142-95800e1afca8 6 | 7 | ## Installation 8 | 9 | ### Cargo 10 | 11 | ```sh 12 | cargo install sxtetris --locked 13 | ``` 14 | 15 | ### AUR 16 | 17 | You can install `sxtetris` from the [AUR](https://aur.archlinux.org/packages/sxtetris) with using an [AUR helper](https://wiki.archlinux.org/title/AUR_helpers). 18 | 19 | ```sh 20 | paru -S sxtetris 21 | ``` 22 | 23 | ### Binary releases 24 | 25 | Download the [latest release binary](https://github.com/shixinhuang99/sxtetris/releases) 26 | 27 | ## Note 28 | 29 | 1. Suggested minimal terminal size: `176x49`. 30 | 2. The terminal needs to support 24 bit color(true color), such as the `iTerm2`. 31 | 3. If you are a macOS user, please do not use the built-in terminal, as its forced line spacing makes the characters in the game look weird. It is recommended to use more modern terminals such as `iTerm2`. 32 | 4. Use the `--show-save-path` argument at launch game to see the save location. 33 | 5. If you are a linux user and get the following error when using `cargo install`: 34 | 35 | ``` 36 | The system library `alsa` required by crate `alsa-sys` was not found. 37 | The file `alsa.pc` needs to be installed and the PKG_CONFIG_PATH environment variable must contain its parent directory. 38 | The PKG_CONFIG_PATH environment variable is not set. 39 | 40 | HINT: if you have installed the library, try setting PKG_CONFIG_PATH to the directory containing `alsa.pc`. 41 | ``` 42 | 43 | you can try running the following command and install again: 44 | 45 | ```sh 46 | sudo apt-get update 47 | sudo apt-get install libasound2-dev 48 | export PKG_CONFIG_PATH=$PKG_CONFIG_PATH:/usr/lib/pkgconfig:/usr/lib/x86_64-linux-gnu/pkgconfig 49 | ``` 50 | 51 | ## Sources of music and sound effects 52 | 53 | All audio files are in the `src/global/assets` directory, files from [freesound](https://freesound.org) are trimmed 54 | 55 | | file | author | source | 56 | | ------------- | --------------- | ---------------------------------------------------------------------- | 57 | | bg_music.mp3 | Stable Audio | | 58 | | game_over.wav | themusicalnomad | | 59 | | lock.wav | Mellau | | 60 | | menu.wav | Christopherderp | | 61 | | move.wav | aphom000 | | 62 | | clear.mp3 | B_Lamerichs | | 63 | 64 | ## Disclaimer 65 | 66 | This project is an open-source Tetris game running in the terminal. The Tetris game is a registered trademark, and all rights belong to its respective owner. This project is intended for educational and research purposes only and should not be used for any commercial purposes. 67 | 68 | By using this project, you agree to use it solely for non-commercial educational and research purposes. The developer is not responsible for any infringement. 69 | -------------------------------------------------------------------------------- /cliff.toml: -------------------------------------------------------------------------------- 1 | # git-cliff ~ configuration file 2 | # https://git-cliff.org/docs/configuration 3 | 4 | [changelog] 5 | # changelog header 6 | header = """ 7 | # Changelog\n 8 | All notable changes to this project will be documented in this file.\n 9 | """ 10 | # template for the changelog body 11 | # https://keats.github.io/tera/docs/#introduction 12 | body = """ 13 | {% if version %}\ 14 | ## [{{ version | trim_start_matches(pat="v") }}] - {{ timestamp | date(format="%Y-%m-%d") }} 15 | {% else %}\ 16 | ## [unreleased] 17 | {% endif %}\ 18 | {% if previous %}\ 19 | {% if previous.commit_id %} 20 | [{{ previous.commit_id | truncate(length=7, end="") }}]({{ previous.commit_id }})...\ 21 | [{{ commit_id | truncate(length=7, end="") }}]({{ commit_id }}) 22 | {% endif %}\ 23 | {% endif %}\ 24 | {% for group, commits in commits | group_by(attribute="group") %} 25 | ### {{ group | upper_first }} 26 | {% for commit in commits %} 27 | - {{ commit.message | upper_first }} ([{{ commit.id | truncate(length=7, end="") }}]({{ commit.id }}))\ 28 | {% for footer in commit.footers -%} 29 | , {{ footer.token }}{{ footer.separator }}{{ footer.value }}\ 30 | {% endfor %}\ 31 | {% endfor %} 32 | {% endfor %}\n 33 | """ 34 | # remove the leading and trailing whitespace from the template 35 | trim = true 36 | # changelog footer 37 | footer = """ 38 | 39 | """ 40 | 41 | [git] 42 | # parse the commits based on https://www.conventionalcommits.org 43 | conventional_commits = true 44 | # filter out the commits that are not conventional 45 | filter_unconventional = true 46 | # process each line of a commit as an individual commit 47 | split_commits = false 48 | # regex for parsing and grouping commits 49 | commit_parsers = [ 50 | { message = "^feat", group = "Features" }, 51 | { message = "^fix", group = "Bug Fixes" }, 52 | { message = "^doc", group = "Documentation" }, 53 | { message = "^perf", group = "Performance" }, 54 | { message = "^refactor", group = "Refactor" }, 55 | { message = "^style", group = "Styling" }, 56 | { message = "^test", group = "Testing" }, 57 | { message = "^chore\\(deps\\)", skip = true }, 58 | { message = "^chore\\(pr\\)", skip = true }, 59 | { message = "^chore\\(pull\\)", skip = true }, 60 | { message = "^chore\\(release\\)", skip = true }, 61 | { message = "^chore|ci", group = "Miscellaneous Tasks" }, 62 | { body = ".*security", group = "Security" }, 63 | ] 64 | # protect breaking changes from being skipped due to matching a skipping commit_parser 65 | protect_breaking_commits = false 66 | # filter out the commits that are not matched by commit parsers 67 | filter_commits = false 68 | # regex for matching git tags 69 | tag_pattern = "[0-9]+.*" 70 | # regex for skipping tags 71 | skip_tags = "1.0.0" 72 | # regex for ignoring tags 73 | ignore_tags = "" 74 | # sort the tags topologically 75 | topo_order = false 76 | # sort the commits inside sections by oldest/newest order 77 | sort_commits = "oldest" 78 | -------------------------------------------------------------------------------- /justfile: -------------------------------------------------------------------------------- 1 | alias rp := release-pr 2 | alias pt := push-tag 3 | 4 | default: 5 | just --list --unsorted 6 | 7 | fmt: 8 | cargo fmt 9 | taplo fmt 10 | 11 | lint: fmt 12 | cargo clippy --all-features 13 | 14 | check: 15 | cargo fmt --check 16 | taplo fmt --check 17 | cargo clippy --all-features -- -D warnings 18 | 19 | release-pr tag: 20 | git checkout -b "release-{{tag}}" 21 | git cliff --tag {{tag}} -o CHANGELOG.md 22 | cargo set-version {{tag}} 23 | git commit -am "chore(release): {{tag}}" 24 | git push --set-upstream origin release-{{tag}} 25 | 26 | push-tag tag: 27 | git tag {{tag}} 28 | git push origin {{tag}} 29 | 30 | run *args: 31 | cargo +stable run -F _dev -- {{args}} 32 | -------------------------------------------------------------------------------- /rust-toolchain.toml: -------------------------------------------------------------------------------- 1 | [toolchain] 2 | # 1.81.0-nightly (8337ba918 2024-06-12) 3 | channel = "nightly-2024-06-13" 4 | profile = "minimal" 5 | components = ["rustfmt", "clippy"] 6 | -------------------------------------------------------------------------------- /rustfmt.toml: -------------------------------------------------------------------------------- 1 | edition = "2021" 2 | version = "Two" 3 | unstable_features = true 4 | max_width = 80 5 | group_imports = "StdExternalCrate" 6 | imports_granularity = "Crate" 7 | use_field_init_shorthand = true 8 | wrap_comments = true 9 | hard_tabs = true 10 | combine_control_expr = false 11 | newline_style = "Unix" 12 | struct_lit_single_line = false 13 | single_line_if_else_max_width = 0 14 | single_line_let_else_max_width = 0 15 | force_multiline_blocks = true 16 | -------------------------------------------------------------------------------- /src/app.rs: -------------------------------------------------------------------------------- 1 | use std::env; 2 | 3 | use anyhow::Result; 4 | 5 | use crate::{ 6 | global::{global_audio, init_global_audio}, 7 | handler::{Event, MainHandler}, 8 | save::Save, 9 | state::State, 10 | term::Term, 11 | ui::{loading, ui}, 12 | }; 13 | 14 | pub struct App { 15 | term: Term, 16 | handler: MainHandler, 17 | state: State, 18 | save: Save, 19 | } 20 | 21 | impl App { 22 | pub fn new() -> Result { 23 | let term = Term::new()?; 24 | let handler = MainHandler::new(); 25 | let state = State::new(handler.create_sub_handler()); 26 | let save = Save::new(); 27 | 28 | Ok(Self { 29 | term, 30 | handler, 31 | state, 32 | save, 33 | }) 34 | } 35 | 36 | pub async fn run(&mut self) -> Result<()> { 37 | for arg in env::args() { 38 | if arg == "--show-save-path" { 39 | self.save.show_save_path(); 40 | return Ok(()); 41 | } 42 | } 43 | 44 | self.term.init()?; 45 | self.term.draw(loading)?; 46 | 47 | init_global_audio(); 48 | self.save.read(&mut self.state); 49 | self.handler.init_task(); 50 | 51 | while let Some(event) = self.handler.recv().await { 52 | if event == Event::CtrlC { 53 | break; 54 | } 55 | 56 | if event == Event::Tick { 57 | self.state.update_line_clear(); 58 | self.term.draw(|f| { 59 | ui(f, &mut self.state); 60 | })?; 61 | continue; 62 | } 63 | 64 | self.state.handle_event(event); 65 | 66 | if !self.state.running { 67 | break; 68 | } 69 | } 70 | 71 | global_audio(|audio| audio.stop_all()); 72 | self.save.write(&self.state); 73 | self.handler.shutdown().await; 74 | self.state.handler.shutdown().await; 75 | 76 | self.term.exit()?; 77 | 78 | Ok(()) 79 | } 80 | } 81 | -------------------------------------------------------------------------------- /src/common/mod.rs: -------------------------------------------------------------------------------- 1 | mod point; 2 | mod position; 3 | mod tetromino_kind; 4 | 5 | pub use position::{pos, Position}; 6 | pub use tetromino_kind::TetrominoKind; 7 | 8 | use crate::global::{global_audio, Sound}; 9 | 10 | pub trait Board { 11 | fn get_kind(&self, x: usize, y: usize) -> Option<&TetrominoKind>; 12 | } 13 | 14 | pub trait Reset { 15 | fn reset(&mut self); 16 | } 17 | 18 | pub trait Menu { 19 | fn cursor_mut(&mut self) -> &mut usize; 20 | 21 | fn cursor(&self) -> usize; 22 | 23 | fn end(&self) -> usize; 24 | 25 | fn items(&self) -> Vec; 26 | 27 | fn up(&mut self) { 28 | let end = self.end(); 29 | let cursor = self.cursor_mut(); 30 | 31 | if *cursor == 0 { 32 | *cursor = end; 33 | } else { 34 | *cursor -= 1; 35 | } 36 | 37 | global_audio(|audio| audio.play_sound(Sound::Menu)); 38 | } 39 | 40 | fn down(&mut self) { 41 | let end = self.end(); 42 | let cursor = self.cursor_mut(); 43 | 44 | if *cursor == end { 45 | *cursor = 0; 46 | } else { 47 | *cursor += 1; 48 | } 49 | 50 | global_audio(|audio| audio.play_sound(Sound::Menu)); 51 | } 52 | 53 | fn reset(&mut self) { 54 | *self.cursor_mut() = 0; 55 | } 56 | } 57 | 58 | pub trait VecExt { 59 | fn into_owned_vec(self) -> Vec; 60 | } 61 | 62 | impl VecExt for Vec<&str> { 63 | fn into_owned_vec(self) -> Vec { 64 | self.into_iter().map(|s| s.to_string()).collect() 65 | } 66 | } 67 | -------------------------------------------------------------------------------- /src/common/point.rs: -------------------------------------------------------------------------------- 1 | use serde::{Deserialize, Serialize}; 2 | 3 | #[derive(Clone, PartialEq, Eq, Deserialize, Serialize)] 4 | pub struct Point { 5 | pub x: T, 6 | pub y: T, 7 | } 8 | 9 | impl Point { 10 | pub const fn new(raw_point: (i8, i8)) -> Self { 11 | Self { 12 | x: raw_point.0, 13 | y: raw_point.1, 14 | } 15 | } 16 | 17 | pub fn to_usize_point(&self) -> Point { 18 | self.clone().into() 19 | } 20 | } 21 | 22 | impl From> for Point { 23 | fn from(value: Point) -> Self { 24 | Self { 25 | x: value.x as usize, 26 | y: value.y as usize, 27 | } 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /src/common/position.rs: -------------------------------------------------------------------------------- 1 | use std::{ 2 | array::IntoIter, 3 | ops::{Add, Sub}, 4 | }; 5 | 6 | use serde::{Deserialize, Serialize}; 7 | 8 | use super::point::Point; 9 | use crate::consts::{MAIN_BOARD_BUFFER_ROWS, MAIN_BOARD_COLS, MAIN_BOARD_ROWS}; 10 | 11 | const MAX_Y: i8 = MAIN_BOARD_ROWS as i8 - 1; 12 | const MAX_X: i8 = MAIN_BOARD_COLS as i8 - 1; 13 | const MIN_Y: i8 = MAIN_BOARD_BUFFER_ROWS as i8; 14 | 15 | #[derive(Clone, PartialEq, Eq, Deserialize, Serialize)] 16 | #[serde(transparent)] 17 | pub struct Position([Point; 4]); 18 | 19 | impl Position { 20 | pub const fn new(raw_points: [(i8, i8); 4]) -> Self { 21 | Self([ 22 | Point::new(raw_points[0]), 23 | Point::new(raw_points[1]), 24 | Point::new(raw_points[2]), 25 | Point::new(raw_points[3]), 26 | ]) 27 | } 28 | 29 | pub fn into_iter(self) -> IntoIter, 4> { 30 | self.0.into_iter() 31 | } 32 | 33 | pub fn update)>(&mut self, f: F) { 34 | self.0.iter_mut().for_each(f); 35 | } 36 | 37 | pub fn is_touch_bottom(&self) -> bool { 38 | self.0.iter().any(|p| p.y >= MAX_Y) 39 | } 40 | 41 | pub fn is_touch_left(&self) -> bool { 42 | self.0.iter().any(|p| p.x <= 0) 43 | } 44 | 45 | pub fn is_touch_right(&self) -> bool { 46 | self.0.iter().any(|p| p.x >= MAX_X) 47 | } 48 | 49 | pub fn is_outside_the_board(&self) -> bool { 50 | self.0 51 | .iter() 52 | .any(|p| p.x < 0 || p.x > MAX_X || p.y < 0 || p.y > MAX_Y) 53 | } 54 | 55 | pub fn is_outside_the_visible(&self) -> bool { 56 | self.0 57 | .iter() 58 | .any(|p| p.x < 0 || p.x > MAX_X || p.y < MIN_Y || p.y > MAX_Y) 59 | } 60 | 61 | pub fn to_usize_points(&self) -> Vec> { 62 | self.0.iter().map(|p| p.to_usize_point()).collect() 63 | } 64 | 65 | pub fn bottom_point(&self) -> &Point { 66 | self.0.iter().max_by(|a, b| a.y.cmp(&b.y)).unwrap() 67 | } 68 | 69 | pub fn contains(&self, x: usize, y: usize) -> bool { 70 | self.0 71 | .iter() 72 | .any(|p| p.x as usize == x && p.y as usize == y) 73 | } 74 | } 75 | 76 | pub const fn pos(raw_points: [(i8, i8); 4]) -> Position { 77 | Position::new(raw_points) 78 | } 79 | 80 | impl Default for Position { 81 | fn default() -> Self { 82 | Self::new([(0, 0); 4]) 83 | } 84 | } 85 | 86 | impl Sub for Position { 87 | type Output = Position; 88 | 89 | fn sub(mut self, rhs: Self) -> Self::Output { 90 | for i in 0..self.0.len() { 91 | self.0[i].x -= rhs.0[i].x; 92 | self.0[i].y -= rhs.0[i].y; 93 | } 94 | self 95 | } 96 | } 97 | 98 | impl Add for Position { 99 | type Output = Position; 100 | 101 | fn add(mut self, rhs: Self) -> Self::Output { 102 | for i in 0..self.0.len() { 103 | self.0[i].x += rhs.0[i].x; 104 | self.0[i].y += rhs.0[i].y; 105 | } 106 | self 107 | } 108 | } 109 | 110 | impl Add> for Position { 111 | type Output = Position; 112 | 113 | fn add(mut self, rhs: Point) -> Self::Output { 114 | self.update(|p| { 115 | p.x += rhs.x; 116 | p.y += rhs.y; 117 | }); 118 | self 119 | } 120 | } 121 | -------------------------------------------------------------------------------- /src/common/tetromino_kind.rs: -------------------------------------------------------------------------------- 1 | use ratatui::style::Color; 2 | use serde::{Deserialize, Serialize}; 3 | 4 | use super::{pos, Position}; 5 | 6 | #[derive(Clone, Copy, PartialEq, Eq, Default, Deserialize, Serialize)] 7 | pub enum TetrominoKind { 8 | #[default] 9 | I, 10 | /// ``` 11 | /// [] 12 | /// [][][] 13 | /// ``` 14 | J, 15 | /// ``` 16 | /// [] 17 | /// [][][] 18 | /// ``` 19 | L, 20 | O, 21 | /// ``` 22 | /// [][] 23 | /// [][] 24 | /// ``` 25 | S, 26 | T, 27 | /// ``` 28 | /// [][] 29 | /// [][] 30 | /// ``` 31 | Z, 32 | } 33 | 34 | impl TetrominoKind { 35 | pub fn init_position(&self, idx: usize) -> Position { 36 | let position = match self { 37 | TetrominoKind::I => &position_map::I[idx], 38 | TetrominoKind::J => &position_map::J[idx], 39 | TetrominoKind::L => &position_map::L[idx], 40 | TetrominoKind::O => &position_map::O[idx], 41 | TetrominoKind::S => &position_map::S[idx], 42 | TetrominoKind::T => &position_map::T[idx], 43 | TetrominoKind::Z => &position_map::Z[idx], 44 | }; 45 | 46 | position.clone() 47 | } 48 | 49 | pub fn color(&self) -> Color { 50 | match self { 51 | TetrominoKind::I => color::cyan(), 52 | TetrominoKind::J => color::blue(), 53 | TetrominoKind::L => color::orange(), 54 | TetrominoKind::O => color::yellow(), 55 | TetrominoKind::S => color::green(), 56 | TetrominoKind::T => color::purple(), 57 | TetrominoKind::Z => color::red(), 58 | } 59 | } 60 | 61 | pub fn dark_color(&self) -> Color { 62 | match self { 63 | TetrominoKind::I => color::dark_cyan(), 64 | TetrominoKind::J => color::dark_blue(), 65 | TetrominoKind::L => color::dark_orange(), 66 | TetrominoKind::O => color::dark_yellow(), 67 | TetrominoKind::S => color::dark_green(), 68 | TetrominoKind::T => color::dark_purple(), 69 | TetrominoKind::Z => color::dark_red(), 70 | } 71 | } 72 | } 73 | 74 | mod position_map { 75 | use super::{pos, Position}; 76 | 77 | type Map = [Position; 4]; 78 | 79 | pub const I: Map = [ 80 | pos([(0, 1), (1, 1), (2, 1), (3, 1)]), 81 | pos([(2, 0), (2, 1), (2, 2), (2, 3)]), 82 | pos([(0, 2), (1, 2), (2, 2), (3, 2)]), 83 | pos([(1, 0), (1, 1), (1, 2), (1, 3)]), 84 | ]; 85 | 86 | pub const J: Map = [ 87 | pos([(0, 0), (0, 1), (1, 1), (2, 1)]), 88 | pos([(2, 0), (1, 0), (1, 1), (1, 2)]), 89 | pos([(2, 2), (2, 1), (1, 1), (0, 1)]), 90 | pos([(0, 2), (1, 2), (1, 1), (1, 0)]), 91 | ]; 92 | 93 | pub const L: Map = [ 94 | pos([(2, 0), (0, 1), (1, 1), (2, 1)]), 95 | pos([(2, 2), (1, 0), (1, 1), (1, 2)]), 96 | pos([(0, 2), (2, 1), (1, 1), (0, 1)]), 97 | pos([(0, 0), (1, 2), (1, 1), (1, 0)]), 98 | ]; 99 | 100 | pub const O: Map = [ 101 | pos([(1, 0), (2, 0), (1, 1), (2, 1)]), 102 | pos([(1, 0), (2, 0), (1, 1), (2, 1)]), 103 | pos([(1, 0), (2, 0), (1, 1), (2, 1)]), 104 | pos([(1, 0), (2, 0), (1, 1), (2, 1)]), 105 | ]; 106 | 107 | pub const S: Map = [ 108 | pos([(1, 0), (2, 0), (0, 1), (1, 1)]), 109 | pos([(2, 1), (2, 2), (1, 0), (1, 1)]), 110 | pos([(1, 2), (0, 2), (2, 1), (1, 1)]), 111 | pos([(0, 1), (0, 0), (1, 2), (1, 1)]), 112 | ]; 113 | 114 | pub const T: Map = [ 115 | pos([(1, 0), (0, 1), (1, 1), (2, 1)]), 116 | pos([(2, 1), (1, 0), (1, 1), (1, 2)]), 117 | pos([(1, 2), (2, 1), (1, 1), (0, 1)]), 118 | pos([(0, 1), (1, 2), (1, 1), (1, 0)]), 119 | ]; 120 | 121 | pub const Z: Map = [ 122 | pos([(0, 0), (1, 0), (1, 1), (2, 1)]), 123 | pos([(2, 0), (2, 1), (1, 1), (1, 2)]), 124 | pos([(2, 2), (1, 2), (1, 1), (0, 1)]), 125 | pos([(0, 2), (0, 1), (1, 1), (1, 0)]), 126 | ]; 127 | } 128 | 129 | mod color { 130 | use ratatui::style::Color; 131 | 132 | pub fn red() -> Color { 133 | Color::Rgb(200, 0, 0) 134 | } 135 | 136 | pub fn orange() -> Color { 137 | Color::Rgb(255, 165, 0) 138 | } 139 | 140 | pub fn yellow() -> Color { 141 | Color::Rgb(255, 255, 0) 142 | } 143 | 144 | pub fn green() -> Color { 145 | Color::Rgb(0, 255, 0) 146 | } 147 | 148 | pub fn cyan() -> Color { 149 | Color::Rgb(0, 255, 255) 150 | } 151 | 152 | pub fn blue() -> Color { 153 | Color::Rgb(5, 50, 255) 154 | } 155 | 156 | pub fn purple() -> Color { 157 | Color::Rgb(128, 0, 128) 158 | } 159 | 160 | pub fn dark_red() -> Color { 161 | Color::Rgb(139, 0, 0) 162 | } 163 | 164 | pub fn dark_orange() -> Color { 165 | Color::Rgb(205, 92, 0) 166 | } 167 | 168 | pub fn dark_yellow() -> Color { 169 | Color::Rgb(139, 139, 0) 170 | } 171 | 172 | pub fn dark_green() -> Color { 173 | Color::Rgb(0, 68, 27) 174 | } 175 | 176 | pub fn dark_cyan() -> Color { 177 | Color::Rgb(0, 139, 139) 178 | } 179 | 180 | pub fn dark_blue() -> Color { 181 | Color::Rgb(0, 0, 139) 182 | } 183 | 184 | pub fn dark_purple() -> Color { 185 | Color::Rgb(64, 0, 64) 186 | } 187 | } 188 | -------------------------------------------------------------------------------- /src/consts.rs: -------------------------------------------------------------------------------- 1 | pub const APP_NAME: &str = env!("CARGO_PKG_NAME"); 2 | pub const APP_VER: &str = env!("CARGO_PKG_VERSION"); 3 | 4 | // 30 fps 5 | pub const FRAME_RATE_SECS: f32 = 0.033; 6 | 7 | pub const MIN_CELL_WIDTH: u16 = 5; 8 | pub const MIN_CELL_HEIGHT: u16 = 3; 9 | 10 | pub const MAIN_BOARD_COLS: usize = 10; 11 | pub const MAIN_BOARD_BUFFER_ROWS: usize = 5; 12 | pub const MAIN_BOARD_VISIBLE_ROWS: usize = 16; 13 | pub const MAIN_BOARD_ROWS: usize = 14 | MAIN_BOARD_VISIBLE_ROWS + MAIN_BOARD_BUFFER_ROWS; 15 | 16 | pub const NEXT_BOARD_COLS: usize = 8; 17 | pub const NEXT_BOARD_ROWS: usize = 2; 18 | -------------------------------------------------------------------------------- /src/global/assets/bg_music.mp3: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/shixinhuang99/sxtetris/c04a2d97c893a06be6c22b2237907b4d86a5b907/src/global/assets/bg_music.mp3 -------------------------------------------------------------------------------- /src/global/assets/clear.mp3: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/shixinhuang99/sxtetris/c04a2d97c893a06be6c22b2237907b4d86a5b907/src/global/assets/clear.mp3 -------------------------------------------------------------------------------- /src/global/assets/game_over.wav: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/shixinhuang99/sxtetris/c04a2d97c893a06be6c22b2237907b4d86a5b907/src/global/assets/game_over.wav -------------------------------------------------------------------------------- /src/global/assets/lock.wav: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/shixinhuang99/sxtetris/c04a2d97c893a06be6c22b2237907b4d86a5b907/src/global/assets/lock.wav -------------------------------------------------------------------------------- /src/global/assets/menu.wav: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/shixinhuang99/sxtetris/c04a2d97c893a06be6c22b2237907b4d86a5b907/src/global/assets/menu.wav -------------------------------------------------------------------------------- /src/global/assets/move.wav: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/shixinhuang99/sxtetris/c04a2d97c893a06be6c22b2237907b4d86a5b907/src/global/assets/move.wav -------------------------------------------------------------------------------- /src/global/audio.rs: -------------------------------------------------------------------------------- 1 | use std::{cell::OnceCell, collections::HashMap, io::Cursor}; 2 | 3 | use anyhow::Result; 4 | use rodio::{ 5 | source::{Amplify, Buffered, Repeat}, 6 | Decoder, OutputStream, OutputStreamHandle, Sink, Source, 7 | }; 8 | 9 | use super::{global_setting, is_played}; 10 | 11 | type SoundSource = Buffered>>>; 12 | type MusicSource = Repeat>>>; 13 | 14 | thread_local! { 15 | static AUDIO: OnceCell