mirror of
https://github.com/dualshock-tools/dualshock-tools.github.io.git
synced 2026-07-18 05:34:06 +03:00
Compare commits
65 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
50dcc191e8 | ||
|
|
8b7e8425de | ||
|
|
e1141b25a7 | ||
|
|
c295cfa508 | ||
|
|
48fc4b5dce | ||
|
|
7d4ddfdfad | ||
|
|
3493c4de74 | ||
|
|
42fc94a9a2 | ||
|
|
d4ba4a5fdd | ||
|
|
f82cdcf663 | ||
|
|
f05499defd | ||
|
|
7038beb545 | ||
|
|
f5e7c4cd85 | ||
|
|
e69cb6ef95 | ||
|
|
c17cdfc92b | ||
|
|
9d45f17cfc | ||
|
|
aeb7e9010a | ||
|
|
7b19117311 | ||
|
|
a72e0223b9 | ||
|
|
f43aa7af83 | ||
|
|
f7f61b88b9 | ||
|
|
2fe3416c5c | ||
|
|
9f5c8914bc | ||
|
|
247f5be479 | ||
|
|
caa1b260a7 | ||
|
|
398d7e8592 | ||
|
|
01dca68b17 | ||
|
|
470bdaeeb4 | ||
|
|
71633d7718 | ||
|
|
9bb9f2f082 | ||
|
|
f0dc0b829e | ||
|
|
32a0f57b0b | ||
|
|
45d68bd75e | ||
|
|
28f1f4fa02 | ||
|
|
2b1f42b4eb | ||
|
|
eaa94d8bbc | ||
|
|
67c9cd903f | ||
|
|
8ba5991314 | ||
|
|
188929ff6f | ||
|
|
02c1f1262b | ||
|
|
8e8592438e | ||
|
|
0aad6497a8 | ||
|
|
372e8abf57 | ||
|
|
d1b6cd5c96 | ||
|
|
390f2d97b6 | ||
|
|
4fe737aed1 | ||
|
|
53456b9663 | ||
|
|
994501a614 | ||
|
|
3fc58dbe64 | ||
|
|
2a834b130b | ||
|
|
c436d94ead | ||
|
|
1e7d4e83cc | ||
|
|
f643dbe005 | ||
|
|
b85f12eccd | ||
|
|
0aac1509aa | ||
|
|
5237c7ca46 | ||
|
|
b163a7d1d4 | ||
|
|
6f662c6a7a | ||
|
|
77b3cedfad | ||
|
|
1fa7066477 | ||
|
|
65376ea717 | ||
|
|
97317bd7b2 | ||
|
|
ef5b307046 | ||
|
|
9e359c9dcd | ||
|
|
152a11d7bc |
76
.github/workflows/gulp-deploy.yml
vendored
Normal file
76
.github/workflows/gulp-deploy.yml
vendored
Normal file
@@ -0,0 +1,76 @@
|
||||
name: Build and Deploy to GitHub Pages
|
||||
|
||||
on:
|
||||
push:
|
||||
branches:
|
||||
- main
|
||||
- build-dist-with-gulp
|
||||
- release-2-16
|
||||
workflow_dispatch:
|
||||
inputs:
|
||||
deploy:
|
||||
description: "Deploy to GitHub Pages?"
|
||||
required: true
|
||||
default: "true"
|
||||
type: choice
|
||||
options:
|
||||
- "true"
|
||||
- "false"
|
||||
|
||||
# Sets permissions of the GITHUB_TOKEN to allow deployment to GitHub Pages
|
||||
permissions:
|
||||
contents: read
|
||||
pages: write
|
||||
id-token: write
|
||||
|
||||
# Allow only one concurrent deployment, skipping runs queued between the run in-progress and latest queued.
|
||||
# However, do NOT cancel in-progress runs as we want to allow these production deployments to complete.
|
||||
concurrency:
|
||||
group: "pages"
|
||||
cancel-in-progress: false
|
||||
|
||||
jobs:
|
||||
build:
|
||||
runs-on: ubuntu-latest
|
||||
|
||||
strategy:
|
||||
matrix:
|
||||
node-version: [20.x]
|
||||
|
||||
steps:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v4
|
||||
|
||||
- name: Setup Node.js ${{ matrix.node-version }}
|
||||
uses: actions/setup-node@v4
|
||||
with:
|
||||
node-version: ${{ matrix.node-version }}
|
||||
cache: "npm"
|
||||
|
||||
- name: Install dependencies
|
||||
run: npm ci
|
||||
|
||||
- name: Build project
|
||||
run: npm run build:prod
|
||||
|
||||
- name: Setup Pages
|
||||
uses: actions/configure-pages@v4
|
||||
if: inputs.deploy == 'true'
|
||||
|
||||
- name: Upload artifact
|
||||
uses: actions/upload-pages-artifact@v3
|
||||
if: inputs.deploy == 'true'
|
||||
with:
|
||||
path: "./dist"
|
||||
|
||||
deploy:
|
||||
environment:
|
||||
name: github-pages
|
||||
url: ${{ steps.deployment.outputs.page_url }}
|
||||
runs-on: ubuntu-latest
|
||||
needs: build
|
||||
if: inputs.deploy == 'true'
|
||||
steps:
|
||||
- name: Deploy to GitHub Pages
|
||||
id: deployment
|
||||
uses: actions/deploy-pages@v4
|
||||
58
.gitignore
vendored
Normal file
58
.gitignore
vendored
Normal file
@@ -0,0 +1,58 @@
|
||||
# Dependencies
|
||||
node_modules/
|
||||
npm-debug.log*
|
||||
yarn-debug.log*
|
||||
yarn-error.log*
|
||||
|
||||
# Build outputs
|
||||
dist/
|
||||
.tmp/
|
||||
|
||||
# OS generated files
|
||||
.DS_Store
|
||||
.DS_Store?
|
||||
._*
|
||||
.Spotlight-V100
|
||||
.Trashes
|
||||
ehthumbs.db
|
||||
Thumbs.db
|
||||
|
||||
# IDE files
|
||||
.vscode/
|
||||
.idea/
|
||||
*.swp
|
||||
*.swo
|
||||
|
||||
# Logs
|
||||
logs
|
||||
*.log
|
||||
|
||||
# Runtime data
|
||||
pids
|
||||
*.pid
|
||||
*.seed
|
||||
*.pid.lock
|
||||
|
||||
# Coverage directory used by tools like istanbul
|
||||
coverage/
|
||||
|
||||
# nyc test coverage
|
||||
.nyc_output
|
||||
|
||||
# Dependency directories
|
||||
jspm_packages/
|
||||
|
||||
# Optional npm cache directory
|
||||
.npm
|
||||
|
||||
# Optional REPL history
|
||||
.node_repl_history
|
||||
|
||||
# Output of 'npm pack'
|
||||
*.tgz
|
||||
|
||||
# Yarn Integrity file
|
||||
.yarn-integrity
|
||||
|
||||
# dotenv environment variables file
|
||||
.env
|
||||
136
DEVELOPMENT.md
Normal file
136
DEVELOPMENT.md
Normal file
@@ -0,0 +1,136 @@
|
||||
# Development Guide
|
||||
|
||||
## Quick Start
|
||||
|
||||
```bash
|
||||
# Install dependencies
|
||||
npm install
|
||||
|
||||
# Start development with auto-reload
|
||||
npm run dev:full
|
||||
```
|
||||
|
||||
Open `https://localhost:8443` in your browser (accept the SSL certificate warning).
|
||||
|
||||
## Available Scripts
|
||||
|
||||
| Script | Description |
|
||||
| --------------------- | --------------------------------------------------------- |
|
||||
| `npm run build` | Build for development (with source maps) |
|
||||
| `npm run build:prod` | Build for production (minified, optimized) |
|
||||
| `npm run clean` | Clean the dist directory |
|
||||
| `npm run serve:https` | Serve built app over HTTPS (required for WebHID) |
|
||||
| `npm run serve` | Serve built app over HTTP (WebHID won't work) |
|
||||
| `npm run start` | Build and serve over HTTPS |
|
||||
| `npm run dev:full` | **Recommended**: Build, watch, and serve with auto-reload |
|
||||
| `npm run watch` | Watch files and rebuild on changes |
|
||||
|
||||
## Development Workflow
|
||||
|
||||
### For Active Development
|
||||
|
||||
```bash
|
||||
npm run dev:full
|
||||
```
|
||||
|
||||
This starts the complete development environment:
|
||||
|
||||
- Builds the application
|
||||
- Watches for file changes
|
||||
- Serves over HTTPS at `https://localhost:8443`
|
||||
- Automatically rebuilds when you save files
|
||||
|
||||
### For Testing Built Version
|
||||
|
||||
```bash
|
||||
npm run start
|
||||
```
|
||||
|
||||
This builds once and serves the result.
|
||||
|
||||
## Important Notes
|
||||
|
||||
### HTTPS Requirement
|
||||
|
||||
The WebHID API requires HTTPS. The development server uses self-signed certificates located at:
|
||||
|
||||
- `server.crt` - SSL certificate
|
||||
- `server.key` - SSL private key
|
||||
|
||||
### Browser Compatibility
|
||||
|
||||
- **Chrome/Edge**: Full WebHID support ✅
|
||||
- **Firefox**: No WebHID support ❌
|
||||
- **Safari**: No WebHID support ❌
|
||||
|
||||
### SSL Certificate Warning
|
||||
|
||||
When first accessing `https://localhost:8443`, your browser will show a security warning because we're using a self-signed certificate. This is normal for development - click "Advanced" and "Proceed to localhost" to continue.
|
||||
|
||||
## File Structure
|
||||
|
||||
```
|
||||
├── js/ # Source JavaScript files
|
||||
│ ├── core.js # Main application entry point
|
||||
│ ├── controllers/ # Controller-specific classes
|
||||
│ └── modals/ # Modal dialog handlers
|
||||
├── css/ # Source CSS files
|
||||
├── templates/ # HTML template files
|
||||
├── lang/ # Translation JSON files
|
||||
├── assets/ # SVG assets
|
||||
├── dist/ # Built application (auto-generated)
|
||||
└── dev-server.js # Custom development server
|
||||
```
|
||||
|
||||
## Build Process
|
||||
|
||||
The build system uses Gulp with the following steps:
|
||||
|
||||
1. **JavaScript**: Bundled with Rollup, supports ES modules
|
||||
2. **CSS**: Concatenated and optionally minified
|
||||
3. **HTML**: Processed and optionally minified
|
||||
4. **Assets**: Copied to dist, SVGs can be inlined in production
|
||||
5. **Languages**: JSON files copied and optionally minified
|
||||
|
||||
### Development vs Production
|
||||
|
||||
| Feature | Development | Production |
|
||||
| -------------- | ----------- | ---------- |
|
||||
| Source maps | ✅ | ❌ |
|
||||
| Minification | ❌ | ✅ |
|
||||
| Asset inlining | ❌ | ✅ |
|
||||
| File hashing | ❌ | ✅ |
|
||||
|
||||
## Troubleshooting
|
||||
|
||||
### Port Already in Use
|
||||
|
||||
If port 8443 is busy:
|
||||
|
||||
```bash
|
||||
PORT=8444 npm run serve:https
|
||||
```
|
||||
|
||||
### Build Errors
|
||||
|
||||
Clean and rebuild:
|
||||
|
||||
```bash
|
||||
npm run clean
|
||||
npm run build
|
||||
```
|
||||
|
||||
### SSL Certificate Issues
|
||||
|
||||
The certificates are pre-generated. If you need new ones:
|
||||
|
||||
```bash
|
||||
openssl req -x509 -newkey rsa:4096 -keyout server.key -out server.crt -days 365 -nodes -subj "/CN=localhost"
|
||||
```
|
||||
|
||||
### WebHID Not Working
|
||||
|
||||
1. Make sure you're using HTTPS (`npm run serve:https`)
|
||||
2. Use Chrome or Edge browser
|
||||
3. Accept the SSL certificate warning
|
||||
4. Check browser console for errors
|
||||
94
README.md
94
README.md
@@ -1,3 +1,93 @@
|
||||
# dualshock-tools.github.io
|
||||
# DualShock Calibration GUI
|
||||
|
||||
The code behind the DualShock Calibration GUI
|
||||
A web-based calibration tool for PlayStation DualShock 4, DualSense, and DualSense Edge controllers using the WebHID API.
|
||||
|
||||
## Features
|
||||
|
||||
- Controller connection via WebHID API
|
||||
- Stick calibration and range calibration
|
||||
- Input testing and visualization
|
||||
- Battery status display
|
||||
- Multi-language support (20+ languages)
|
||||
- Progressive Web App capabilities
|
||||
|
||||
## Development
|
||||
|
||||
### Prerequisites
|
||||
|
||||
- Node.js (v16 or higher)
|
||||
- npm or yarn
|
||||
- Modern browser with WebHID support (Chrome/Edge)
|
||||
|
||||
### Getting Started
|
||||
|
||||
1. **Install dependencies:**
|
||||
|
||||
```bash
|
||||
npm install
|
||||
```
|
||||
|
||||
2. **Build the application:**
|
||||
|
||||
```bash
|
||||
npm run build
|
||||
```
|
||||
|
||||
3. **Start the development server:**
|
||||
|
||||
```bash
|
||||
npm run start
|
||||
```
|
||||
|
||||
The app will be available at `https://localhost:8443`
|
||||
|
||||
### Development Scripts
|
||||
|
||||
- `npm run build` - Build the application for development
|
||||
- `npm run build:prod` - Build the application for production
|
||||
- `npm run clean` - Clean the dist directory
|
||||
- `npm run serve:https` - Serve the built app over HTTPS (required for WebHID)
|
||||
- `npm run serve` - Serve the built app over HTTP (WebHID won't work)
|
||||
- `npm run start` - Build and serve the app
|
||||
- `npm run dev:full` - Build, watch for changes, and serve with auto-reload
|
||||
- `npm run watch` - Watch for file changes and rebuild
|
||||
|
||||
### Development Workflow
|
||||
|
||||
For active development with auto-rebuild:
|
||||
|
||||
```bash
|
||||
npm run dev:full
|
||||
```
|
||||
|
||||
This will:
|
||||
|
||||
1. Build the application
|
||||
2. Start watching for file changes
|
||||
3. Serve the app over HTTPS at `https://localhost:8443`
|
||||
4. Automatically rebuild when files change
|
||||
|
||||
### Important Notes
|
||||
|
||||
- **HTTPS Required**: The WebHID API requires HTTPS. The development server uses self-signed certificates.
|
||||
- **Browser Security**: You may need to accept the self-signed certificate warning in your browser.
|
||||
- **Controller Support**: Only works in browsers with WebHID support (Chrome, Edge, Opera).
|
||||
|
||||
### Project Structure
|
||||
|
||||
- `js/` - Source JavaScript files
|
||||
- `css/` - Source CSS files
|
||||
- `templates/` - HTML template files
|
||||
- `lang/` - Translation files
|
||||
- `assets/` - SVG assets
|
||||
- `dist/` - Built application (generated)
|
||||
|
||||
### Build System
|
||||
|
||||
The project uses Gulp for building:
|
||||
|
||||
- JavaScript bundling with Rollup
|
||||
- CSS concatenation and minification
|
||||
- HTML processing and minification
|
||||
- Asset optimization
|
||||
- Development vs production builds
|
||||
|
||||
108
assets/dualshock-controller.svg
Normal file
108
assets/dualshock-controller.svg
Normal file
@@ -0,0 +1,108 @@
|
||||
<svg id="controller-svg" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 640 518" style="width: 80%; height: auto; max-width: 80%;" stroke-width="1">
|
||||
<g id="Button_infills">
|
||||
<g id="Mute_infill" transform="translate(0,0.65) scale(0.70)">
|
||||
<path id="Mute_infill" d="M454.47,468.7c-6.47,0-12.69.04-18.75.14-.92.01-2.18.28-2.96,1.48-.56.85-.83,2.14-.8,3.81.03,2.24.41,3.3,3.67,3.32,4.47.03,8.94.02,13.41.02l5.53-.03c1.83,0,3.67,0,5.5-.01,4.41-.01,8.97-.03,13.46.04,3.68.09,4.03-1.61,4.06-3.62.02-1.47-.23-2.58-.76-3.39-.67-1.03-1.83-1.6-3.26-1.62-6.64-.08-12.98-.12-19.1-.12Z"/>
|
||||
</g>
|
||||
<g id="Down_infill" transform="translate(0,0.65) scale(0.70)">
|
||||
<path d="M177.4,357.17c-1.88,2.05-4.45,3.18-7.24,3.18h-22.91c-2.79,0-5.36-1.13-7.25-3.18-1.88-2.05-2.79-4.71-2.55-7.49l1.25-14.78c.43-5.04,2.71-9.71,6.42-13.16l9.04-8.39c1.21-1.12,2.74-1.68,4.27-1.68s2.98.54,4.18,1.61l9.44,8.45c3.87,3.47,6.24,8.23,6.68,13.4l1.23,14.55c.24,2.78-.67,5.44-2.56,7.49Z"/>
|
||||
</g>
|
||||
<g id="PS_infill" transform="translate(0,0.65) scale(0.70)">
|
||||
<path d="M455.41,437.59c11.37.03,20.87-9.06,21-20.1.14-11.24-9.39-20.97-20.61-21.05-11.23-.08-21,9.57-20.99,20.72,0,11.16,9.32,20.4,20.6,20.43Z"/>
|
||||
</g>
|
||||
<g id="Right_infill" transform="translate(0,0.65) scale(0.70)">
|
||||
<path d="M223.51,284.09v22.91c0,2.79-1.13,5.36-3.18,7.24-2.05,1.89-4.71,2.8-7.49,2.56l-14.55-1.23c-5.17-.44-9.93-2.81-13.39-6.68l-8.46-9.44c-2.17-2.43-2.14-6.06.07-8.45l8.4-9.04c3.44-3.71,8.11-5.99,13.15-6.42l14.78-1.25c2.78-.24,5.44.67,7.49,2.56,2.05,1.88,3.18,4.45,3.18,7.24Z"/>
|
||||
</g>
|
||||
<g id="Left_infill" transform="translate(0,0.65) scale(0.70)">
|
||||
<path d="M140.97,299.45l-8.46,9.44c-3.46,3.87-8.22,6.24-13.39,6.68l-14.55,1.23c-2.78.24-5.44-.67-7.49-2.56-2.05-1.88-3.18-4.45-3.18-7.24v-22.91c0-2.79,1.13-5.36,3.18-7.24,1.84-1.69,4.17-2.6,6.63-2.6.28,0,.57.01.86.04l14.78,1.25c5.04.43,9.71,2.71,13.15,6.42l8.4,9.04c2.21,2.39,2.24,6.02.07,8.45Z"/>
|
||||
</g>
|
||||
<g id="Up_infill" transform="translate(0,0.65) scale(0.70)">
|
||||
<path d="M179.96,241.41l-1.23,14.55c-.44,5.17-2.81,9.93-6.68,13.39l-9.44,8.46c-2.43,2.17-6.06,2.14-8.45-.07l-9.04-8.4c-3.71-3.44-5.99-8.11-6.42-13.15l-1.25-14.78c-.24-2.78.67-5.44,2.55-7.49,1.89-2.05,4.46-3.18,7.25-3.18h22.91c2.79,0,5.36,1.13,7.24,3.18,1.89,2.05,2.8,4.71,2.56,7.49Z"/>
|
||||
</g>
|
||||
<g id="Triangle_infill" transform="translate(0,0.65) scale(0.70)">
|
||||
<path d="M751.45,261.08c15.08-.01,26.75-11.5,26.73-26.31-.02-14.47-12.19-26.62-26.73-26.69-14.57-.07-26.65,11.99-26.66,26.63-.01,14.84,11.65,26.37,26.66,26.36Z"/>
|
||||
</g>
|
||||
<g id="Cross_infill" transform="translate(0,0.65) scale(0.70)">
|
||||
<path d="M750.93,379.05c15.44-.06,27.38-11.64,27.24-26.43-.13-14.28-12.84-26.83-26.99-26.3-14.58.55-26.43,12.2-26.39,26.91.04,14.23,11.83,25.88,26.14,25.82Z"/>
|
||||
</g>
|
||||
<g id="Circle_infill" transform="translate(0,0.65) scale(0.70)">
|
||||
<path d="M787.29,293.47c-.03,14.49,11.88,26.68,26.15,26.75,14.74.08,26.99-11.95,26.95-26.46-.04-14.51-12.12-26.34-27.04-26.48-14.04-.14-26.03,11.91-26.06,26.18Z"/>
|
||||
</g>
|
||||
<g id="Square_infill" transform="translate(0,0.65) scale(0.70)">
|
||||
<path d="M689.1,320.22c14.61.11,27.23-12.13,27.17-26.35-.06-14.09-12.36-26.44-26.54-26.66-14.42-.22-26.52,11.67-26.66,26.18-.13,14.49,11.74,26.73,26.03,26.83Z"/>
|
||||
</g>
|
||||
<g id="Options_infill" transform="translate(0,0.65) scale(0.70)">
|
||||
<path d="M691.58,199.27l-4.27,17.92c-.91,3.82-4.76,6.19-8.58,5.28-3.82-.91-6.19-4.76-5.28-8.58l4.27-17.92c.78-3.27,3.71-5.48,6.93-5.48.54,0,1.1.06,1.65.19,1.85.44,3.42,1.58,4.42,3.2s1.3,3.53.86,5.38Z"/>
|
||||
</g>
|
||||
<g id="Create_infill" transform="translate(0,0.65) scale(0.70)">
|
||||
<path d="M224.03,191.39c.55-.13,1.11-.19,1.65-.19,3.22,0,6.15,2.21,6.93,5.47l4.27,17.93c.44,1.85.13,3.76-.86,5.38-1,1.62-2.57,2.76-4.42,3.2-3.82.91-7.67-1.46-8.58-5.28l-4.27-17.92c-.91-3.82,1.46-7.67,5.28-8.58Z"/>
|
||||
</g>
|
||||
<g id="R2_infill" transform="translate(0,0.65) scale(0.70)">
|
||||
<path d="M800.14,115.88c-1.06,1.16-2.71,1.73-5.05,1.73-.01,0-.03,0-.04-.01-24.46-6.24-52.88-10.2-84.5-11.76h-.12c-4.19.08-7.09-.8-8.55-2.62-1.41-1.74-1.67-4.53-.77-8.29l.03-.15,9.87-67.57c3.29-14.17,13.23-21.12,30.28-21.12,2.57,0,5.31.16,8.22.47,13.16,1.54,22.93,6.87,29.86,16.29,2.6,3.53,4.67,7.72,6.16,12.44,7.81,24.72,11.55,46.61,15.88,71.95l.15.88c.41,3.61-.06,6.25-1.42,7.76Z"/>
|
||||
</g>
|
||||
<g id="L2_infill" transform="translate(0,0.65) scale(0.70)">
|
||||
<path d="M208.41,103.22c-1.47,1.82-4.36,2.7-8.55,2.62h-.12c-31.62,1.56-60.04,5.52-84.5,11.76-.01.01-.03.01-.04.01-2.34,0-4-.57-5.05-1.73-1.36-1.51-1.84-4.15-1.42-7.76l.15-.88c4.33-25.34,8.07-47.23,15.87-71.95,1.49-4.72,3.57-8.91,6.17-12.44,6.93-9.42,16.7-14.75,29.86-16.29,2.9-.31,5.64-.47,8.22-.47,17.05,0,26.98,6.95,30.28,21.12l9.87,67.57.03.15c.89,3.76.63,6.55-.77,8.29Z"/>
|
||||
</g>
|
||||
<g id="R1_infill" transform="translate(0,0.65) scale(0.70)">
|
||||
<path d="M805.8,173.73c-45.97-8.48-86.34-15.03-123.26-19.99,2.9-8.22,9.5-13.32,20.48-15.9,26.02-3.4,53.76,2.2,87.27,17.61.98.44,1.96.95,2.94,1.51,9.2,5.27,12.41,9.42,12.57,16.77Z"/>
|
||||
</g>
|
||||
<g id="L1_infill" transform="translate(0,0.65) scale(0.70)">
|
||||
<path d="M226.89,153.84c-42.76,6.62-84.3,13.1-123.56,19.27.76-6.19,2.09-12.15,27.86-22.29,28.7-10.58,37.26-12.24,70.44-13.64,2.49-.11,4.68,0,6.67.32,9.71,1.57,15.81,6.94,18.59,16.34Z"/>
|
||||
</g>
|
||||
</g>
|
||||
<g id="Outline" transform="translate(0,0.65) scale(0.70)">
|
||||
<g id="Controller">
|
||||
<path id="Controller_outline" d="M804.61,172.5s.09.02.13.02c-45.03-8.29-84.58-14.71-120.82-19.6.06,0,.12.02.17.02-.09.21-.14.44-.23.66-1.95.4-4.06.27-6,.85-.01-.01-.04-.03-.06-.05-.04-.13-.09-.26-.14-.39.02,0,.04,0,.07,0-4.87-.52-9.74-1.01-14.62-1.5-4.79-.46-9.6-.91-14.4-1.34h-.01s-.37-.05-.37-.05c-9.11-.83-18.27-1.58-27.45-2.28,0,.04,0,.08,0,.11,6.85.92,13.16,2.58,18.67,6.93,0,0-.01-.01-.02-.02,1.13.1,2.24.2,3.36.3,5.18,1.42,9.39,5.36,10.93,10.49,1.6,5.35,1.3,12.24-.9,20.47l-21.05,109.2c-4.19,26.12-19.01,37.08-42.82,41.56l-143.01.03-128.89-.03c-23.72-4.39-39.07-18.19-42.83-41.64l-2.11-10.93c-.29-2.09-.65-4.23-1.12-6.43l-12.19-62.64-5.57-28.92-.04-.19c-.09-.35-.16-.68-.25-1.03l-1.25-6.42s0-.03-.01-.04c-.67-4.99-.48-9.34.61-12.98,1.44-4.81,5.22-8.56,9.95-10.19,1.68-.14,3.36-.28,5.03-.42-.01,0-.02.02-.04.03.13-.02.26-.04.39-.06,1.51-.96,3.05-1.79,4.52-2.46,4.51-2.11,9.69-3.99,14.78-4.58-8.71.66-17.56,1.37-26.29,2.11l-1.11.09c-9.48.82-18.77,1.68-27.61,2.55l-.46.05s0-.01,0-.02c-.02.03-.03.06-.04.09-1.99.06-3.94-.42-5.98-.72,0-.03,0-.06-.01-.09.03,0,.06,0,.08-.01-41.23,6.38-81.95,12.73-121.09,18.88,0-.03.01-.07.02-.1l-5.76,1.61c-1.39.76-2.77,1.68-4.11,2.75-6.4,5.15-12.04,13.69-17.24,26.11-27.39,64.19-47.54,129.24-59.9,193.34C4.64,462.34-.21,530.22,3.08,597.4c2.41,40.48,7.54,66.82,16.62,85.41,9.85,20.12,24.59,31.39,46.4,35.45l39.76,12.39.33.07h.1c.97.12,1.93.18,2.86.18,13.63,0,18.84-11.41,21.55-19.96,27.65-75.71,49.02-130.11,67.27-171.19,8.52-19.59,24.3-29.11,48.23-29.11,3.5,0,7.23.21,11.11.63h.17c60.68,2.54,123.31,3.82,186.16,3.82,70.29,0,142.26-1.6,213.94-4.76,2.31-.2,4.59-.3,6.77-.3,23.28,0,39.64,11.03,50,33.68,26.25,62.96,48.44,119.86,67.83,173.94,3.28,8.94,9.45,13.47,18.32,13.47,1.52,0,3.14-.14,4.82-.4h.06s45.5-13.11,45.5-13.11c2-.48,4.05-1.09,6.27-1.86l.13-.04.72-.25v-.02c15.47-5.75,26.84-17.21,34.75-35,7.77-17.48,12.58-41.33,15.58-77.35,4.35-57.49-1.58-134.16-16.29-210.35-15.8-81.82-40.06-154.86-68.3-205.65-2.37-4.62-4.05-7.26-5.79-9.11-2.01-2.17-4.26-3.46-7.64-4.35,0-.05-.03.03-.04-.02M654.75,157.28c1.32.12,2.27.2,2.26.19,4.84.46,9.76.95,14.92,1.48-3.75,2.27-6.89,5.18-9.51,8.8-.01-.02-.01-.04-.02-.06-.81,1.03-1.56,2.12-2.23,3.26-.18-2.07-.53-4.04-1.07-5.86-.89-2.98-2.4-5.62-4.35-7.82ZM251.1,157.47l.22-.17.34-.03c-2.05,2.16-3.62,4.8-4.53,7.83-.29.95-.5,1.95-.69,2.98-.3-.5-.5-.83-.51-.82-2.55-3.31-5.76-6.16-9.46-8.41,4.54-.44,9.37-.89,14.63-1.37ZM63.74,711.34c-1.7,0-3.53-.26-5.45-.77l-.46-.09c-15.03-4.97-25.58-14.54-33.18-30.09-8.75-17.89-13.71-43.59-16.08-83.29C2.18,466.43,27.04,334.31,82.48,204.42c5.96-14.26,12.4-22.95,19.68-26.57,36.97-5.81,77.23-12.09,119.66-18.67,12.6,2.24,22,10.48,24.57,21.52.29,2.12.73,4.32,1.3,6.61l5.63,28.91,13.52,70.16c3.04,22.28-4.43,36.44-19.51,54.89-33.86,35.52-63.96,83.16-92.02,145.65-22.57,50.27-43.21,108.54-64.97,183.45-3.79,15.91-8.97,32.96-18.74,38.81-2.41,1.45-4.98,2.16-7.85,2.16ZM804.28,725.31c-1.3.21-2.54.31-3.7.31-6.47,0-10.8-3.22-13.23-9.84-19.36-54.03-41.59-111.02-67.97-174.28-11.21-24.52-29.78-36.96-55.17-36.96-2.28,0-4.64.1-6.97.3-71.45,3.15-143.25,4.75-213.42,4.75-62.79,0-125.39-1.28-185.99-3.8-3.91-.42-7.72-.63-11.32-.63-26.2,0-44.22,10.9-53.58,32.37-18.31,41.24-39.73,95.76-67.43,171.64-3.62,11.38-8.49,16.23-16.28,16.23-.66,0-1.36-.03-2.07-.1l-34.11-10.63c.47-.24.93-.49,1.38-.76,11.51-6.9,17.19-25.2,21.22-42.14,31.82-109.48,78.28-245.56,155.72-326.77l.12-.14c10.32-12.6,15.94-21.99,18.94-31.77.01.02.02.03.03.05l.04-.29c.47-1.24.83-2.6,1.14-4.03,5.82,18.4,22.43,32.57,45.18,34.56l129.25.04,143.13-.03h.24c23.32-2.05,38.12-13.14,44.92-33.72.1.51.2,1.01.32,1.53,3.02,14.37,11.49,26.24,20.3,37l.17.19c81.44,78.96,128.1,212.33,162.99,332.38,5.91,20.1,10.54,31.1,19.1,35.05l-32.95,9.49ZM902.84,602.66c-4.81,57.88-14.43,96.11-47.36,107.83-4.19,1.09-7.37,1.59-9.99,1.59-9.87,0-14.41-6.75-22.08-32.85-22.39-77.03-43.38-136.08-66.05-185.82-29.41-64.53-61.55-113.22-98.27-148.86-16.5-20.18-23.88-35.21-18.4-61.3l20.03-98.96c4.49-15.34,12.4-22.67,27.28-25.27,35.69,4.91,74.62,11.29,119,19.5h.07c5.65,1.12,7.18,2.15,11.82,11.17,60.68,109.11,92.4,301.63,83.95,412.97Z"/>
|
||||
<g id="Speaker_grill">
|
||||
<circle cx="420.29" cy="357.71" r="4.82"/>
|
||||
<circle cx="437.84" cy="357.71" r="4.82"/>
|
||||
<circle cx="455.38" cy="357.71" r="4.82"/>
|
||||
<circle cx="472.93" cy="357.71" r="4.82"/>
|
||||
<circle cx="490.47" cy="358.68" r="4.82"/>
|
||||
</g>
|
||||
<path id="L3_surround" d="M340.92,373.72c-12.1-11.94-28.56-18.52-46.36-18.52-1.03,0-2.06.02-3.11.06-16.56.69-32.12,7.92-43.82,20.35-11.43,12.15-17.66,28.1-17.11,43.7-.63,16.4,5.79,32.86,17.63,45.16,12.39,12.87,29.14,19.96,47.17,19.96h.13c17.75-.03,34.16-6.86,46.21-19.24,12.14-12.46,18.58-29.31,18.14-47.45-.41-16.77-7.12-32.41-18.9-44.04ZM296.63,478.55c-.35,0-.7,0-1.06,0-16.24,0-31.34-6.14-42.53-17.29-11.18-11.15-17.33-26.19-17.32-42.36.02-27.96,22.56-58.15,58.94-58.15h.29c16.72.07,32,6.28,43.02,17.47,10.8,10.97,16.65,25.88,16.48,41.98-.4,36.53-29.71,58.36-57.82,58.36Z"/>
|
||||
<path id="R3_surround" d="M617.17,355.14c-1.39,0-2.81.05-4.21.13-16.38,1.04-31.68,7.93-43.07,19.39-11.63,11.71-18.09,27.2-18.18,43.63-.1,18.38,6.27,34.57,18.42,46.8,12.21,12.3,29.46,19.38,47.3,19.41h.1c16.61,0,32.4-6.7,44.48-18.88,12.21-12.3,19.13-29.12,19-46.1.29-16.6-6.42-33.11-18.41-45.31-12.1-12.31-28.23-19.09-45.43-19.09ZM675.5,419.52c-.02,32.9-25.99,58.85-59.12,59.08h-.4c-15.55,0-30.85-6.54-41.96-17.95-11.2-11.5-17.15-26.51-16.74-42.27.84-32.25,26.93-57.61,59.4-57.74h.24c16.08,0,31.03,6.27,42.11,17.65,10.89,11.19,16.89,26.21,16.48,41.23Z"/>
|
||||
</g>
|
||||
<g id="Button_outlines">
|
||||
<path id="L1" d="M131.54,151.76c28.58-10.54,37.1-12.19,70.13-13.58.62-.03,1.21-.04,1.78-.04,1.7,0,3.23.11,4.69.35,8.92,1.44,14.64,6.2,17.45,14.54-.03,0-.06,0-.08.01,0,.03,0,.06.01.09,2.04.3,3.99.78,5.98.72.02-.03.03-.06.04-.09-3.07-11.83-10.65-18.79-22.53-20.72-1.76-.27-3.6-.41-5.61-.41-.63,0-1.28,0-1.95.04-5.25.22-9.69.44-13.55.68-23.59,1.48-33.63,4.15-58.32,13.26-1.9.75-3.55,1.43-5.01,2.05l-.16.07c-23.9,10.2-24.72,17.05-25.6,24.3-.02.13-.04.25-.05.38l5.76-1.61c.79-5.14,3.38-10.75,27.02-20.05Z"/>
|
||||
<path id="R1" d="M804.81,159.88c-2.27-2.33-5.34-4.53-9.35-6.83-1.04-.6-2.15-1.17-3.28-1.69-27.77-12.77-52.08-18.98-74.31-18.98-5.21,0-10.43.34-15.56,1.02l-.23.04c-13.31,3.1-21.29,9.84-24.35,20.58-.02,0-.04,0-.07,0,.05.13.1.26.14.39.02.02.05.03.06.05.49-.18,1-.3,1.52-.33,1.52-.11,3.01-.3,4.48-.51.01-.04.03-.08.05-.12.05-.18.11-.36.18-.54-.06,0-.12-.02-.17-.02,2.98-7.21,9.14-11.7,19.28-14.1,4.8-.62,9.73-.94,14.65-.94,21.43,0,44.99,6.05,72.03,18.48.91.41,1.84.89,2.85,1.47,8.44,4.83,11.54,8.54,12.01,14.69-.05,0-.09-.02-.13-.02.06.13.12.25.16.39.02.06.05.12.07.18,1.01.07,1.98.26,2.89.58.87-.31,1.74-.34,2.57-.15-.14-5.55-1.73-9.75-5.49-13.61Z"/>
|
||||
<path id="L2_outline" d="M115.16,122.1h.4l.52-.07.06-.02c24.15-6.19,52.33-10.12,83.69-11.68h.47c5.39,0,9.3-1.44,11.61-4.29,2.31-2.88,2.86-6.94,1.67-11.99l-9.91-67.79c-3.78-16.37-15.49-24.66-34.81-24.66-2.7,0-5.6.17-8.61.49-14.28,1.66-25.37,7.75-32.97,18.08-2.9,3.94-5.2,8.57-6.83,13.75-7.91,25.05-11.67,47.06-16.02,72.55l-.18,1.03c-.57,5.06.28,8.9,2.55,11.39,1.92,2.12,4.73,3.2,8.34,3.2ZM109.72,108.29l.15-.89c4.32-25.3,8.06-47.16,15.84-71.81,1.46-4.61,3.48-8.7,6.02-12.15,6.76-9.19,16.3-14.38,29.16-15.89,2.88-.31,5.61-.46,8.11-.46,16.53,0,26.12,6.66,29.29,20.26l9.88,67.62.04.18c.81,3.44.62,5.94-.57,7.43-1.21,1.5-3.65,2.25-7.25,2.25h-.69c-31.62,1.56-60.09,5.52-84.61,11.76-1.98-.02-3.35-.48-4.19-1.4-1.15-1.27-1.55-3.69-1.18-6.92Z"/>
|
||||
<path id="R2_outline" d="M709.98,110.34h.41c31.43,1.56,59.6,5.48,83.74,11.68l.06.02.53.07h.4c3.61,0,6.42-1.08,8.34-3.2,2.27-2.5,3.13-6.33,2.54-11.45l-.17-.97c-4.35-25.49-8.11-47.5-16.02-72.55-1.63-5.18-3.93-9.81-6.83-13.75-7.61-10.33-18.71-16.42-32.99-18.08-3-.33-5.89-.49-8.6-.49-19.32,0-31.03,8.3-34.82,24.74l-9.87,67.63c-1.21,5.13-.66,9.2,1.66,12.08,2.31,2.85,6.22,4.29,11.61,4.29ZM702.09,95.12l.04-.2,9.85-67.49c3.18-13.69,12.77-20.35,29.31-20.35,2.49,0,5.22.16,8.1.46,12.87,1.51,22.41,6.7,29.17,15.89,2.53,3.43,4.55,7.52,6.01,12.15,7.79,24.65,11.52,46.51,15.85,71.82l.14.83c.37,3.3-.03,5.71-1.17,6.97-.85.93-2.22,1.39-4.19,1.4-24.52-6.25-52.99-10.21-84.66-11.77h-.64c-3.56,0-6.07-.77-7.26-2.25-1.2-1.49-1.4-3.99-.56-7.47Z"/>
|
||||
<path id="Create_outline" d="M218.64,218.94c1.25,5.26,5.9,8.93,11.31,8.93.92,0,1.83-.11,2.69-.32,3.02-.72,5.57-2.57,7.2-5.22,1.63-2.65,2.13-5.76,1.41-8.77l-4.26-17.93c-1.25-5.26-5.9-8.93-11.31-8.93-.9,0-1.81.11-2.7.32-3.02.71-5.57,2.57-7.2,5.21-1.63,2.65-2.13,5.76-1.42,8.78l4.27,17.93ZM220.47,195.11c.86-1.4,2.21-2.37,3.79-2.75.46-.11.93-.16,1.42-.16,2.85,0,5.3,1.93,5.96,4.7l4.27,17.93c.38,1.59.11,3.23-.74,4.62-.86,1.4-2.21,2.38-3.8,2.75-.47.11-.94.17-1.42.17-2.85,0-5.3-1.94-5.96-4.71l-4.27-17.93c-.38-1.59-.11-3.23.75-4.62Z"/>
|
||||
<path id="Options_outline" d="M677.7,226.85c.91.21,1.82.32,2.69.32,5.4,0,10.05-3.68,11.3-8.94l4.27-17.92c.72-3.02.22-6.15-1.41-8.79-1.63-2.64-4.18-4.5-7.2-5.22-.88-.21-1.79-.31-2.69-.31-5.41,0-10.06,3.67-11.32,8.93l-4.27,17.93c-1.49,6.23,2.38,12.51,8.62,14.01ZM674.43,214.12l4.26-17.92c.66-2.77,3.11-4.71,5.96-4.71.5,0,.96.06,1.42.17,1.59.38,2.94,1.35,3.8,2.74.85,1.38,1.12,3.03.74,4.63l-4.26,17.92c-.66,2.77-3.11,4.71-5.96,4.71-.47,0-.95-.06-1.42-.17-1.59-.38-2.94-1.35-3.8-2.75-.86-1.39-1.12-3.04-.74-4.63Z"/>
|
||||
<path id="Left_outline" d="M99.81,321.31c1.27.35,2.6.53,3.93.53.42,0,.83-.02,1.25-.06l14.55-1.23c5.53-.47,10.68-2.71,14.76-6.39.68-.6,1.32-1.25,1.94-1.94l8.45-9.44c3.91-4.36,3.85-10.88-.13-15.18l-8.39-9.04c-4.29-4.63-10.11-7.47-16.4-8l-14.78-1.25c-4.13-.36-8.24,1.05-11.29,3.85s-4.8,6.79-4.8,10.93v22.91c0,4.14,1.75,8.12,4.8,10.93,1.75,1.61,3.85,2.76,6.11,3.38ZM93.9,284.09c0-2.79,1.13-5.36,3.18-7.24,1.84-1.69,4.17-2.6,6.63-2.6.28,0,.57.01.86.04l14.78,1.25c5.04.43,9.71,2.71,13.15,6.42l8.4,9.04c2.21,2.39,2.24,6.02.07,8.45l-8.46,9.44c-3.46,3.87-8.22,6.24-13.39,6.68l-14.55,1.23c-2.78.24-5.44-.67-7.49-2.56-2.05-1.88-3.18-4.45-3.18-7.24v-22.91Z"/>
|
||||
<path id="Right_outline" d="M172.85,287.6c-3.98,4.3-4.04,10.82-.14,15.18l8.27,9.23.19.21c4.32,4.83,10.25,7.78,16.7,8.33l14.55,1.23c.42.04.83.06,1.25.06,1.4,0,2.79-.2,4.12-.58,2.18-.64,4.22-1.76,5.92-3.33,3.05-2.81,4.8-6.79,4.8-10.93v-22.91c0-4.14-1.75-8.13-4.8-10.93-3.05-2.8-7.16-4.2-11.29-3.85l-14.78,1.25c-.74.06-1.48.16-2.2.28-2.7.47-5.27,1.36-7.65,2.64-2.43,1.31-4.64,3.01-6.55,5.08l-8.39,9.04ZM198.06,275.54l14.78-1.25c2.78-.24,5.44.67,7.49,2.56,2.05,1.88,3.18,4.45,3.18,7.24v22.91c0,2.79-1.13,5.36-3.18,7.24-2.05,1.89-4.71,2.8-7.49,2.56l-14.55-1.23c-5.17-.44-9.93-2.81-13.39-6.68l-8.46-9.44c-2.17-2.43-2.14-6.06.07-8.45l8.4-9.04c3.44-3.71,8.11-5.99,13.15-6.42Z"/>
|
||||
<path id="Down_outline" d="M183.71,334.71c-.13-1.61-.42-3.18-.84-4.71-.05-.16-.1-.32-.15-.47-.22-.68-.45-1.34-.69-2-1.43-3.61-3.69-6.87-6.65-9.52l-9.44-8.46c-4.36-3.9-10.88-3.85-15.18.14l-9.04,8.39c-1.05.97-2,2.01-2.85,3.12-2.94,3.82-4.74,8.41-5.15,13.28l-1.25,14.78c-.15,1.83.03,3.65.54,5.38.62,2.18,1.75,4.21,3.31,5.91,2.8,3.05,6.79,4.8,10.93,4.8h22.91c4.14,0,8.12-1.75,10.93-4.8,2.8-3.05,4.2-7.16,3.85-11.29l-1.23-14.55ZM177.4,357.17c-1.88,2.05-4.45,3.18-7.24,3.18h-22.91c-2.79,0-5.36-1.13-7.25-3.18-1.88-2.05-2.79-4.71-2.55-7.49l1.25-14.78c.43-5.04,2.71-9.71,6.42-13.16l9.04-8.39c1.21-1.12,2.74-1.68,4.27-1.68s2.98.54,4.18,1.61l9.44,8.45c3.87,3.47,6.24,8.23,6.68,13.4l1.23,14.55c.24,2.78-.67,5.44-2.56,7.49Z"/>
|
||||
<path id="Up_outline" d="M133.72,256.61c.48,5.73,2.88,11.07,6.81,15.22.38.41.78.8,1.19,1.18l9.04,8.39c2.18,2.02,4.92,3.03,7.67,3.03s5.36-.97,7.51-2.9l9.44-8.45c1.35-1.2,2.55-2.53,3.58-3.96,2.51-3.43,4.1-7.44,4.64-11.72.05-.34.08-.68.11-1.02l1.23-14.55c.35-4.13-1.05-8.24-3.85-11.29-2.81-3.05-6.79-4.8-10.93-4.8h-22.91c-4.14,0-8.13,1.75-10.93,4.8-1.53,1.66-2.64,3.64-3.27,5.76-.54,1.77-.74,3.65-.58,5.53l1.25,14.78ZM140,233.92c1.89-2.05,4.46-3.18,7.25-3.18h22.91c2.79,0,5.36,1.13,7.24,3.18,1.89,2.05,2.8,4.71,2.56,7.49l-1.23,14.55c-.44,5.17-2.81,9.93-6.68,13.39l-9.44,8.46c-2.43,2.17-6.06,2.14-8.45-.07l-9.04-8.4c-3.71-3.44-5.99-8.11-6.42-13.15l-1.25-14.78c-.24-2.78.67-5.44,2.55-7.49Z"/>
|
||||
<path id="Cross_outline" d="M751.82,321.39h-.11c-8.53,0-16.94,3.65-23.08,10.01-5.91,6.13-9.01,13.94-8.72,21.98.63,17.53,13.54,30.1,31.38,30.57h.03c17.47,0,31.35-13.6,31.6-30.96.12-8.05-3.19-16.1-9.08-22.09-5.9-6.01-13.93-9.48-22.02-9.51ZM770.09,370.25c-4.93,5-11.74,7.77-19.16,7.8h-.1c-13.76,0-24.99-11.14-25.03-24.82-.04-13.99,11.13-25.37,25.43-25.91.28-.01.56-.02.84-.02,13.25,0,24.99,11.83,25.12,25.32.06,6.67-2.46,12.93-7.09,17.63Z"/>
|
||||
<path id="Triangle_outline" d="M751.06,266c.21,0,.41,0,.62,0,8.36,0,16.79-3.45,22.54-9.22,5.71-5.73,8.72-13.49,8.69-22.44-.05-17.11-14.19-31.03-31.52-31.03h-.19c-17.15.1-31.24,14.15-31.4,31.3-.08,8.08,3.16,15.85,9.1,21.87,5.94,6.02,14.02,9.48,22.16,9.51ZM751.32,209.08h.12c13.93.07,25.71,11.83,25.73,25.69.01,6.89-2.62,13.27-7.4,17.98-4.79,4.71-11.3,7.31-18.35,7.32-6.99,0-13.47-2.6-18.25-7.33-4.77-4.72-7.4-11.13-7.39-18.03.01-14.13,11.47-25.63,25.53-25.63Z"/>
|
||||
<path id="Circle_outline" d="M791.23,272.06c-5.72,5.82-8.79,13.5-8.65,21.62.31,17.85,13.17,30.72,31.27,31.3.3,0,.6.01.9.01,16.35,0,30.24-14.13,30.33-30.86.05-8.44-3.12-16.31-8.92-22.14-5.91-5.94-13.96-9.21-22.68-9.21-8.47,0-16.37,3.3-22.25,9.28ZM839.39,293.77c.02,6.64-2.62,12.96-7.44,17.78-4.93,4.95-11.46,7.67-18.37,7.67,0,0-.14,0-.14,0-13.66-.07-25.18-11.87-25.15-25.75.03-13.65,11.4-25.19,24.83-25.19h.23c14.33.14,26.01,11.57,26.05,25.49Z"/>
|
||||
<path id="Square_outline" d="M691.99,262.62c-.79-.06-1.6-.09-2.38-.09-8.46,0-16.39,3.35-22.34,9.45-5.74,5.88-8.93,13.76-8.74,21.58-.29,17.51,12.78,31.02,30.42,31.42.26,0,.52,0,.78,0,17.09,0,30.37-12.98,30.9-30.18.51-16.54-12.34-30.97-28.64-32.18ZM707.82,311.38c-4.97,4.99-11.72,7.85-18.53,7.85,0,0-.18,0-.18,0-6.58-.05-12.82-2.74-17.59-7.59-4.87-4.95-7.51-11.43-7.45-18.24.13-13.89,11.46-25.19,25.26-25.19h.38c13.56.21,25.5,12.2,25.56,25.67.03,6.44-2.62,12.65-7.44,17.5Z"/>
|
||||
<path id="PS_outline" d="M455.4,442.49h.21c14.28-.12,25.41-11.31,25.35-25.47-.06-14.05-11.44-25.51-25.42-25.54-13.74,0-25.39,11.7-25.44,25.55-.03,6.72,2.63,13.09,7.46,17.95,4.82,4.84,11.16,7.51,17.84,7.51ZM441.75,403.34c3.78-3.75,8.85-5.9,13.92-5.9h.13c5.08.04,10.12,2.23,13.84,6.02,3.73,3.8,5.84,8.91,5.78,14.02-.13,10.54-9.08,19.11-20,19.11h0c-10.81-.02-19.6-8.74-19.6-19.43,0-5.03,2.17-10.07,5.94-13.82Z"/>
|
||||
<path id="Mute_outline" d="M474.24,464.3c-6.6-.06-13.03-.1-19.11-.1-6.51,0-12.67.04-18.82.11-2.55.03-4.67.99-6.15,2.77-1.4,1.7-2.12,4.04-2.07,6.78.07,3.52,1.54,7.73,8.15,7.76,2.64.01,5.27.02,7.91.02h11.06s1.74-.03,1.74-.03c0,0,7.44-.02,9.31-.02,2.62,0,5.25,0,7.86.04h.17c7.21,0,8.38-5.01,8.43-8,.05-2.57-.65-4.8-2.03-6.45-1.54-1.85-3.77-2.85-6.45-2.88ZM473.79,476.4h-2.19c-2.66-.05-2.76-.04-5.42-.04-1.84,0-10.97.03-10.97.03l-5.52.04h-5.9c-2.5,0-5,0-7.5-.02-.93,0-2.31-.66-2.33-2.29-.02-1.53-.18-2.63.18-3.31.57-1.06,1.65-1.24,2.25-1.25,6.08-.11,12.21-.17,18.74-.17,6.06,0,12.48.05,19.09.15,1.14.02,2.07.53,2.55,1.42.21.4.5,1.12.47,2.82-.02,1.47-.69,2.61-3.43,2.61Z"/>
|
||||
</g>
|
||||
</g>
|
||||
<g transform="translate(0,0.65) scale(0.70)">
|
||||
<g id="Trackpad_infill" >
|
||||
<path d="M452.27,328.53v-.02c40.22,0,80.43.07,120.65-.07,6.47-.02,13.17.01,19.36-1.58,19.32-4.99,29.59-18.18,33.51-36.6,7.44-34.93,15.37-69.99,21.95-105.09,1.8-9.6-.91-20.7-9.35-26.91-6.53-4.8-15.07-5.38-22.94-6-15.84-1.24-31.65-1.69-47.52-2.33-25.29-1.01-52.32-3.71-77.62-4-59.86-.67-117.65,1.12-177.41,5.09-10.18.68-20.91.48-30.97,2.12-12.6,2.05-25.72,12.82-22.5,31.32,2.97,17.08,7.65,34.26,11,51.28,3.72,18.85,7.61,37.68,11.08,56.58,2.33,12.67,8.64,23.23,19.04,30.56,9.97,7.03,21.64,5.61,33.14,5.62,39.53.06,79.06.02,118.6.02Z"/>
|
||||
</g>
|
||||
<g id="Trackpad_outline" >
|
||||
<path d="M272.25,153.56c-4.52,2.07-9.76,5.6-12.42,9.85-4.66,6.89-3.71,15.95-1.11,26.9l19.74,98.37c4.52,27.51,18.61,41.63,45.84,43.95h.12l235.94.06c-4.66-.08,4.33,0,9.56,0,35.3,0,49.5-11.1,56.07-37.73l20.44-101.35c4.26-16.93,3.93-29.59-6.87-37.71-6.24-4.92-13.49-6.41-21.4-7.26-52.97-4-107.12-6.03-161.4-6.03-.3,0-.6,0-.9,0-2.3-.01-4.58-.02-6.81-.02-.36,0-.72,0-1.08,0-.33,0-.66,0-1,0-3.06.02-6.18.05-9.34.09-48.92.43-98.66,2.47-148.15,6.11-5.85.15-12,2.31-17.24,4.76ZM641.07,192.4l-20.45,101.35c-6.01,24.35-18.98,33.44-50.41,33.44-3.02,0-6.24.2-9.64,0l-235.88-.06c-24.7-2.11-36.7-14.33-40.82-39.44l-19.79-98.56c-2.23-9.46-3.46-17.08.31-22.64,4.07-6.04,11.93-10.09,23.26-12.03,13.9-1.04,27.83-1.95,41.74-2.73,35.06-1.79,70.63-3.02,101.96-3.47.19,0,.38,0,.58,0,1.55-.02,3.08-.04,4.6-.06,6.53-.06,13.04-.09,19.54-.09,46.61.2,104.83,2.34,158.55,5.8,3.45.26,7.4.89,10.36,1.77,18.01,5.87,21.08,16.85,16.09,36.73Z"/>
|
||||
</g>
|
||||
</g>
|
||||
<g id="L3" transform="translate(0,0.65) scale(0.70)">
|
||||
<g id="L3_infill">
|
||||
<path d="M295.63,461.03c23.36,0,41.53-17.87,41.57-40.86.03-23.53-18.65-42.27-42.16-42.27-23.09,0-41.82,18.55-41.83,41.45-.01,23.9,18.09,41.69,42.42,41.69Z"/>
|
||||
</g>
|
||||
<g id="L3_outline">
|
||||
<path d="M295.14,466.67c-26.36-.18-47.62-21.47-47.16-47.19.51-28.21,21.76-46.51,47.28-47.04,25.52-.53,47.65,22.07,47.37,47.25-.29,26.05-21.63,47.15-47.5,46.98ZM295.63,461.03c23.36,0,41.53-17.87,41.57-40.86.03-23.53-18.65-42.27-42.16-42.27-23.09,0-41.82,18.55-41.83,41.45-.01,23.9,18.09,41.69,42.42,41.69Z"/>
|
||||
</g>
|
||||
</g>
|
||||
<g id="R3" transform="translate(0,0.65) scale(0.70)">
|
||||
<g id="R3_infill">
|
||||
<path d="M658.23,419.7c.55-22.76-17.76-41.19-40.35-41.72-23.43-.55-42.68,18.19-43.29,40.74-.65,23.92,18.7,41.15,39.11,42.46,25.96,1.66,44.96-18.72,44.52-41.48Z"/>
|
||||
</g>
|
||||
<g id="R3_outline">
|
||||
<path d="M664.07,419.78c-.01,26.37-21.16,47.39-47.6,47.32-26.19-.06-48.19-21.58-47.62-47.5.59-26.82,21.12-47.52,48.44-47.45,26.83.08,46.79,21.47,46.78,47.62ZM658.23,419.7c.55-22.76-17.76-41.19-40.35-41.72-23.43-.55-42.68,18.19-43.29,40.74-.65,23.92,18.7,41.15,39.11,42.46,25.96,1.66,44.96-18.72,44.52-41.48Z"/>
|
||||
</g>
|
||||
</g>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 23 KiB |
27
assets/icons.svg
Normal file
27
assets/icons.svg
Normal file
@@ -0,0 +1,27 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" class="d-none">
|
||||
<symbol id="paypal" viewBox="0 0 384 512">
|
||||
<path fill="#ffffff" d="M111.4 295.9c-3.5 19.2-17.4 108.7-21.5 134-.3 1.8-1 2.5-3 2.5H12.3c-7.6 0-13.1-6.6-12.1-13.9L58.8 46.6c1.5-9.6 10.1-16.9 20-16.9 152.3 0 165.1-3.7 204 11.4 60.1 23.3 65.6 79.5 44 140.3-21.5 62.6-72.5 89.5-140.1 90.3-43.4 .7-69.5-7-75.3 24.2zM357.1 152c-1.8-1.3-2.5-1.8-3 1.3-2 11.4-5.1 22.5-8.8 33.6-39.9 113.8-150.5 103.9-204.5 103.9-6.1 0-10.1 3.3-10.9 9.4-22.6 140.4-27.1 169.7-27.1 169.7-1 7.1 3.5 12.9 10.6 12.9h63.5c8.6 0 15.7-6.3 17.4-14.9 .7-5.4-1.1 6.1 14.4-91.3 4.6-22 14.3-19.7 29.3-19.7 71 0 126.4-28.8 142.9-112.3 6.5-34.8 4.6-71.4-23.8-92.6z"/>
|
||||
</symbol>
|
||||
<symbol id="ethereum" viewBox="0 0 320 512">
|
||||
<path fill="#ffffff" d="M311.9 260.8L160 353.6 8 260.8 160 0l151.9 260.8zM160 383.4L8 290.6 160 512l152-221.4-152 92.8z"/>
|
||||
</symbol>
|
||||
|
||||
<symbol id="info" viewBox="0 -860 960 960">
|
||||
<path d="M440-280h80v-240h-80v240Zm40-320q17 0 28.5-11.5T520-640q0-17-11.5-28.5T480-680q-17 0-28.5 11.5T440-640q0 17 11.5 28.5T480-600Zm0 520q-83 0-156-31.5T197-197q-54-54-85.5-127T80-480q0-83 31.5-156T197-763q54-54 127-85.5T480-880q83 0 156 31.5T763-763q54 54 85.5 127T880-480q0 83-31.5 156T763-197q-54 54-127 85.5T480-80Zm0-80q134 0 227-93t93-227q0-134-93-227t-227-93q-134 0-227 93t-93 227q0 134 93 227t227 93Zm0-320Z"/>
|
||||
</symbol>
|
||||
<symbol id="discord" viewBox="0 0 640 512">
|
||||
<path d="M524.531,69.836a1.5,1.5,0,0,0-.764-.7A485.065,485.065,0,0,0,404.081,32.03a1.816,1.816,0,0,0-1.923.91,337.461,337.461,0,0,0-14.9,30.6,447.848,447.848,0,0,0-134.426,0,309.541,309.541,0,0,0-15.135-30.6,1.89,1.89,0,0,0-1.924-.91A483.689,483.689,0,0,0,116.085,69.137a1.712,1.712,0,0,0-.788.676C39.068,183.651,18.186,294.69,28.43,404.354a2.016,2.016,0,0,0,.765,1.375A487.666,487.666,0,0,0,176.02,479.918a1.9,1.9,0,0,0,2.063-.676A348.2,348.2,0,0,0,208.12,430.4a1.86,1.86,0,0,0-1.019-2.588,321.173,321.173,0,0,1-45.868-21.853,1.885,1.885,0,0,1-.185-3.126c3.082-2.309,6.166-4.711,9.109-7.137a1.819,1.819,0,0,1,1.9-.256c96.229,43.917,200.41,43.917,295.5,0a1.812,1.812,0,0,1,1.924.233c2.944,2.426,6.027,4.851,9.132,7.16a1.884,1.884,0,0,1-.162,3.126,301.407,301.407,0,0,1-45.89,21.83,1.875,1.875,0,0,0-1,2.611,391.055,391.055,0,0,0,30.014,48.815,1.864,1.864,0,0,0,2.063.7A486.048,486.048,0,0,0,610.7,405.729a1.882,1.882,0,0,0,.765-1.352C623.729,277.594,590.933,167.465,524.531,69.836ZM222.491,337.58c-28.972,0-52.844-26.587-52.844-59.239S193.056,219.1,222.491,219.1c29.665,0,53.306,26.82,52.843,59.239C275.334,310.993,251.924,337.58,222.491,337.58Zm195.38,0c-28.971,0-52.843-26.587-52.843-59.239S388.437,219.1,417.871,219.1c29.667,0,53.307,26.82,52.844,59.239C470.715,310.993,447.538,337.58,417.871,337.58Z"/>
|
||||
</symbol>
|
||||
<symbol id="mail" viewBox="0 0 512 512">
|
||||
<path d="M48 64C21.5 64 0 85.5 0 112c0 15.1 7.1 29.3 19.2 38.4L236.8 313.6c11.4 8.5 27 8.5 38.4 0L492.8 150.4c12.1-9.1 19.2-23.3 19.2-38.4c0-26.5-21.5-48-48-48H48zM0 176V384c0 35.3 28.7 64 64 64H448c35.3 0 64-28.7 64-64V176L294.4 339.2c-22.8 17.1-54 17.1-76.8 0L0 176z"/>
|
||||
</symbol>
|
||||
<symbol id="github" viewBox="0 0 496 512">
|
||||
<path d="M165.9 397.4c0 2-2.3 3.6-5.2 3.6-3.3.3-5.6-1.3-5.6-3.6 0-2 2.3-3.6 5.2-3.6 3-.3 5.6 1.3 5.6 3.6zm-31.1-4.5c-.7 2 1.3 4.3 4.3 4.9 2.6 1 5.6 0 6.2-2s-1.3-4.3-4.3-5.2c-2.6-.7-5.5.3-6.2 2.3zm44.2-1.7c-2.9.7-4.9 2.6-4.6 4.9.3 2 2.9 3.3 5.9 2.6 2.9-.7 4.9-2.6 4.6-4.6-.3-1.9-3-3.2-5.9-2.9zM244.8 8C106.1 8 0 113.3 0 252c0 110.9 69.8 205.8 169.5 239.2 12.8 2.3 17.3-5.6 17.3-12.1 0-6.2-.3-40.4-.3-61.4 0 0-70 15-84.7-29.8 0 0-11.4-29.1-27.8-36.6 0 0-22.9-15.7 1.6-15.4 0 0 24.9 2 38.6 25.8 21.9 38.6 58.6 27.5 72.9 20.9 2.3-16 8.8-27.1 16-33.7-55.9-6.2-112.3-14.3-112.3-110.5 0-27.5 7.6-41.3 23.6-58.9-2.6-6.5-11.1-33.3 2.6-67.9 20.9-6.5 69 27 69 27 20-5.6 41.5-8.5 62.8-8.5s42.8 2.9 62.8 8.5c0 0 48.1-33.6 69-27 13.7 34.7 5.2 61.4 2.6 67.9 16 17.7 25.8 31.5 25.8 58.9 0 96.5-58.9 104.2-114.8 110.5 9.2 7.9 17 22.9 17 46.4 0 33.7-.3 75.4-.3 83.6 0 6.5 4.6 14.4 17.3 12.1C428.2 457.8 496 362.9 496 252 496 113.3 383.5 8 244.8 8zM97.2 352.9c-1.3 1-1 3.3.7 5.2 1.6 1.6 3.9 2.3 5.2 1 1.3-1 1-3.3-.7-5.2-1.6-1.6-3.9-2.3-5.2-1zm-10.8-8.1c-.7 1.3.3 2.9 2.3 3.9 1.6 1 3.6.7 4.3-.7.7-1.3-.3-2.9-2.3-3.9-2-.6-3.6-.3-4.3.7zm32.4 35.6c-1.6 1.3-1 4.3 1.3 6.2 2.3 2.3 5.2 2.6 6.5 1 1.3-1.3.7-4.3-1.3-6.2-2.2-2.3-5.2-2.6-6.5-1zm-11.4-14.7c-1.6 1-1.6 3.6 0 5.9 1.6 2.3 4.3 3.3 5.6 2.3 1.6-1.3 1.6-3.9 0-6.2-1.4-2.3-4-3.3-5.6-2z"/>
|
||||
</symbol>
|
||||
<symbol id="mug" viewBox="0 0 512 512">
|
||||
<path fill="#ffffff" d="M88 0C74.7 0 64 10.7 64 24c0 38.9 23.4 59.4 39.1 73.1l1.1 1C120.5 112.3 128 119.9 128 136c0 13.3 10.7 24 24 24s24-10.7 24-24c0-38.9-23.4-59.4-39.1-73.1l-1.1-1C119.5 47.7 112 40.1 112 24c0-13.3-10.7-24-24-24zM32 192c-17.7 0-32 14.3-32 32V416c0 53 43 96 96 96H288c53 0 96-43 96-96h16c61.9 0 112-50.1 112-112s-50.1-112-112-112H352 32zm352 64h16c26.5 0 48 21.5 48 48s-21.5 48-48 48H384V256zM224 24c0-13.3-10.7-24-24-24s-24 10.7-24 24c0 38.9 23.4 59.4 39.1 73.1l1.1 1C232.5 112.3 240 119.9 240 136c0 13.3 10.7 24 24 24s24-10.7 24-24c0-38.9-23.4-59.4-39.1-73.1l-1.1-1C231.5 47.7 224 40.1 224 24z"/>
|
||||
</symbol>
|
||||
<symbol id="lang" viewBox="0 0 640 512">
|
||||
<path d="M0 128C0 92.7 28.7 64 64 64H256h48 16H576c35.3 0 64 28.7 64 64V384c0 35.3-28.7 64-64 64H320 304 256 64c-35.3 0-64-28.7-64-64V128zm320 0V384H576V128H320zM178.3 175.9c-3.2-7.2-10.4-11.9-18.3-11.9s-15.1 4.7-18.3 11.9l-64 144c-4.5 10.1 .1 21.9 10.2 26.4s21.9-.1 26.4-10.2l8.9-20.1h73.6l8.9 20.1c4.5 10.1 16.3 14.6 26.4 10.2s14.6-16.3 10.2-26.4l-64-144zM160 233.2L179 276H141l19-42.8zM448 164c11 0 20 9 20 20v4h44 16c11 0 20 9 20 20s-9 20-20 20h-2l-1.6 4.5c-8.9 24.4-22.4 46.6-39.6 65.4c.9 .6 1.8 1.1 2.7 1.6l18.9 11.3c9.5 5.7 12.5 18 6.9 27.4s-18 12.5-27.4 6.9l-18.9-11.3c-4.5-2.7-8.8-5.5-13.1-8.5c-10.6 7.5-21.9 14-34 19.4l-3.6 1.6c-10.1 4.5-21.9-.1-26.4-10.2s.1-21.9 10.2-26.4l3.6-1.6c6.4-2.9 12.6-6.1 18.5-9.8l-12.2-12.2c-7.8-7.8-7.8-20.5 0-28.3s20.5-7.8 28.3 0l14.6 14.6 .5 .5c12.4-13.1 22.5-28.3 29.8-45H448 376c-11 0-20-9-20-20s9-20 20-20h52v-4c0-11 9-20 20-20z"/>
|
||||
</symbol>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 5.9 KiB |
116
css/finetune.css
Normal file
116
css/finetune.css
Normal file
@@ -0,0 +1,116 @@
|
||||
/* Styles for fine-tuning interface */
|
||||
|
||||
/* Styling for coordinate labels - base state to prevent layout shift */
|
||||
#finetuneStickCanvasLx-lbl,
|
||||
#finetuneStickCanvasLy-lbl,
|
||||
#finetuneStickCanvasRx-lbl,
|
||||
#finetuneStickCanvasRy-lbl {
|
||||
padding: 2px 4px !important;
|
||||
border-radius: 3px !important;
|
||||
background-color: transparent !important;
|
||||
}
|
||||
|
||||
/* Styling for finetune input boxes - base state to prevent layout shift */
|
||||
input[id^="finetune"] {
|
||||
border: 1px solid transparent !important;
|
||||
width: 90px !important;
|
||||
min-width: 90px !important;
|
||||
color: #969696 !important;
|
||||
}
|
||||
|
||||
/* Styling for highlighted coordinate labels */
|
||||
#finetuneStickCanvasLx-lbl.text-primary,
|
||||
#finetuneStickCanvasLy-lbl.text-primary,
|
||||
#finetuneStickCanvasRx-lbl.text-primary,
|
||||
#finetuneStickCanvasRy-lbl.text-primary {
|
||||
color: #0d6efd !important;
|
||||
background-color: rgba(13, 110, 253, 0.1) !important;
|
||||
}
|
||||
|
||||
/* CSS Grid layout for finetune inputs around canvas */
|
||||
.finetune-grid {
|
||||
display: grid;
|
||||
grid-template-columns: 1fr auto 1fr;
|
||||
grid-template-rows: auto 1fr auto;
|
||||
grid-template-areas:
|
||||
". top ."
|
||||
"left center right"
|
||||
". bottom .";
|
||||
justify-items: center;
|
||||
align-items: center;
|
||||
width: 100%;
|
||||
margin: 0 auto;
|
||||
max-width: fit-content;
|
||||
}
|
||||
|
||||
.finetune-top {
|
||||
grid-area: top;
|
||||
}
|
||||
|
||||
.finetune-left {
|
||||
grid-area: left;
|
||||
}
|
||||
|
||||
.finetune-center {
|
||||
grid-area: center;
|
||||
}
|
||||
|
||||
.finetune-right {
|
||||
grid-area: right;
|
||||
}
|
||||
|
||||
.finetune-bottom {
|
||||
grid-area: bottom;
|
||||
}
|
||||
|
||||
/* Finetune mode visibility controls */
|
||||
.finetune-center-mode {
|
||||
display: block;
|
||||
}
|
||||
|
||||
.finetune-circularity-mode {
|
||||
display: none;
|
||||
}
|
||||
|
||||
/* When circularity mode is active */
|
||||
#finetuneModal.circularity-mode .finetune-center-mode {
|
||||
display: none;
|
||||
}
|
||||
|
||||
#finetuneModal.circularity-mode .finetune-circularity-mode {
|
||||
display: block;
|
||||
}
|
||||
|
||||
/* Hide raw numbers mode - hide input boxes when checkbox is unchecked */
|
||||
#finetuneModal.hide-raw-numbers .finetune-top,
|
||||
#finetuneModal.hide-raw-numbers .finetune-left,
|
||||
#finetuneModal.hide-raw-numbers .finetune-right,
|
||||
#finetuneModal.hide-raw-numbers .finetune-bottom {
|
||||
display: none;
|
||||
}
|
||||
|
||||
/* Adjust grid layout when raw numbers are hidden - center the canvas */
|
||||
#finetuneModal.hide-raw-numbers .finetune-grid {
|
||||
grid-template-columns: 1fr;
|
||||
grid-template-rows: 1fr;
|
||||
grid-template-areas: "center";
|
||||
}
|
||||
|
||||
/* when element with id finetuneModal has class hide-raw-numbers, hide all elements with id finetuneStickCanvasL and finetuneStickCanvasR */
|
||||
#finetuneModal.hide-raw-numbers #finetuneStickCanvasL,
|
||||
#finetuneModal.hide-raw-numbers #finetuneStickCanvasR {
|
||||
display: none;
|
||||
}
|
||||
#finetuneModal:not(.hide-raw-numbers) #finetuneStickCanvasL,
|
||||
#finetuneModal:not(.hide-raw-numbers) #finetuneStickCanvasR {
|
||||
display: block;
|
||||
}
|
||||
#finetuneModal.hide-raw-numbers #finetuneStickCanvasL_large,
|
||||
#finetuneModal.hide-raw-numbers #finetuneStickCanvasR_large
|
||||
{
|
||||
display: block;
|
||||
}
|
||||
#finetuneModal:not(.hide-raw-numbers) #finetuneStickCanvasL_large,
|
||||
#finetuneModal:not(.hide-raw-numbers) #finetuneStickCanvasR_large {
|
||||
display: none;
|
||||
}
|
||||
28
css/main.css
Normal file
28
css/main.css
Normal file
@@ -0,0 +1,28 @@
|
||||
/* Main styles for DualShock Calibration GUI */
|
||||
|
||||
/* Add padding to body to prevent content from being hidden behind fixed footer */
|
||||
body {
|
||||
padding-bottom: 80px;
|
||||
}
|
||||
|
||||
dl.row dt {
|
||||
font-weight: normal;
|
||||
}
|
||||
dl.row dd {
|
||||
font-family: monospace;
|
||||
}
|
||||
|
||||
#left-stick-card,
|
||||
#right-stick-card {
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
.stick-card-active {
|
||||
border: 1px solid #0d6efd !important;
|
||||
box-shadow: 0 0 10px rgba(13, 110, 253, 0.3) !important;
|
||||
}
|
||||
|
||||
.stick-card-active .card-header {
|
||||
background-color: #0d6efd !important;
|
||||
color: white !important;
|
||||
}
|
||||
183
dev-server.js
Normal file
183
dev-server.js
Normal file
@@ -0,0 +1,183 @@
|
||||
#!/usr/bin/env node
|
||||
|
||||
import https from 'https';
|
||||
import http from 'http';
|
||||
import fs from 'fs';
|
||||
import path from 'path';
|
||||
import { fileURLToPath } from 'url';
|
||||
|
||||
const __filename = fileURLToPath(import.meta.url);
|
||||
const __dirname = path.dirname(__filename);
|
||||
|
||||
// Configuration
|
||||
const config = {
|
||||
port: process.env.PORT || 8443,
|
||||
httpPort: process.env.HTTP_PORT || 8080,
|
||||
host: process.env.HOST || 'localhost',
|
||||
distDir: path.join(__dirname, 'dist'),
|
||||
certFile: path.join(__dirname, 'server.crt'),
|
||||
keyFile: path.join(__dirname, 'server.key'),
|
||||
useHttps: process.env.HTTPS === 'true'
|
||||
};
|
||||
|
||||
// MIME types
|
||||
const mimeTypes = {
|
||||
'.html': 'text/html',
|
||||
'.js': 'text/javascript',
|
||||
'.css': 'text/css',
|
||||
'.json': 'application/json',
|
||||
'.png': 'image/png',
|
||||
'.jpg': 'image/jpeg',
|
||||
'.gif': 'image/gif',
|
||||
'.svg': 'image/svg+xml',
|
||||
'.ico': 'image/x-icon',
|
||||
'.webmanifest': 'application/manifest+json'
|
||||
};
|
||||
|
||||
function getMimeType(filePath) {
|
||||
const ext = path.extname(filePath).toLowerCase();
|
||||
return mimeTypes[ext] || 'application/octet-stream';
|
||||
}
|
||||
|
||||
function requestHandler(req, res) {
|
||||
// Parse URL and remove query parameters
|
||||
let urlPath = new URL(req.url, `http://${req.headers.host}`).pathname;
|
||||
|
||||
// Default to index.html for root requests
|
||||
if (urlPath === '/') {
|
||||
urlPath = '/index.html';
|
||||
}
|
||||
|
||||
const filePath = path.join(config.distDir, urlPath);
|
||||
const mimeType = getMimeType(filePath);
|
||||
|
||||
// Security check - ensure file is within dist directory
|
||||
if (!filePath.startsWith(config.distDir)) {
|
||||
res.writeHead(403, { 'Content-Type': 'text/plain' });
|
||||
res.end('Forbidden');
|
||||
return;
|
||||
}
|
||||
|
||||
// Set CORS headers for development
|
||||
res.setHeader('Access-Control-Allow-Origin', '*');
|
||||
res.setHeader('Access-Control-Allow-Methods', 'GET, POST, PUT, DELETE, OPTIONS');
|
||||
res.setHeader('Access-Control-Allow-Headers', 'Content-Type, Authorization');
|
||||
|
||||
// Disable caching for development
|
||||
res.setHeader('Cache-Control', 'no-cache, no-store, must-revalidate');
|
||||
res.setHeader('Pragma', 'no-cache');
|
||||
res.setHeader('Expires', '0');
|
||||
|
||||
// Handle OPTIONS requests
|
||||
if (req.method === 'OPTIONS') {
|
||||
res.writeHead(200);
|
||||
res.end();
|
||||
return;
|
||||
}
|
||||
|
||||
fs.readFile(filePath, (err, data) => {
|
||||
if (err) {
|
||||
if (err.code === 'ENOENT') {
|
||||
// Try to serve index.html for SPA routing
|
||||
const indexPath = path.join(config.distDir, 'index.html');
|
||||
fs.readFile(indexPath, (indexErr, indexData) => {
|
||||
if (indexErr) {
|
||||
res.writeHead(404, { 'Content-Type': 'text/plain' });
|
||||
res.end('Not Found');
|
||||
} else {
|
||||
res.writeHead(200, { 'Content-Type': 'text/html' });
|
||||
res.end(indexData);
|
||||
}
|
||||
});
|
||||
} else {
|
||||
res.writeHead(500, { 'Content-Type': 'text/plain' });
|
||||
res.end('Internal Server Error');
|
||||
}
|
||||
} else {
|
||||
res.writeHead(200, { 'Content-Type': mimeType });
|
||||
res.end(data);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
function startServer() {
|
||||
// Check if dist directory exists
|
||||
if (!fs.existsSync(config.distDir)) {
|
||||
console.error(`❌ Dist directory not found: ${config.distDir}`);
|
||||
console.log('💡 Run "npm run build" first to build the application');
|
||||
process.exit(1);
|
||||
}
|
||||
|
||||
if (config.useHttps) {
|
||||
// Check if SSL certificates exist
|
||||
if (!fs.existsSync(config.certFile) || !fs.existsSync(config.keyFile)) {
|
||||
console.error('❌ SSL certificates not found');
|
||||
console.log('💡 SSL certificates are required for WebHID API');
|
||||
console.log(' Make sure server.crt and server.key exist in the project root');
|
||||
process.exit(1);
|
||||
}
|
||||
|
||||
// Read SSL certificates
|
||||
const options = {
|
||||
key: fs.readFileSync(config.keyFile),
|
||||
cert: fs.readFileSync(config.certFile)
|
||||
};
|
||||
|
||||
// Create HTTPS server
|
||||
const server = https.createServer(options, requestHandler);
|
||||
|
||||
server.listen(config.port, config.host, () => {
|
||||
console.log('🚀 Development server started!');
|
||||
console.log(`📱 App running at: https://${config.host}:${config.port}`);
|
||||
console.log('🔒 HTTPS enabled (required for WebHID API)');
|
||||
console.log('💡 Press Ctrl+C to stop the server');
|
||||
console.log('');
|
||||
console.log('📝 Note: You may need to accept the self-signed certificate in your browser');
|
||||
});
|
||||
|
||||
server.on('error', (err) => {
|
||||
if (err.code === 'EADDRINUSE') {
|
||||
console.error(`❌ Port ${config.port} is already in use`);
|
||||
console.log('💡 Try using a different port: PORT=8444 npm run serve:https');
|
||||
} else {
|
||||
console.error('❌ Server error:', err.message);
|
||||
}
|
||||
process.exit(1);
|
||||
});
|
||||
} else {
|
||||
// Create HTTP server (for testing only - WebHID won't work)
|
||||
const server = http.createServer(requestHandler);
|
||||
|
||||
server.listen(config.httpPort, config.host, () => {
|
||||
console.log('🚀 Development server started!');
|
||||
console.log(`📱 App running at: http://${config.host}:${config.httpPort}`);
|
||||
console.log('⚠️ HTTP mode - WebHID API will only work on localhost');
|
||||
console.log('💡 Use "npm run serve:https" to enable WebHID support to other clients on the local network');
|
||||
console.log('💡 Press Ctrl+C to stop the server');
|
||||
});
|
||||
|
||||
server.on('error', (err) => {
|
||||
if (err.code === 'EADDRINUSE') {
|
||||
console.error(`❌ Port ${config.httpPort} is already in use`);
|
||||
console.log('💡 Try using a different port: HTTP_PORT=8081 npm run serve');
|
||||
} else {
|
||||
console.error('❌ Server error:', err.message);
|
||||
}
|
||||
process.exit(1);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
// Handle graceful shutdown
|
||||
process.on('SIGINT', () => {
|
||||
console.log('\n👋 Shutting down development server...');
|
||||
process.exit(0);
|
||||
});
|
||||
|
||||
process.on('SIGTERM', () => {
|
||||
console.log('\n👋 Shutting down development server...');
|
||||
process.exit(0);
|
||||
});
|
||||
|
||||
// Start the server
|
||||
startServer();
|
||||
318
gulpfile.js
Normal file
318
gulpfile.js
Normal file
@@ -0,0 +1,318 @@
|
||||
import gulp from 'gulp';
|
||||
import cleanCSS from 'gulp-clean-css';
|
||||
import htmlmin from 'gulp-htmlmin';
|
||||
import concat from 'gulp-concat';
|
||||
import sourcemaps from 'gulp-sourcemaps';
|
||||
import gulpif from 'gulp-if';
|
||||
import rename from 'gulp-rename';
|
||||
import { deleteAsync } from 'del';
|
||||
import yargs from 'yargs';
|
||||
import { hideBin } from 'yargs/helpers';
|
||||
import replace from 'gulp-replace';
|
||||
import jsonMinify from 'gulp-json-minify';
|
||||
import crypto from 'crypto';
|
||||
import { rollup } from 'rollup';
|
||||
import { nodeResolve } from '@rollup/plugin-node-resolve';
|
||||
import rollupTerser from '@rollup/plugin-terser';
|
||||
import fs from 'fs/promises';
|
||||
import path from 'path';
|
||||
import { glob } from 'glob';
|
||||
|
||||
// Get command line arguments
|
||||
const argv = yargs(hideBin(process.argv)).argv;
|
||||
const isProduction = argv.production || process.env.NODE_ENV === 'production';
|
||||
|
||||
// Paths configuration
|
||||
const paths = {
|
||||
src: {
|
||||
js: {
|
||||
entry: 'js/core.js',
|
||||
all: 'js/**/*.js'
|
||||
},
|
||||
css: ['css/main.css', 'css/finetune.css'],
|
||||
html: {
|
||||
main: 'index.html',
|
||||
templates: 'templates/**/*.html'
|
||||
},
|
||||
lang: 'lang/**/*.json',
|
||||
assets: [
|
||||
'favicon.ico',
|
||||
'favicon.svg',
|
||||
'favicon-16x16.png',
|
||||
'favicon-32x32.png',
|
||||
'favicon-96x96.png',
|
||||
'apple-touch-icon.png',
|
||||
'web-app-manifest-192x192.png',
|
||||
'web-app-manifest-512x512.png',
|
||||
'site.webmanifest',
|
||||
'donate.png',
|
||||
'googlec4c2e36a49e62fa3.html',
|
||||
'fa.min.css'
|
||||
],
|
||||
svg: 'assets/**/*.svg'
|
||||
},
|
||||
dist: 'dist',
|
||||
temp: '.tmp'
|
||||
};
|
||||
|
||||
// Clean task
|
||||
function clean() {
|
||||
return deleteAsync([paths.dist, paths.temp]);
|
||||
}
|
||||
|
||||
// JavaScript bundling with Rollup
|
||||
async function scripts() {
|
||||
const inputOptions = {
|
||||
input: paths.src.js.entry,
|
||||
plugins: [
|
||||
nodeResolve(),
|
||||
...(isProduction ? [
|
||||
rollupTerser({
|
||||
compress: {
|
||||
drop_console: false,
|
||||
drop_debugger: true,
|
||||
pure_funcs: ['console.debug', 'console.trace'],
|
||||
passes: 2,
|
||||
unsafe: true,
|
||||
unsafe_comps: true,
|
||||
unsafe_math: true,
|
||||
unsafe_proto: true
|
||||
},
|
||||
mangle: {
|
||||
reserved: [
|
||||
'gboot', 'connect', 'disconnect', 'disconnectSync',
|
||||
'show_faq_modal', 'calibrate_stick_centers', 'calibrate_range',
|
||||
'ds5_finetune', 'auto_calibrate_stick_centers', 'flash_all_changes',
|
||||
'reboot_controller', 'welcome_accepted', 'show_info_tab',
|
||||
'nvslock', 'nvsunlock', 'refresh_nvstatus', 'show_edge_modal',
|
||||
'show_donate_modal'
|
||||
],
|
||||
properties: {
|
||||
regex: /^_/
|
||||
}
|
||||
},
|
||||
format: {
|
||||
comments: false
|
||||
}
|
||||
})
|
||||
] : [])
|
||||
]
|
||||
};
|
||||
|
||||
let filename = 'app.js';
|
||||
|
||||
if (isProduction) {
|
||||
const bundle = await rollup(inputOptions);
|
||||
const { output } = await bundle.generate({ format: 'es' });
|
||||
const code = output[0].code;
|
||||
const hash = crypto.createHash('md5').update(code).digest('hex').substring(0, 8);
|
||||
filename = `app-${hash}.js`;
|
||||
|
||||
await fs.writeFile(path.join(paths.dist, filename), code);
|
||||
await bundle.close();
|
||||
} else {
|
||||
const outputOptions = {
|
||||
file: path.join(paths.dist, filename),
|
||||
format: 'es',
|
||||
sourcemap: true
|
||||
};
|
||||
|
||||
const bundle = await rollup(inputOptions);
|
||||
await bundle.write(outputOptions);
|
||||
await bundle.close();
|
||||
}
|
||||
|
||||
// Store the filename for HTML processing
|
||||
global.jsFilename = filename;
|
||||
return Promise.resolve();
|
||||
}
|
||||
|
||||
// CSS processing
|
||||
function styles() {
|
||||
let stream = gulp.src(paths.src.css)
|
||||
.pipe(gulpif(!isProduction, sourcemaps.init()))
|
||||
.pipe(concat('app.css'));
|
||||
|
||||
if (isProduction) {
|
||||
stream = stream.pipe(cleanCSS({
|
||||
level: 2
|
||||
}));
|
||||
|
||||
// Add hash to filename in production
|
||||
stream = stream.pipe(rename(function(path) {
|
||||
const hash = crypto.createHash('md5').update(Date.now().toString()).digest('hex').substring(0, 8);
|
||||
path.basename = `app-${hash}`;
|
||||
global.cssFilename = `${path.basename}.css`;
|
||||
}));
|
||||
} else {
|
||||
stream = stream.pipe(sourcemaps.write('.'));
|
||||
global.cssFilename = 'app.css';
|
||||
}
|
||||
|
||||
return stream.pipe(gulp.dest(paths.dist));
|
||||
}
|
||||
|
||||
// Bundle templates and SVG assets into HTML for production
|
||||
async function bundleAssets() {
|
||||
if (!isProduction) {
|
||||
return Promise.resolve();
|
||||
}
|
||||
|
||||
try {
|
||||
// Read all template files
|
||||
const templateFiles = await glob('templates/**/*.html');
|
||||
const templates = {};
|
||||
|
||||
for (const templateFile of templateFiles) {
|
||||
const content = await fs.readFile(templateFile, 'utf8');
|
||||
const templateName = path.basename(templateFile, '.html');
|
||||
templates[templateName] = content;
|
||||
}
|
||||
|
||||
// Read SVG assets
|
||||
const svgFiles = await glob('assets/**/*.svg');
|
||||
const svgAssets = {};
|
||||
|
||||
for (const svgFile of svgFiles) {
|
||||
const content = await fs.readFile(svgFile, 'utf8');
|
||||
const assetName = path.relative('assets', svgFile);
|
||||
svgAssets[assetName] = content;
|
||||
}
|
||||
|
||||
// Create the bundled assets object
|
||||
const bundledAssets = {
|
||||
templates,
|
||||
svg: svgAssets
|
||||
};
|
||||
|
||||
// Store for use in HTML processing
|
||||
global.bundledAssets = bundledAssets;
|
||||
return Promise.resolve();
|
||||
} catch (error) {
|
||||
console.error('Error bundling assets:', error);
|
||||
throw error;
|
||||
}
|
||||
}
|
||||
|
||||
// HTML processing
|
||||
async function html() {
|
||||
const jsFile = global.jsFilename || 'app.js';
|
||||
const cssFile = global.cssFilename || 'app.css';
|
||||
|
||||
let htmlContent = await fs.readFile(paths.src.html.main, 'utf8');
|
||||
|
||||
// Replace script and CSS references
|
||||
htmlContent = htmlContent.replace('<script type="module" src="js/core.js"></script>', `<script type="module" src="${jsFile}"></script>`);
|
||||
htmlContent = htmlContent.replace('<link rel="stylesheet" href="css/main.css">', '');
|
||||
htmlContent = htmlContent.replace('<link rel="stylesheet" href="css/finetune.css">', `<link rel="stylesheet" href="${cssFile}">`);
|
||||
|
||||
// In production, inject bundled assets
|
||||
if (isProduction && global.bundledAssets) {
|
||||
const bundledAssetsScript = `
|
||||
<script type="text/javascript">
|
||||
window.BUNDLED_ASSETS = ${JSON.stringify(global.bundledAssets)};
|
||||
</script>`;
|
||||
|
||||
// Insert the bundled assets script before the main app script
|
||||
htmlContent = htmlContent.replace(
|
||||
`<script type="module" src="${jsFile}"></script>`,
|
||||
`${bundledAssetsScript}\n<script type="module" src="${jsFile}"></script>`
|
||||
);
|
||||
}
|
||||
|
||||
if (isProduction) {
|
||||
// Use htmlmin to minify the content
|
||||
const htmlMinify = (await import('html-minifier-terser')).minify;
|
||||
htmlContent = await htmlMinify(htmlContent, {
|
||||
caseSensitive: false,
|
||||
collapseBooleanAttributes: true,
|
||||
collapseInlineTagWhitespace: false,
|
||||
collapseWhitespace: true,
|
||||
conservativeCollapse: false,
|
||||
decodeEntities: true,
|
||||
html5: true,
|
||||
includeAutoGeneratedTags: true,
|
||||
keepClosingSlash: false,
|
||||
minifyCSS: true,
|
||||
minifyJS: true,
|
||||
minifyURLs: false,
|
||||
preserveLineBreaks: false,
|
||||
preventAttributesEscaping: false,
|
||||
processConditionalComments: false,
|
||||
removeAttributeQuotes: true,
|
||||
removeComments: true,
|
||||
removeEmptyAttributes: true,
|
||||
removeEmptyElements: false,
|
||||
removeOptionalTags: true,
|
||||
removeRedundantAttributes: true,
|
||||
removeScriptTypeAttributes: true,
|
||||
removeStyleLinkTypeAttributes: true,
|
||||
removeTagWhitespace: false,
|
||||
sortAttributes: true,
|
||||
sortClassName: true,
|
||||
trimCustomFragments: true,
|
||||
useShortDoctype: true
|
||||
});
|
||||
}
|
||||
|
||||
// Write the processed HTML file
|
||||
await fs.writeFile(path.join(paths.dist, 'index.html'), htmlContent);
|
||||
return Promise.resolve();
|
||||
}
|
||||
|
||||
// Template processing (only for development builds)
|
||||
function templates() {
|
||||
if (isProduction) {
|
||||
// In production, templates are bundled into the HTML file
|
||||
return Promise.resolve();
|
||||
}
|
||||
|
||||
return gulp.src(paths.src.html.templates)
|
||||
.pipe(gulp.dest(`${paths.dist}/templates`));
|
||||
}
|
||||
|
||||
// Language files processing
|
||||
function languages() {
|
||||
return gulp.src(paths.src.lang)
|
||||
.pipe(gulpif(isProduction, jsonMinify()))
|
||||
.pipe(gulp.dest(`${paths.dist}/lang`));
|
||||
}
|
||||
|
||||
// Copy assets (SVGs are bundled in production)
|
||||
function assets() {
|
||||
if (isProduction) {
|
||||
// In production, SVGs are bundled into the HTML file, so only copy other assets
|
||||
return gulp.src(paths.src.assets, { base: '.' })
|
||||
.pipe(gulp.dest(paths.dist));
|
||||
}
|
||||
|
||||
return gulp.src([...paths.src.assets, paths.src.svg], { base: '.' })
|
||||
.pipe(gulp.dest(paths.dist));
|
||||
}
|
||||
|
||||
// Watch task
|
||||
function watch() {
|
||||
gulp.watch(paths.src.js.all, scripts);
|
||||
gulp.watch(paths.src.css, styles);
|
||||
gulp.watch([paths.src.html.main, paths.src.html.templates], gulp.series(html, templates));
|
||||
gulp.watch(paths.src.lang, languages);
|
||||
gulp.watch([...paths.src.assets, paths.src.svg], assets);
|
||||
}
|
||||
|
||||
// Development task
|
||||
function dev() {
|
||||
console.log('🚀 Development mode - watching files for changes...');
|
||||
return watch();
|
||||
}
|
||||
|
||||
// Build task
|
||||
const build = gulp.series(
|
||||
clean,
|
||||
gulp.parallel(scripts, styles),
|
||||
bundleAssets,
|
||||
gulp.parallel(html, templates, languages, assets)
|
||||
);
|
||||
|
||||
// Export tasks
|
||||
export { clean, scripts, styles, bundleAssets, html, templates, languages, assets, watch, dev, build };
|
||||
export default build;
|
||||
1026
index.html
1026
index.html
File diff suppressed because it is too large
Load Diff
479
js/controller-manager.js
Normal file
479
js/controller-manager.js
Normal file
@@ -0,0 +1,479 @@
|
||||
'use strict';
|
||||
|
||||
import { sleep, la } from './utils.js';
|
||||
|
||||
/**
|
||||
* Controller Manager - Manages the current controller instance and provides unified interface
|
||||
*/
|
||||
class ControllerManager {
|
||||
constructor(uiDependencies = {}) {
|
||||
this.currentController = null;
|
||||
this.l = uiDependencies.l;
|
||||
this.handleNvStatusUpdate = uiDependencies.handleNvStatusUpdate;
|
||||
this.has_changes_to_write = null;
|
||||
this.inputHandler = null; // Callback function for input processing
|
||||
|
||||
// Button and stick states for UI updates
|
||||
this.button_states = {
|
||||
// e.g. 'square': false, 'cross': false, ...
|
||||
sticks: {
|
||||
left: {
|
||||
x: 0,
|
||||
y: 0
|
||||
},
|
||||
right: {
|
||||
x: 0,
|
||||
y: 0
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
// Touch points for touchpad input
|
||||
this.touchPoints = [];
|
||||
|
||||
// Battery status tracking
|
||||
this.batteryStatus = {
|
||||
bat_txt: "",
|
||||
changed: false,
|
||||
bat_capacity: 0,
|
||||
cable_connected: false,
|
||||
is_charging: false,
|
||||
is_error: false
|
||||
};
|
||||
this._lastBatteryText = "";
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the current controller instance
|
||||
* @param {BaseController} controller Controller instance
|
||||
*/
|
||||
setControllerInstance(instance) {
|
||||
this.currentController = instance;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the current device (for backward compatibility)
|
||||
* @returns {HIDDevice|null} Current device or null if none set
|
||||
*/
|
||||
getDevice() {
|
||||
return this.currentController?.getDevice() || null;
|
||||
}
|
||||
|
||||
getInputConfig() {
|
||||
return this.currentController.getInputConfig();
|
||||
}
|
||||
|
||||
async getDeviceInfo() {
|
||||
return await this.currentController.getInfo();
|
||||
}
|
||||
|
||||
getFinetuneMaxValue() {
|
||||
return this.currentController.getFinetuneMaxValue();
|
||||
}
|
||||
|
||||
/**
|
||||
* Set input report handler on the underlying device
|
||||
* @param {Function|null} handler Input report handler function or null to clear
|
||||
*/
|
||||
setInputReportHandler(handler) {
|
||||
this.currentController.device.oninputreport = handler;
|
||||
}
|
||||
|
||||
/**
|
||||
* Query NVS (Non-Volatile Storage) status
|
||||
* @returns {Promise<Object>} NVS status object
|
||||
*/
|
||||
async queryNvStatus() {
|
||||
const nv = await this.currentController.queryNvStatus();
|
||||
this.handleNvStatusUpdate(nv);
|
||||
return nv;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get in-memory module data (finetune data)
|
||||
* @returns {Promise<Array>} Module data array
|
||||
*/
|
||||
async getInMemoryModuleData() {
|
||||
return await this.currentController.getInMemoryModuleData();
|
||||
}
|
||||
|
||||
/**
|
||||
* Write finetune data to controller
|
||||
* @param {Array} data Finetune data array
|
||||
*/
|
||||
async writeFinetuneData(data) {
|
||||
await this.currentController.writeFinetuneData(data);
|
||||
}
|
||||
|
||||
getModel() {
|
||||
return this.currentController.getModel();
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if a controller is connected
|
||||
* @returns {boolean} True if controller is connected
|
||||
*/
|
||||
isConnected() {
|
||||
return this.currentController !== null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the input callback function
|
||||
* @param {Function} callback - Function to call after processing input
|
||||
*/
|
||||
setInputHandler(callback) {
|
||||
this.inputHandler = callback;
|
||||
}
|
||||
|
||||
/**
|
||||
* Disconnect the current controller
|
||||
*/
|
||||
async disconnect() {
|
||||
if (this.currentController) {
|
||||
await this.currentController.close();
|
||||
this.currentController = null;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Update NVS changes status and UI
|
||||
* @param {boolean} hasChanges Changes status
|
||||
*/
|
||||
setHasChangesToWrite(hasChanges) {
|
||||
if (hasChanges === this.has_changes_to_write)
|
||||
return;
|
||||
|
||||
const saveBtn = $("#savechanges");
|
||||
saveBtn
|
||||
.prop('disabled', !hasChanges)
|
||||
.toggleClass('btn-success', hasChanges)
|
||||
.toggleClass('btn-outline-secondary', !hasChanges);
|
||||
|
||||
this.has_changes_to_write = hasChanges;
|
||||
}
|
||||
|
||||
// Unified controller operations that delegate to the current controller
|
||||
|
||||
/**
|
||||
* Flash/save changes to the controller
|
||||
*/
|
||||
async flash(progressCallback = null) {
|
||||
this.setHasChangesToWrite(false);
|
||||
return this.currentController.flash(progressCallback);
|
||||
}
|
||||
|
||||
/**
|
||||
* Reset the controller
|
||||
*/
|
||||
async reset() {
|
||||
await this.currentController.reset();
|
||||
}
|
||||
|
||||
/**
|
||||
* Unlock NVS (Non-Volatile Storage)
|
||||
*/
|
||||
async nvsUnlock() {
|
||||
await this.currentController.nvsUnlock();
|
||||
await this.queryNvStatus(); // Refresh NVS status
|
||||
}
|
||||
|
||||
/**
|
||||
* Lock NVS (Non-Volatile Storage)
|
||||
*/
|
||||
async nvsLock() {
|
||||
const res = await this.currentController.nvsLock();
|
||||
if (!res.ok) {
|
||||
throw new Error(this.l("NVS Lock failed"), { cause: res.error });
|
||||
}
|
||||
|
||||
await this.queryNvStatus(); // Refresh NVS status
|
||||
return res;
|
||||
}
|
||||
|
||||
/**
|
||||
* Begin stick calibration
|
||||
*/
|
||||
async calibrateSticksBegin() {
|
||||
const res = await this.currentController.calibrateSticksBegin();
|
||||
if (!res.ok) {
|
||||
throw new Error(`${this.l("Stick calibration failed")}. ${res.error?.message}`, { cause: res.error });
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Sample stick position during calibration
|
||||
*/
|
||||
async calibrateSticksSample() {
|
||||
const res = await this.currentController.calibrateSticksSample();
|
||||
if (!res.ok) {
|
||||
await sleep(500);
|
||||
throw new Error(this.l("Stick calibration failed"), { cause: res.error });
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* End stick calibration
|
||||
*/
|
||||
async calibrateSticksEnd() {
|
||||
const res = await this.currentController.calibrateSticksEnd();
|
||||
if (!res.ok) {
|
||||
await sleep(500);
|
||||
throw new Error(this.l("Stick calibration failed"), { cause: res.error });
|
||||
}
|
||||
|
||||
this.setHasChangesToWrite(true);
|
||||
}
|
||||
|
||||
/**
|
||||
* Begin stick range calibration (for UI-driven calibration)
|
||||
*/
|
||||
async calibrateRangeBegin() {
|
||||
const res = await this.currentController.calibrateRangeBegin();
|
||||
if (!res.ok) {
|
||||
throw new Error(`${this.l("Stick calibration failed")}. ${res.error?.message}`, { cause: res.error });
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Handle range calibration on close
|
||||
*/
|
||||
async calibrateRangeOnClose() {
|
||||
const res = await this.currentController.calibrateRangeEnd();
|
||||
if(res?.ok) {
|
||||
this.setHasChangesToWrite(true);
|
||||
return { success: true, message: this.l("Range calibration completed") };
|
||||
} else {
|
||||
// Check if the error is code 3 (DS4/DS5) or codes 4/5 (DS5 Edge), which typically means
|
||||
// the calibration was already ended or the controller is not in range calibration mode
|
||||
if (res?.code === 3 || res?.code === 4 || res?.code === 5) {
|
||||
console.log("Range calibration end returned expected error code", res.code, "- treating as successful completion");
|
||||
// This is likely not an error - the calibration may have already been completed
|
||||
// or the user closed the window without starting calibration
|
||||
return { success: true, message: this.l("Range calibration window closed") };
|
||||
}
|
||||
|
||||
console.log("Range calibration end failed with unexpected error:", res);
|
||||
await sleep(500);
|
||||
const msg = res?.code ? (this.l("Range calibration failed") + this.l("Error ") + String(res.code)) : (this.l("Range calibration failed") + String(res?.error || ""));
|
||||
return { success: false, message: msg, error: res?.error };
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Full stick calibration process ("OLD" fully automated calibration)
|
||||
* @param {Function} progressCallback - Callback function to report progress (0-100)
|
||||
*/
|
||||
async calibrateSticks(progressCallback) {
|
||||
try {
|
||||
la("multi_calibrate_sticks");
|
||||
|
||||
progressCallback(20);
|
||||
await this.calibrateSticksBegin();
|
||||
progressCallback(30);
|
||||
|
||||
// Sample multiple times during the process
|
||||
const sampleCount = 5;
|
||||
for (let i = 0; i < sampleCount; i++) {
|
||||
await sleep(100);
|
||||
await this.calibrateSticksSample();
|
||||
|
||||
// Progress from 30% to 80% during sampling
|
||||
const sampleProgress = 30 + ((i + 1) / sampleCount) * 50;
|
||||
progressCallback(Math.round(sampleProgress));
|
||||
}
|
||||
|
||||
progressCallback(90);
|
||||
await this.calibrateSticksEnd();
|
||||
progressCallback(100);
|
||||
|
||||
return { success: true, message: this.l("Stick calibration completed") };
|
||||
} catch (e) {
|
||||
la("multi_calibrate_sticks_failed", {"r": e});
|
||||
throw e;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Helper function to check if stick positions have changed
|
||||
*/
|
||||
_sticksChanged(current, newValues) {
|
||||
return current.left.x !== newValues.left.x || current.left.y !== newValues.left.y ||
|
||||
current.right.x !== newValues.right.x || current.right.y !== newValues.right.y;
|
||||
}
|
||||
|
||||
/**
|
||||
* Generic button processing for DS4/DS5
|
||||
* Records button states and returns changes
|
||||
*/
|
||||
_recordButtonStates(data, BUTTON_MAP, dpad_byte, l2_analog_byte, r2_analog_byte) {
|
||||
const changes = {};
|
||||
|
||||
// Stick positions (always at bytes 0-3)
|
||||
const [new_lx, new_ly, new_rx, new_ry] = [0, 1, 2, 3]
|
||||
.map(i => data.getUint8(i))
|
||||
.map(v => Math.round((v - 127.5) / 128 * 100) / 100);
|
||||
|
||||
const newSticks = {
|
||||
left: { x: new_lx, y: new_ly },
|
||||
right: { x: new_rx, y: new_ry }
|
||||
};
|
||||
|
||||
if (this._sticksChanged(this.button_states.sticks, newSticks)) {
|
||||
this.button_states.sticks = newSticks;
|
||||
changes.sticks = newSticks;
|
||||
}
|
||||
|
||||
// L2/R2 analog values
|
||||
[
|
||||
['l2', l2_analog_byte],
|
||||
['r2', r2_analog_byte]
|
||||
].forEach(([name, byte]) => {
|
||||
const val = data.getUint8(byte);
|
||||
const key = name + '_analog';
|
||||
if (val !== this.button_states[key]) {
|
||||
this.button_states[key] = val;
|
||||
changes[key] = val;
|
||||
}
|
||||
});
|
||||
|
||||
// Dpad is a 4-bit hat value
|
||||
const hat = data.getUint8(dpad_byte) & 0x0F;
|
||||
const dpad_map = {
|
||||
up: (hat === 0 || hat === 1 || hat === 7),
|
||||
right: (hat === 1 || hat === 2 || hat === 3),
|
||||
down: (hat === 3 || hat === 4 || hat === 5),
|
||||
left: (hat === 5 || hat === 6 || hat === 7)
|
||||
};
|
||||
for (const dir of ['up', 'right', 'down', 'left']) {
|
||||
const pressed = dpad_map[dir];
|
||||
if (this.button_states[dir] !== pressed) {
|
||||
this.button_states[dir] = pressed;
|
||||
changes[dir] = pressed;
|
||||
}
|
||||
}
|
||||
|
||||
// Other buttons
|
||||
for (const btn of BUTTON_MAP) {
|
||||
if (['up', 'right', 'down', 'left'].includes(btn.name)) continue; // Dpad handled above
|
||||
const pressed = (data.getUint8(btn.byte) & btn.mask) !== 0;
|
||||
if (this.button_states[btn.name] !== pressed) {
|
||||
this.button_states[btn.name] = pressed;
|
||||
changes[btn.name] = pressed;
|
||||
}
|
||||
}
|
||||
|
||||
return changes;
|
||||
}
|
||||
|
||||
/**
|
||||
* Process controller input data and call callback if set
|
||||
* This is the first part of the split process_controller_input function
|
||||
* @param {Object} inputData - The input data from the controller
|
||||
* @returns {Object} Changes object containing processed input data
|
||||
*/
|
||||
processControllerInput(inputData) {
|
||||
const { data } = inputData;
|
||||
|
||||
const inputConfig = this.currentController.getInputConfig();
|
||||
const { buttonMap, dpadByte, l2AnalogByte, r2AnalogByte } = inputConfig;
|
||||
const { touchpadOffset } = inputConfig;
|
||||
|
||||
// Process button states using the device-specific configuration
|
||||
const changes = this._recordButtonStates(data, buttonMap, dpadByte, l2AnalogByte, r2AnalogByte);
|
||||
|
||||
// Parse and store touch points if touchpad data is available
|
||||
if (touchpadOffset) {
|
||||
this.touchPoints = this._parseTouchPoints(data, touchpadOffset);
|
||||
}
|
||||
|
||||
// Parse and store battery status
|
||||
this.batteryStatus = this._parseBatteryStatus(data);
|
||||
|
||||
const result = {
|
||||
changes,
|
||||
inputConfig: { buttonMap },
|
||||
touchPoints: this.touchPoints,
|
||||
batteryStatus: this.batteryStatus,
|
||||
};
|
||||
|
||||
this.inputHandler(result);
|
||||
}
|
||||
|
||||
/**
|
||||
* Parse touch points from input data
|
||||
* @param {DataView} data - Input data view
|
||||
* @param {number} offset - Offset to touchpad data
|
||||
* @returns {Array} Array of touch points with {active, id, x, y} properties
|
||||
*/
|
||||
_parseTouchPoints(data, offset) {
|
||||
// Returns array of up to 2 points: {active, id, x, y}
|
||||
const points = [];
|
||||
for (let i = 0; i < 2; i++) {
|
||||
const base = offset + i * 4;
|
||||
const arr = [];
|
||||
for (let j = 0; j < 4; j++) arr.push(data.getUint8(base + j));
|
||||
const b0 = data.getUint8(base);
|
||||
const active = (b0 & 0x80) === 0; // 0 = finger down, 1 = up
|
||||
const id = b0 & 0x7F;
|
||||
const b1 = data.getUint8(base + 1);
|
||||
const b2 = data.getUint8(base + 2);
|
||||
const b3 = data.getUint8(base + 3);
|
||||
// x: 12 bits, y: 12 bits
|
||||
const x = ((b2 & 0x0F) << 8) | b1;
|
||||
const y = (b3 << 4) | (b2 >> 4);
|
||||
points.push({ active, id, x, y });
|
||||
}
|
||||
return points;
|
||||
}
|
||||
|
||||
/**
|
||||
* Parse battery status from input data
|
||||
*/
|
||||
_parseBatteryStatus(data) {
|
||||
const batteryInfo = this.currentController.parseBatteryStatus(data);
|
||||
const bat_txt = this._batteryPercentToText(batteryInfo);
|
||||
|
||||
const changed = bat_txt !== this._lastBatteryText;
|
||||
this._lastBatteryText = bat_txt;
|
||||
|
||||
return { bat_txt, changed, ...batteryInfo };
|
||||
}
|
||||
|
||||
/**
|
||||
* Convert battery percentage to display text with icons
|
||||
*/
|
||||
_batteryPercentToText({bat_capacity, is_charging, is_error}) {
|
||||
if (is_error) {
|
||||
return '<font color="red">' + this.l("error") + '</font>';
|
||||
}
|
||||
|
||||
const batteryIcons = [
|
||||
{ threshold: 20, icon: 'fa-battery-empty' },
|
||||
{ threshold: 40, icon: 'fa-battery-quarter' },
|
||||
{ threshold: 60, icon: 'fa-battery-half' },
|
||||
{ threshold: 80, icon: 'fa-battery-three-quarters' },
|
||||
];
|
||||
|
||||
const icon_txt = batteryIcons.find(item => bat_capacity < item.threshold)?.icon || 'fa-battery-full';
|
||||
const icon_full = `<i class="fa-solid ${icon_txt}"></i>`;
|
||||
const bolt_txt = is_charging ? '<i class="fa-solid fa-bolt"></i>' : '';
|
||||
return [`${bat_capacity}%`, icon_full, bolt_txt].join(' ');
|
||||
}
|
||||
|
||||
/**
|
||||
* Get a bound input handler function that can be assigned to device.oninputreport
|
||||
* @returns {Function} Bound input handler function
|
||||
*/
|
||||
getInputHandler() {
|
||||
return this.processControllerInput.bind(this);
|
||||
}
|
||||
}
|
||||
|
||||
// Function to initialize the controller manager with dependencies
|
||||
export function initControllerManager(dependencies = {}) {
|
||||
const self = new ControllerManager(dependencies);
|
||||
|
||||
// This disables the save button until something actually changes
|
||||
self.setHasChangesToWrite(false);
|
||||
return self;
|
||||
}
|
||||
148
js/controllers/base-controller.js
Normal file
148
js/controllers/base-controller.js
Normal file
@@ -0,0 +1,148 @@
|
||||
'use strict';
|
||||
|
||||
/**
|
||||
* Base Controller class that provides common functionality for all controller types
|
||||
*/
|
||||
class BaseController {
|
||||
constructor(device, uiDependencies = {}) {
|
||||
this.device = device;
|
||||
this.model = "undefined"; // to be set by subclasses
|
||||
this.finetuneMaxValue; // to be set by subclasses
|
||||
|
||||
// UI dependencies injected from core
|
||||
this.l = uiDependencies.l;
|
||||
}
|
||||
|
||||
getModel() {
|
||||
return this.model;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the underlying HID device
|
||||
* @returns {HIDDevice} The HID device
|
||||
*/
|
||||
getDevice() {
|
||||
return this.device;
|
||||
}
|
||||
|
||||
getInputConfig() {
|
||||
throw new Error('getInputConfig() must be implemented by subclass');
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the maximum value for finetune data
|
||||
* @returns {number} Maximum value for finetune adjustments
|
||||
*/
|
||||
getFinetuneMaxValue() {
|
||||
if(!this.finetuneMaxValue) throw new Error('getFinetuneMaxValue() must be implemented by subclass');
|
||||
return this.finetuneMaxValue;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set input report handler
|
||||
* @param {Function} handler Input report handler function
|
||||
*/
|
||||
setInputReportHandler(handler) {
|
||||
this.device.oninputreport = handler;
|
||||
}
|
||||
|
||||
/**
|
||||
* Allocate request buffer with proper size based on device feature reports
|
||||
* @param {number} id Report ID
|
||||
* @param {Array} data Data array to include in the request
|
||||
* @returns {Uint8Array} Allocated request buffer
|
||||
*/
|
||||
alloc_req(id, data = []) {
|
||||
const fr = this.device.collections[0].featureReports;
|
||||
const [report] = fr.find(e => e.reportId === id)?.items || [];
|
||||
const maxLen = report?.reportCount || data.length;
|
||||
|
||||
const len = Math.min(data.length, maxLen);
|
||||
const out = new Uint8Array(maxLen);
|
||||
out.set(data.slice(0, len));
|
||||
return out;
|
||||
}
|
||||
|
||||
/**
|
||||
* Send feature report to device
|
||||
* @param {number} reportId Report ID
|
||||
* @param {ArrayBuffer|Array} data Data to send (if Array, will be processed through allocReq)
|
||||
*/
|
||||
async sendFeatureReport(reportId, data) {
|
||||
// If data is an array, use allocReq to create proper buffer
|
||||
if (Array.isArray(data)) {
|
||||
data = this.alloc_req(reportId, data);
|
||||
}
|
||||
|
||||
try {
|
||||
return await this.device.sendFeatureReport(reportId, data);
|
||||
} catch (error) {
|
||||
// HID doesn't throw proper Errors with stack (stack is "name: message") so generate a new stack here
|
||||
throw new Error(error.stack);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Receive feature report from device
|
||||
* @param {number} reportId Report ID
|
||||
*/
|
||||
async receiveFeatureReport(reportId) {
|
||||
return await this.device.receiveFeatureReport(reportId);
|
||||
}
|
||||
|
||||
/**
|
||||
* Close the HID device connection
|
||||
*/
|
||||
async close() {
|
||||
if (this.device?.opened) {
|
||||
await this.device.close();
|
||||
}
|
||||
}
|
||||
|
||||
// Abstract methods that must be implemented by subclasses
|
||||
async getInfo() {
|
||||
throw new Error('getInfo() must be implemented by subclass');
|
||||
}
|
||||
|
||||
async flash(progressCallback = null) {
|
||||
throw new Error('flash() must be implemented by subclass');
|
||||
}
|
||||
|
||||
async reset() {
|
||||
throw new Error('reset() must be implemented by subclass');
|
||||
}
|
||||
|
||||
async nvsLock() {
|
||||
throw new Error('nvsLock() must be implemented by subclass');
|
||||
}
|
||||
|
||||
async nvsUnlock() {
|
||||
throw new Error('nvsUnlock() must be implemented by subclass');
|
||||
}
|
||||
|
||||
async calibrateSticksBegin() {
|
||||
throw new Error('calibrateSticksBegin() must be implemented by subclass');
|
||||
}
|
||||
|
||||
async calibrateSticksEnd() {
|
||||
throw new Error('calibrateSticksEnd() must be implemented by subclass');
|
||||
}
|
||||
|
||||
async calibrateSticksSample() {
|
||||
throw new Error('calibrateSticksSample() must be implemented by subclass');
|
||||
}
|
||||
|
||||
async calibrateRangeBegin() {
|
||||
throw new Error('calibrateRangeBegin() must be implemented by subclass');
|
||||
}
|
||||
|
||||
async calibrateRangeEnd() {
|
||||
throw new Error('calibrateRangeEnd() must be implemented by subclass');
|
||||
}
|
||||
|
||||
parseBatteryStatus(data) {
|
||||
throw new Error('parseBatteryStatus() must be implemented by subclass');
|
||||
}
|
||||
}
|
||||
|
||||
export default BaseController;
|
||||
101
js/controllers/controller-factory.js
Normal file
101
js/controllers/controller-factory.js
Normal file
@@ -0,0 +1,101 @@
|
||||
'use strict';
|
||||
|
||||
import DS4Controller from './ds4-controller.js';
|
||||
import DS5Controller from './ds5-controller.js';
|
||||
import DS5EdgeController from './ds5-edge-controller.js';
|
||||
import { dec2hex } from '../utils.js';
|
||||
|
||||
/**
|
||||
* Controller Factory - Creates the appropriate controller instance based on device type
|
||||
*/
|
||||
class ControllerFactory {
|
||||
static getSupportedModels() {
|
||||
const ds4v1 = { vendorId: 0x054c, productId: 0x05c4 };
|
||||
const ds4v2 = { vendorId: 0x054c, productId: 0x09cc };
|
||||
const ds5 = { vendorId: 0x054c, productId: 0x0ce6 };
|
||||
const ds5edge = { vendorId: 0x054c, productId: 0x0df2 };
|
||||
return [ds4v1, ds4v2, ds5, ds5edge];
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Create a controller instance based on the HID device product ID
|
||||
* @param {HIDDevice} device The HID device
|
||||
* @param {Object} uiDependencies Optional UI dependencies (l function, etc.)
|
||||
* @returns {BaseController} The appropriate controller instance
|
||||
*/
|
||||
static createControllerInstance(device, uiDependencies = {}) {
|
||||
switch (device.productId) {
|
||||
case 0x05c4: // DS4 v1
|
||||
case 0x09cc: // DS4 v2
|
||||
return new DS4Controller(device, uiDependencies);
|
||||
|
||||
case 0x0ce6: // DS5
|
||||
return new DS5Controller(device, uiDependencies);
|
||||
|
||||
case 0x0df2: // DS5 Edge
|
||||
return new DS5EdgeController(device, uiDependencies);
|
||||
|
||||
default:
|
||||
throw new Error(`Unsupported device: ${dec2hex(device.vendorId)}:${dec2hex(device.productId)}`);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Get device name based on product ID
|
||||
* @param {number} productId Product ID
|
||||
* @returns {string} Device name
|
||||
*/
|
||||
static getDeviceName(productId) {
|
||||
switch (productId) {
|
||||
case 0x05c4:
|
||||
return "Sony DualShock 4 V1";
|
||||
case 0x09cc:
|
||||
return "Sony DualShock 4 V2";
|
||||
case 0x0ce6:
|
||||
return "Sony DualSense";
|
||||
case 0x0df2:
|
||||
return "Sony DualSense Edge";
|
||||
default:
|
||||
return "Unknown Device";
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Get UI configuration based on product ID
|
||||
* @param {number} productId Product ID
|
||||
* @returns {Object} UI configuration
|
||||
*/
|
||||
static getUIConfig(productId) {
|
||||
switch (productId) {
|
||||
case 0x05c4: // DS4 v1
|
||||
case 0x09cc: // DS4 v2
|
||||
return {
|
||||
showInfo: false,
|
||||
showFinetune: false,
|
||||
showMute: false,
|
||||
showInfoTab: false
|
||||
};
|
||||
|
||||
case 0x0ce6: // DS5
|
||||
case 0x0df2: // DS5 Edge
|
||||
return {
|
||||
showInfo: true,
|
||||
showFinetune: true,
|
||||
showMute: true,
|
||||
showInfoTab: true
|
||||
};
|
||||
|
||||
default:
|
||||
return {
|
||||
showInfo: false,
|
||||
showFinetune: false,
|
||||
showMute: false,
|
||||
showInfoTab: false
|
||||
};
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Export for use in other modules
|
||||
export default ControllerFactory;
|
||||
375
js/controllers/ds4-controller.js
Normal file
375
js/controllers/ds4-controller.js
Normal file
@@ -0,0 +1,375 @@
|
||||
'use strict';
|
||||
|
||||
import BaseController from './base-controller.js';
|
||||
import {
|
||||
sleep,
|
||||
dec2hex,
|
||||
dec2hex32,
|
||||
format_mac_from_view,
|
||||
lf,
|
||||
la
|
||||
} from '../utils.js';
|
||||
|
||||
const NOT_GENUINE_SONY_CONTROLLER_MSG = "Your device might not be a genuine Sony controller. If it is not a clone then please report this issue.";
|
||||
|
||||
// DS4 Button mapping configuration
|
||||
const DS4_BUTTON_MAP = [
|
||||
{ name: 'up', byte: 4, mask: 0x0 }, // Dpad handled separately
|
||||
{ name: 'right', byte: 4, mask: 0x1 },
|
||||
{ name: 'down', byte: 4, mask: 0x2 },
|
||||
{ name: 'left', byte: 4, mask: 0x3 },
|
||||
{ name: 'square', byte: 4, mask: 0x10, svg: 'Square' },
|
||||
{ name: 'cross', byte: 4, mask: 0x20, svg: 'Cross' },
|
||||
{ name: 'circle', byte: 4, mask: 0x40, svg: 'Circle' },
|
||||
{ name: 'triangle', byte: 4, mask: 0x80, svg: 'Triangle' },
|
||||
{ name: 'l1', byte: 5, mask: 0x01, svg: 'L1' },
|
||||
{ name: 'l2', byte: 5, mask: 0x04, svg: 'L2' }, // analog handled separately
|
||||
{ name: 'r1', byte: 5, mask: 0x02, svg: 'R1' },
|
||||
{ name: 'r2', byte: 5, mask: 0x08, svg: 'R2' }, // analog handled separately
|
||||
{ name: 'share', byte: 5, mask: 0x10, svg: 'Create' },
|
||||
{ name: 'options', byte: 5, mask: 0x20, svg: 'Options' },
|
||||
{ name: 'l3', byte: 5, mask: 0x40, svg: 'L3' },
|
||||
{ name: 'r3', byte: 5, mask: 0x80, svg: 'R3' },
|
||||
{ name: 'ps', byte: 6, mask: 0x01, svg: 'PS' },
|
||||
{ name: 'touchpad', byte: 6, mask: 0x02, svg: 'Trackpad' },
|
||||
// No mute button on DS4
|
||||
];
|
||||
|
||||
// DS4 Input processing configuration
|
||||
const DS4_INPUT_CONFIG = {
|
||||
buttonMap: DS4_BUTTON_MAP,
|
||||
dpadByte: 4,
|
||||
l2AnalogByte: 7,
|
||||
r2AnalogByte: 8,
|
||||
touchpadOffset: 34,
|
||||
};
|
||||
|
||||
/**
|
||||
* DualShock 4 Controller implementation
|
||||
*/
|
||||
class DS4Controller extends BaseController {
|
||||
constructor(device, uiDependencies = {}) {
|
||||
super(device, uiDependencies);
|
||||
this.model = "DS4";
|
||||
}
|
||||
|
||||
getInputConfig() {
|
||||
return DS4_INPUT_CONFIG;
|
||||
}
|
||||
|
||||
async getInfo() {
|
||||
const { l } = this;
|
||||
|
||||
// Device-only: collect info and return a common structure; do not touch the DOM
|
||||
try {
|
||||
let deviceTypeText = l("unknown");
|
||||
let is_clone = false;
|
||||
|
||||
const view = lf("ds4_info", await this.receiveFeatureReport(0xa3));
|
||||
|
||||
const cmd = view.getUint8(0, true);
|
||||
|
||||
if(cmd != 0xa3 || view.buffer.byteLength < 49) {
|
||||
if(view.buffer.byteLength != 49) {
|
||||
deviceTypeText = l("clone");
|
||||
is_clone = true;
|
||||
}
|
||||
}
|
||||
|
||||
const k1 = new TextDecoder().decode(view.buffer.slice(1, 0x10)).replace(/\0/g, '');
|
||||
const k2 = new TextDecoder().decode(view.buffer.slice(0x10, 0x20)).replace(/\0/g, '');
|
||||
|
||||
const hw_ver_major = view.getUint16(0x21, true);
|
||||
const hw_ver_minor = view.getUint16(0x23, true);
|
||||
const sw_ver_major = view.getUint32(0x25, true);
|
||||
const sw_ver_minor = view.getUint16(0x25+4, true);
|
||||
try {
|
||||
if(!is_clone) {
|
||||
// If this feature report succeeds, it's an original device
|
||||
await this.receiveFeatureReport(0x81);
|
||||
deviceTypeText = l("original");
|
||||
}
|
||||
} catch(e) {
|
||||
la("clone");
|
||||
is_clone = true;
|
||||
deviceTypeText = l("clone");
|
||||
}
|
||||
|
||||
const infoItems = [
|
||||
{ key: l("Build Date"), value: `${k1} ${k2}`, cat: "fw" },
|
||||
{ key: l("HW Version"), value: `${dec2hex(hw_ver_major)}:${dec2hex(hw_ver_minor)}`, cat: "hw" },
|
||||
{ key: l("SW Version"), value: `${dec2hex32(sw_ver_major)}:${dec2hex(sw_ver_minor)}`, cat: "fw" },
|
||||
{ key: l("Device Type"), value: deviceTypeText, cat: "hw", severity: is_clone ? 'danger' : undefined },
|
||||
];
|
||||
|
||||
if(!is_clone) {
|
||||
// Add Board Model (UI will append the info icon)
|
||||
infoItems.push({ key: l("Board Model"), value: this.hwToBoardModel(hw_ver_minor), cat: "hw", addInfoIcon: 'board' });
|
||||
|
||||
const bd_addr = await this.getBdAddr();
|
||||
infoItems.push({ key: l("Bluetooth Address"), value: bd_addr, cat: "hw" });
|
||||
}
|
||||
|
||||
const nv = await this.queryNvStatus();
|
||||
const rare = this.isRare(hw_ver_minor);
|
||||
const disable_bits = is_clone ? 1 : 0; // 1: clone
|
||||
|
||||
return { ok: true, infoItems, nv, disable_bits, rare };
|
||||
} catch(error) {
|
||||
// Return error but do not touch DOM
|
||||
return { ok: false, error, disable_bits: 1 };
|
||||
}
|
||||
}
|
||||
|
||||
async flash(progressCallback = null) {
|
||||
la("ds4_flash");
|
||||
try {
|
||||
await this.nvsUnlock();
|
||||
const lockRes = await this.nvsLock();
|
||||
if(!lockRes.ok) throw (lockRes.error || new Error("NVS lock failed"));
|
||||
|
||||
return { success: true, message: this.l("Changes saved successfully") };
|
||||
} catch(error) {
|
||||
throw new Error(this.l("Error while saving changes"), { cause: error });
|
||||
}
|
||||
}
|
||||
|
||||
async reset() {
|
||||
la("ds4_reset");
|
||||
try {
|
||||
await this.sendFeatureReport(0xa0, [4,1,0]);
|
||||
} catch(error) {
|
||||
}
|
||||
}
|
||||
|
||||
async nvsLock() {
|
||||
la("ds4_nvlock");
|
||||
try {
|
||||
await this.sendFeatureReport(0xa0, [10,1,0]);
|
||||
return { ok: true };
|
||||
} catch(error) {
|
||||
return { ok: false, error };
|
||||
}
|
||||
}
|
||||
|
||||
async nvsUnlock() {
|
||||
la("ds4_nvunlock");
|
||||
try {
|
||||
await this.sendFeatureReport(0xa0, [10,2,0x3e,0x71,0x7f,0x89]);
|
||||
return { ok: true };
|
||||
} catch(error) {
|
||||
return { ok: false, error };
|
||||
}
|
||||
}
|
||||
|
||||
async getBdAddr() {
|
||||
const view = lf("ds4_getbdaddr", await this.receiveFeatureReport(0x12));
|
||||
return format_mac_from_view(view, 1);
|
||||
}
|
||||
|
||||
async calibrateRangeBegin() {
|
||||
la("ds4_calibrate_range_begin");
|
||||
try {
|
||||
// Begin
|
||||
await this.sendFeatureReport(0x90, [1,1,2]);
|
||||
await sleep(200);
|
||||
|
||||
// Assert
|
||||
const data = await this.receiveFeatureReport(0x91);
|
||||
const data2 = await this.receiveFeatureReport(0x92);
|
||||
const [d1, d2] = [data, data2].map(v => v.buffer.byteLength == 4 ? v.getUint32(0, false) : undefined);
|
||||
if(d1 != 0x91010201 || d2 != 0x920102ff) {
|
||||
la("ds4_calibrate_range_begin_failed", {"d1": d1, "d2": d2});
|
||||
return {
|
||||
ok: false,
|
||||
error: new Error(this.l(NOT_GENUINE_SONY_CONTROLLER_MSG)),
|
||||
code: 1, d1, d2
|
||||
};
|
||||
}
|
||||
return { ok: true };
|
||||
} catch(error) {
|
||||
la("ds4_calibrate_range_begin_failed", {"r": error});
|
||||
return { ok: false, error };
|
||||
}
|
||||
}
|
||||
|
||||
async calibrateRangeEnd() {
|
||||
la("ds4_calibrate_range_end");
|
||||
try {
|
||||
// Write
|
||||
await this.sendFeatureReport(0x90, [2,1,2]);
|
||||
await sleep(200);
|
||||
|
||||
const data = await this.receiveFeatureReport(0x91);
|
||||
const data2 = await this.receiveFeatureReport(0x92);
|
||||
const [d1, d2] = [data, data2].map(v => v.getUint32(0, false));
|
||||
if(d1 != 0x91010202 || d2 != 0x92010201) {
|
||||
la("ds4_calibrate_range_end_failed", {"d1": d1, "d2": d2});
|
||||
return { ok: false, code: 3, d1, d2 };
|
||||
}
|
||||
|
||||
return { ok: true };
|
||||
} catch(error) {
|
||||
la("ds4_calibrate_range_end_failed", {"r": error});
|
||||
return { ok: false, error };
|
||||
}
|
||||
}
|
||||
|
||||
async calibrateSticksBegin() {
|
||||
la("ds4_calibrate_sticks_begin");
|
||||
try {
|
||||
// Begin
|
||||
await this.sendFeatureReport(0x90, [1,1,1]);
|
||||
await sleep(200);
|
||||
|
||||
// Assert
|
||||
const data = await this.receiveFeatureReport(0x91);
|
||||
const data2 = await this.receiveFeatureReport(0x92);
|
||||
const [d1, d2] = [data, data2].map(v => v.buffer.byteLength == 4 ? v.getUint32(0, false) : undefined);
|
||||
if(d1 != 0x91010101 || d2 != 0x920101ff) {
|
||||
la("ds4_calibrate_sticks_begin_failed", {"d1": d1, "d2": d2});
|
||||
return {
|
||||
ok: false,
|
||||
error: new Error(this.l(NOT_GENUINE_SONY_CONTROLLER_MSG)),
|
||||
code: 1, d1, d2,
|
||||
};
|
||||
}
|
||||
|
||||
return { ok: true };
|
||||
} catch(error) {
|
||||
la("ds4_calibrate_sticks_begin_failed", {"r": error});
|
||||
return { ok: false, error };
|
||||
}
|
||||
}
|
||||
|
||||
async calibrateSticksSample() {
|
||||
la("ds4_calibrate_sticks_sample");
|
||||
try {
|
||||
// Sample
|
||||
await this.sendFeatureReport(0x90, [3,1,1]);
|
||||
await sleep(200);
|
||||
|
||||
// Assert
|
||||
const data = await this.receiveFeatureReport(0x91);
|
||||
const data2 = await this.receiveFeatureReport(0x92);
|
||||
if(data.getUint32(0, false) != 0x91010101 || data2.getUint32(0, false) != 0x920101ff) {
|
||||
const [d1, d2] = [data, data2].map(v => dec2hex32(v.getUint32(0, false)));
|
||||
la("ds4_calibrate_sticks_sample_failed", {"d1": d1, "d2": d2});
|
||||
return { ok: false, code: 2, d1, d2 };
|
||||
}
|
||||
return { ok: true };
|
||||
} catch(error) {
|
||||
return { ok: false, error };
|
||||
}
|
||||
}
|
||||
|
||||
async calibrateSticksEnd() {
|
||||
la("ds4_calibrate_sticks_end");
|
||||
try {
|
||||
// Write
|
||||
await this.sendFeatureReport(0x90, [2,1,1]);
|
||||
await sleep(200);
|
||||
|
||||
const data = await this.receiveFeatureReport(0x91);
|
||||
const data2 = await this.receiveFeatureReport(0x92);
|
||||
if(data.getUint32(0, false) != 0x91010102 || data2.getUint32(0, false) != 0x92010101) {
|
||||
const [d1, d2] = [data, data2].map(v => dec2hex32(v.getUint32(0, false)));
|
||||
la("ds4_calibrate_sticks_end_failed", {"d1": d1, "d2": d2});
|
||||
return { ok: false, code: 3, d1, d2 };
|
||||
}
|
||||
|
||||
return { ok: true };
|
||||
} catch(error) {
|
||||
la("ds4_calibrate_sticks_end_failed", {"r": error});
|
||||
return { ok: false, error };
|
||||
}
|
||||
}
|
||||
|
||||
async queryNvStatus() {
|
||||
try {
|
||||
await this.sendFeatureReport(0x08, [0xff,0, 12]);
|
||||
const data = lf("ds4_nvstatus", await this.receiveFeatureReport(0x11));
|
||||
const ret = data.getUint8(1, false);
|
||||
const res = { device: 'ds4', code: ret }
|
||||
switch(ret) {
|
||||
case 1:
|
||||
return { ...res, status: 'locked', locked: true, mode: 'temporary' };
|
||||
case 0:
|
||||
return { ...res, status: 'unlocked', locked: false, mode: 'permanent' };
|
||||
default:
|
||||
return { ...res, status: 'unknown', locked: null };
|
||||
}
|
||||
} catch (error) {
|
||||
return { device: 'ds4', status: 'error', locked: null, code: 2, error };
|
||||
}
|
||||
}
|
||||
|
||||
hwToBoardModel(hw_ver) {
|
||||
const a = hw_ver >> 8;
|
||||
if(a == 0x31) {
|
||||
return "JDM-001";
|
||||
} else if(a == 0x43) {
|
||||
return "JDM-011";
|
||||
} else if(a == 0x54) {
|
||||
return "JDM-030";
|
||||
} else if(a >= 0x64 && a <= 0x74) {
|
||||
return "JDM-040";
|
||||
} else if((a > 0x80 && a < 0x84) || a == 0x93) {
|
||||
return "JDM-020";
|
||||
} else if(a == 0xa4 || a == 0x90 || a == 0xa0) {
|
||||
return "JDM-050";
|
||||
} else if(a == 0xb0) {
|
||||
return "JDM-055 (Scuf?)";
|
||||
} else if(a == 0xb4) {
|
||||
return "JDM-055";
|
||||
} else {
|
||||
if(this.isRare(hw_ver))
|
||||
return "WOW!";
|
||||
return this.l("Unknown");
|
||||
}
|
||||
}
|
||||
|
||||
isRare(hw_ver) {
|
||||
const a = hw_ver >> 8;
|
||||
const b = a >> 4;
|
||||
return ((b == 7 && a > 0x74) || (b == 9 && a != 0x93 && a != 0x90));
|
||||
}
|
||||
|
||||
/**
|
||||
* Parse DS4 battery status from input data
|
||||
*/
|
||||
parseBatteryStatus(data) {
|
||||
const bat = data.getUint8(29); // DS4 battery byte is at position 29
|
||||
|
||||
// DS4: bat_data = low 4 bits, bat_status = bit 4
|
||||
const bat_data = bat & 0x0f;
|
||||
const bat_status = (bat >> 4) & 1;
|
||||
const cable_connected = bat_status === 1;
|
||||
|
||||
let bat_capacity = 0;
|
||||
let is_charging = false;
|
||||
let is_error = false;
|
||||
|
||||
if (cable_connected) {
|
||||
if (bat_data < 10) {
|
||||
bat_capacity = Math.min(bat_data * 10 + 5, 100);
|
||||
is_charging = true;
|
||||
} else if (bat_data === 10) {
|
||||
bat_capacity = 100;
|
||||
is_charging = true;
|
||||
} else if (bat_data === 11) {
|
||||
bat_capacity = 100; // Fully charged
|
||||
} else {
|
||||
bat_capacity = 0;
|
||||
is_error = true;
|
||||
}
|
||||
} else {
|
||||
// On battery power
|
||||
bat_capacity = bat_data < 10 ? bat_data * 10 + 5 : 100;
|
||||
}
|
||||
|
||||
return { bat_capacity, cable_connected, is_charging, is_error };
|
||||
}
|
||||
}
|
||||
|
||||
export default DS4Controller;
|
||||
433
js/controllers/ds5-controller.js
Normal file
433
js/controllers/ds5-controller.js
Normal file
@@ -0,0 +1,433 @@
|
||||
'use strict';
|
||||
|
||||
import BaseController from './base-controller.js';
|
||||
import {
|
||||
sleep,
|
||||
buf2hex,
|
||||
dec2hex,
|
||||
dec2hex32,
|
||||
dec2hex8,
|
||||
format_mac_from_view,
|
||||
reverse_str,
|
||||
la,
|
||||
lf
|
||||
} from '../utils.js';
|
||||
|
||||
// DS5 Button mapping configuration
|
||||
const DS5_BUTTON_MAP = [
|
||||
{ name: 'up', byte: 7, mask: 0x0 }, // Dpad handled separately
|
||||
{ name: 'right', byte: 7, mask: 0x1 },
|
||||
{ name: 'down', byte: 7, mask: 0x2 },
|
||||
{ name: 'left', byte: 7, mask: 0x3 },
|
||||
{ name: 'square', byte: 7, mask: 0x10, svg: 'Square' },
|
||||
{ name: 'cross', byte: 7, mask: 0x20, svg: 'Cross' },
|
||||
{ name: 'circle', byte: 7, mask: 0x40, svg: 'Circle' },
|
||||
{ name: 'triangle', byte: 7, mask: 0x80, svg: 'Triangle' },
|
||||
{ name: 'l1', byte: 8, mask: 0x01, svg: 'L1' },
|
||||
{ name: 'l2', byte: 4, mask: 0xff }, // analog handled separately
|
||||
{ name: 'r1', byte: 8, mask: 0x02, svg: 'R1' },
|
||||
{ name: 'r2', byte: 5, mask: 0xff }, // analog handled separately
|
||||
{ name: 'create', byte: 8, mask: 0x10, svg: 'Create' },
|
||||
{ name: 'options', byte: 8, mask: 0x20, svg: 'Options' },
|
||||
{ name: 'l3', byte: 8, mask: 0x40, svg: 'L3' },
|
||||
{ name: 'r3', byte: 8, mask: 0x80, svg: 'R3' },
|
||||
{ name: 'ps', byte: 9, mask: 0x01, svg: 'PS' },
|
||||
{ name: 'touchpad', byte: 9, mask: 0x02, svg: 'Trackpad' },
|
||||
{ name: 'mute', byte: 9, mask: 0x04, svg: 'Mute' },
|
||||
];
|
||||
|
||||
// DS5 Input processing configuration
|
||||
const DS5_INPUT_CONFIG = {
|
||||
buttonMap: DS5_BUTTON_MAP,
|
||||
dpadByte: 7,
|
||||
l2AnalogByte: 4,
|
||||
r2AnalogByte: 5,
|
||||
touchpadOffset: 32,
|
||||
};
|
||||
|
||||
function ds5_color(x) {
|
||||
const colorMap = {
|
||||
'00': 'White',
|
||||
'01': 'Midnight Black',
|
||||
'02': 'Cosmic Red',
|
||||
'03': 'Nova Pink',
|
||||
'04': 'Galactic Purple',
|
||||
'05': 'Starlight Blue',
|
||||
'06': 'Grey Camouflage',
|
||||
'07': 'Volcanic Red',
|
||||
'08': 'Sterling Silver',
|
||||
'09': 'Cobalt Blue',
|
||||
'10': 'Chroma Teal',
|
||||
'11': 'Chroma Indigo',
|
||||
'12': 'Chroma Pearl',
|
||||
'30': '30th Anniversary',
|
||||
'Z1': 'God of War Ragnarok',
|
||||
'Z2': 'Spider-Man 2',
|
||||
'Z3': 'Astro Bot',
|
||||
'Z4': 'Fortnite',
|
||||
'Z6': 'The Last of Us',
|
||||
};
|
||||
|
||||
const colorCode = x.slice(4, 6);
|
||||
const colorName = colorMap[colorCode] || 'Unknown';
|
||||
return colorName;
|
||||
}
|
||||
|
||||
/**
|
||||
* DualSense (DS5) Controller implementation
|
||||
*/
|
||||
class DS5Controller extends BaseController {
|
||||
constructor(device, uiDependencies = {}) {
|
||||
super(device, uiDependencies);
|
||||
this.model = "DS5";
|
||||
this.finetuneMaxValue = 65535; // 16-bit max value for DS5
|
||||
}
|
||||
|
||||
getInputConfig() {
|
||||
return DS5_INPUT_CONFIG;
|
||||
}
|
||||
|
||||
async getInfo() {
|
||||
return this._getInfo(false);
|
||||
}
|
||||
|
||||
async _getInfo(is_edge) {
|
||||
const { l } = this;
|
||||
// Device-only: collect info and return a common structure; do not touch the DOM
|
||||
try {
|
||||
console.log("Fetching DS5 info...");
|
||||
const view = lf("ds5_info", await this.receiveFeatureReport(0x20));
|
||||
console.log("Got DS5 info report:", buf2hex(view.buffer));
|
||||
const cmd = view.getUint8(0, true);
|
||||
if(cmd != 0x20 || view.buffer.byteLength != 64)
|
||||
return { ok: false, error: new Error("Invalid response for ds5_info") };
|
||||
|
||||
const build_date = new TextDecoder().decode(view.buffer.slice(1, 1+11));
|
||||
const build_time = new TextDecoder().decode(view.buffer.slice(12, 20));
|
||||
|
||||
const fwtype = view.getUint16(20, true);
|
||||
const swseries = view.getUint16(22, true);
|
||||
const hwinfo = view.getUint32(24, true);
|
||||
const fwversion = view.getUint32(28, true);
|
||||
|
||||
const updversion = view.getUint16(44, true);
|
||||
const unk = view.getUint8(46, true);
|
||||
|
||||
const fwversion1 = view.getUint32(48, true);
|
||||
const fwversion2 = view.getUint32(52, true);
|
||||
const fwversion3 = view.getUint32(56, true);
|
||||
|
||||
const serial_number = await this.getSystemInfo(1, 19, 17);
|
||||
const color = ds5_color(serial_number);
|
||||
const infoItems = [
|
||||
{ key: l("Serial Number"), value: serial_number, cat: "hw" },
|
||||
{ key: l("MCU Unique ID"), value: await this.getSystemInfo(1, 9, 9, false), cat: "hw", isExtra: true },
|
||||
{ key: l("PCBA ID"), value: reverse_str(await this.getSystemInfo(1, 17, 14)), cat: "hw", isExtra: true },
|
||||
{ key: l("Battery Barcode"), value: await this.getSystemInfo(1, 24, 23), cat: "hw", isExtra: true },
|
||||
{ key: l("VCM Left Barcode"), value: await this.getSystemInfo(1, 26, 16), cat: "hw", isExtra: true },
|
||||
{ key: l("VCM Right Barcode"), value: await this.getSystemInfo(1, 28, 16), cat: "hw", isExtra: true },
|
||||
|
||||
{ key: l("Color"), value: l(color), cat: "hw", addInfoIcon: 'color' },
|
||||
|
||||
...(is_edge ? [] : [{ key: l("Board Model"), value: this.hwToBoardModel(hwinfo), cat: "hw", addInfoIcon: 'board' }]),
|
||||
|
||||
{ key: l("FW Build Date"), value: build_date + " " + build_time, cat: "fw" },
|
||||
{ key: l("FW Type"), value: "0x" + dec2hex(fwtype), cat: "fw", isExtra: true },
|
||||
{ key: l("FW Series"), value: "0x" + dec2hex(swseries), cat: "fw", isExtra: true },
|
||||
{ key: l("HW Model"), value: "0x" + dec2hex32(hwinfo), cat: "hw", isExtra: true },
|
||||
{ key: l("FW Version"), value: "0x" + dec2hex32(fwversion), cat: "fw" },
|
||||
{ key: l("FW Update"), value: "0x" + dec2hex(updversion), cat: "fw" },
|
||||
{ key: l("FW Update Info"), value: "0x" + dec2hex8(unk), cat: "fw", isExtra: true },
|
||||
{ key: l("SBL FW Version"), value: "0x" + dec2hex32(fwversion1), cat: "fw", isExtra: true },
|
||||
{ key: l("Venom FW Version"), value: "0x" + dec2hex32(fwversion2), cat: "fw", isExtra: true },
|
||||
{ key: l("Spider FW Version"), value: "0x" + dec2hex32(fwversion3), cat: "fw", isExtra: true },
|
||||
|
||||
{ key: l("Touchpad ID"), value: await this.getSystemInfo(5, 2, 8, false), cat: "hw", isExtra: true },
|
||||
{ key: l("Touchpad FW Version"), value: await this.getSystemInfo(5, 4, 8, false), cat: "fw", isExtra: true },
|
||||
];
|
||||
|
||||
const old_controller = build_date.search(/ 2020| 2021/);
|
||||
let disable_bits = 0;
|
||||
if(old_controller != -1) {
|
||||
la("ds5_info_error", {"r": "old"})
|
||||
disable_bits |= 2; // 2: outdated firmware
|
||||
}
|
||||
|
||||
const nv = await this.queryNvStatus();
|
||||
const bd_addr = await this.getBdAddr();
|
||||
infoItems.push({ key: l("Bluetooth Address"), value: bd_addr, cat: "hw" });
|
||||
|
||||
const pending_reboot = (nv?.status === 'pending_reboot');
|
||||
|
||||
return { ok: true, infoItems, nv, disable_bits, pending_reboot };
|
||||
} catch(error) {
|
||||
la("ds5_info_error", {"r": error})
|
||||
return { ok: false, error, disable_bits: 1 };
|
||||
}
|
||||
}
|
||||
|
||||
async flash(progressCallback = null) {
|
||||
la("ds5_flash");
|
||||
try {
|
||||
await this.nvsUnlock();
|
||||
const lockRes = await this.nvsLock();
|
||||
if(!lockRes.ok) throw (lockRes.error || new Error("NVS lock failed"));
|
||||
|
||||
return { success: true, message: this.l("Changes saved successfully") };
|
||||
} catch(error) {
|
||||
throw new Error(this.l("Error while saving changes"), { cause: error });
|
||||
}
|
||||
}
|
||||
|
||||
async reset() {
|
||||
la("ds5_reset");
|
||||
try {
|
||||
await this.sendFeatureReport(0x80, [1,1]);
|
||||
} catch(error) {
|
||||
}
|
||||
}
|
||||
|
||||
async nvsLock() {
|
||||
la("ds5_nvlock");
|
||||
try {
|
||||
await this.sendFeatureReport(0x80, [3,1]);
|
||||
await this.receiveFeatureReport(0x81);
|
||||
return { ok: true };
|
||||
} catch(error) {
|
||||
return { ok: false, error };
|
||||
}
|
||||
}
|
||||
|
||||
async nvsUnlock() {
|
||||
la("ds5_nvunlock");
|
||||
try {
|
||||
await this.sendFeatureReport(0x80, [3,2, 101, 50, 64, 12]);
|
||||
const data = await this.receiveFeatureReport(0x81);
|
||||
} catch(error) {
|
||||
await sleep(500);
|
||||
throw new Error(this.l("NVS Unlock failed"), { cause: error });
|
||||
}
|
||||
}
|
||||
|
||||
async getBdAddr() {
|
||||
await this.sendFeatureReport(0x80, [9,2]);
|
||||
const data = lf("ds5_getbdaddr", await this.receiveFeatureReport(0x81));
|
||||
return format_mac_from_view(data, 4);
|
||||
}
|
||||
|
||||
async getSystemInfo(base, num, length, decode = true) {
|
||||
await this.sendFeatureReport(128, [base,num])
|
||||
const pcba_id = lf("ds5_pcba_id", await this.receiveFeatureReport(129));
|
||||
if(pcba_id.getUint8(1) != base || pcba_id.getUint8(2) != num || pcba_id.getUint8(3) != 2) {
|
||||
return this.l("error");
|
||||
}
|
||||
if(decode)
|
||||
return new TextDecoder().decode(pcba_id.buffer.slice(4, 4+length));
|
||||
|
||||
return buf2hex(pcba_id.buffer.slice(4, 4+length));
|
||||
}
|
||||
|
||||
async calibrateSticksBegin() {
|
||||
la("ds5_calibrate_sticks_begin");
|
||||
try {
|
||||
// Begin
|
||||
await this.sendFeatureReport(0x82, [1,1,1]);
|
||||
|
||||
// Assert
|
||||
const data = await this.receiveFeatureReport(0x83);
|
||||
if(data.getUint32(0, false) != 0x83010101) {
|
||||
const d1 = dec2hex32(data.getUint32(0, false));
|
||||
la("ds5_calibrate_sticks_begin_failed", {"d1": d1});
|
||||
throw new Error(`Stick center calibration begin failed: ${d1}`);
|
||||
}
|
||||
return { ok: true };
|
||||
} catch(error) {
|
||||
la("ds5_calibrate_sticks_begin_failed", {"r": e});
|
||||
return { ok: false, error };
|
||||
}
|
||||
}
|
||||
|
||||
async calibrateSticksSample() {
|
||||
la("ds5_calibrate_sticks_sample");
|
||||
try {
|
||||
// Sample
|
||||
await this.sendFeatureReport(0x82, [3,1,1]);
|
||||
|
||||
// Assert
|
||||
const data = await this.receiveFeatureReport(0x83);
|
||||
if(data.getUint32(0, false) != 0x83010101) {
|
||||
const d1 = dec2hex32(data.getUint32(0, false));
|
||||
la("ds5_calibrate_sticks_sample_failed", {"d1": d1});
|
||||
throw new Error(`Stick center calibration sample failed: ${d1}`);
|
||||
}
|
||||
return { ok: true };
|
||||
} catch(error) {
|
||||
la("ds5_calibrate_sticks_sample_failed", {"r": e});
|
||||
return { ok: false, error };
|
||||
}
|
||||
}
|
||||
|
||||
async calibrateSticksEnd() {
|
||||
la("ds5_calibrate_sticks_end");
|
||||
try {
|
||||
// Write
|
||||
await this.sendFeatureReport(0x82, [2,1,1]);
|
||||
|
||||
const data = await this.receiveFeatureReport(0x83);
|
||||
|
||||
if(data.getUint32(0, false) != 0x83010102) {
|
||||
const d1 = dec2hex32(data.getUint32(0, false));
|
||||
la("ds5_calibrate_sticks_failed", {"s": 3, "d1": d1});
|
||||
throw new Error(`Stick center calibration end failed: ${d1}`);
|
||||
}
|
||||
|
||||
return { ok: true };
|
||||
} catch(error) {
|
||||
la("ds5_calibrate_sticks_end_failed", {"r": e});
|
||||
return { ok: false, error };
|
||||
}
|
||||
}
|
||||
|
||||
async calibrateRangeBegin() {
|
||||
la("ds5_calibrate_range_begin");
|
||||
try {
|
||||
// Begin
|
||||
await this.sendFeatureReport(0x82, [1,1,2]);
|
||||
|
||||
// Assert
|
||||
const data = await this.receiveFeatureReport(0x83);
|
||||
if(data.getUint32(0, false) != 0x83010201) {
|
||||
const d1 = dec2hex32(data.getUint32(0, false));
|
||||
la("ds5_calibrate_range_begin_failed", {"d1": d1});
|
||||
throw new Error(`Stick range calibration begin failed: ${d1}`);
|
||||
}
|
||||
return { ok: true };
|
||||
} catch(error) {
|
||||
la("ds5_calibrate_range_begin_failed", {"r": e});
|
||||
return { ok: false, error };
|
||||
}
|
||||
}
|
||||
|
||||
async calibrateRangeEnd() {
|
||||
la("ds5_calibrate_range_end");
|
||||
try {
|
||||
// Write
|
||||
await this.sendFeatureReport(0x82, [2,1,2]);
|
||||
|
||||
// Assert
|
||||
const data = await this.receiveFeatureReport(0x83);
|
||||
|
||||
if(data.getUint32(0, false) != 0x83010202) {
|
||||
const d1 = dec2hex32(data.getUint32(0, false));
|
||||
la("ds5_calibrate_range_end_failed", {"d1": d1});
|
||||
throw new Error(`Stick range calibration end failed: ${d1}`);
|
||||
}
|
||||
|
||||
return { ok: true };
|
||||
} catch(error) {
|
||||
la("ds5_calibrate_range_end_failed", {"r": e});
|
||||
return { ok: false, error };
|
||||
}
|
||||
}
|
||||
|
||||
async queryNvStatus() {
|
||||
try {
|
||||
await this.sendFeatureReport(0x80, [3,3]);
|
||||
const data = lf("ds5_nvstatus", await this.receiveFeatureReport(0x81));
|
||||
const ret = data.getUint32(1, false);
|
||||
if (ret === 0x15010100) {
|
||||
return { device: 'ds5', status: 'pending_reboot', locked: null, code: 4, raw: ret };
|
||||
}
|
||||
if (ret === 0x03030201) {
|
||||
return { device: 'ds5', status: 'locked', locked: true, mode: 'temporary', code: 1, raw: ret };
|
||||
}
|
||||
if (ret === 0x03030200) {
|
||||
return { device: 'ds5', status: 'unlocked', locked: false, mode: 'permanent', code: 0, raw: ret };
|
||||
}
|
||||
if (ret === 1 || ret === 2) {
|
||||
return { device: 'ds5', status: 'unknown', locked: null, code: 2, raw: ret };
|
||||
}
|
||||
return { device: 'ds5', status: 'unknown', locked: null, code: ret, raw: ret };
|
||||
} catch (e) {
|
||||
return { device: 'ds5', status: 'error', locked: null, code: 2, error: e };
|
||||
}
|
||||
}
|
||||
|
||||
hwToBoardModel(hw_ver) {
|
||||
const a = (hw_ver >> 8) & 0xff;
|
||||
if(a == 0x03) {
|
||||
return "BDM-010";
|
||||
} else if(a == 0x04) {
|
||||
return "BDM-020";
|
||||
} else if(a == 0x05) {
|
||||
return "BDM-030";
|
||||
} else if(a == 0x06) {
|
||||
return "BDM-040";
|
||||
} else if(a == 0x07 || a == 0x08) {
|
||||
return "BDM-050";
|
||||
} else {
|
||||
return this.l("Unknown");
|
||||
}
|
||||
}
|
||||
|
||||
async getInMemoryModuleData() {
|
||||
// DualSense
|
||||
await this.sendFeatureReport(0x80, [12, 2]);
|
||||
await sleep(100);
|
||||
const data = await this.receiveFeatureReport(0x81);
|
||||
const cmd = data.getUint8(0, true);
|
||||
const [p1, p2, p3] = [1, 2, 3].map(i => data.getUint8(i, true));
|
||||
|
||||
if(cmd != 129 || p1 != 12 || (p2 != 2 && p2 != 4) || p3 != 2)
|
||||
return null;
|
||||
|
||||
return Array.from({ length: 12 }, (_, i) => data.getUint16(4 + i * 2, true));
|
||||
}
|
||||
|
||||
async writeFinetuneData(data) {
|
||||
const pkg = data.reduce((acc, val) => acc.concat([val & 0xff, val >> 8]), [12, 1]);
|
||||
await this.sendFeatureReport(0x80, pkg);
|
||||
}
|
||||
|
||||
/**
|
||||
* Parse DS5 battery status from input data
|
||||
*/
|
||||
parseBatteryStatus(data) {
|
||||
const bat = data.getUint8(52); // DS5 battery byte is at position 52
|
||||
|
||||
// DS5: bat_charge = low 4 bits, bat_status = high 4 bits
|
||||
const bat_charge = bat & 0x0f;
|
||||
const bat_status = bat >> 4;
|
||||
|
||||
let bat_capacity = 0;
|
||||
let cable_connected = false;
|
||||
let is_charging = false;
|
||||
let is_error = false;
|
||||
|
||||
switch (bat_status) {
|
||||
case 0:
|
||||
// On battery power
|
||||
bat_capacity = Math.min(bat_charge * 10 + 5, 100);
|
||||
break;
|
||||
case 1:
|
||||
// Charging
|
||||
bat_capacity = Math.min(bat_charge * 10 + 5, 100);
|
||||
is_charging = true;
|
||||
cable_connected = true;
|
||||
break;
|
||||
case 2:
|
||||
// Fully charged
|
||||
bat_capacity = 100;
|
||||
cable_connected = true;
|
||||
break;
|
||||
default:
|
||||
// Error state
|
||||
is_error = true;
|
||||
break;
|
||||
}
|
||||
|
||||
return { bat_capacity, cable_connected, is_charging, is_error };
|
||||
}
|
||||
}
|
||||
|
||||
export default DS5Controller;
|
||||
248
js/controllers/ds5-edge-controller.js
Normal file
248
js/controllers/ds5-edge-controller.js
Normal file
@@ -0,0 +1,248 @@
|
||||
'use strict';
|
||||
|
||||
import DS5Controller from './ds5-controller.js';
|
||||
import { sleep, dec2hex32, la, lf } from '../utils.js';
|
||||
|
||||
/**
|
||||
* DualSense Edge (DS5 Edge) Controller implementation
|
||||
*/
|
||||
class DS5EdgeController extends DS5Controller {
|
||||
constructor(device, uiDependencies = {}) {
|
||||
super(device, uiDependencies);
|
||||
this.model = "DS5_Edge";
|
||||
this.finetuneMaxValue = 4095; // 12-bit max value for DS5 Edge
|
||||
}
|
||||
|
||||
async getInfo() {
|
||||
const { l } = this;
|
||||
|
||||
// DS5 Edge uses the same info structure as DS5 but with is_edge=true
|
||||
const result = await this._getInfo(true);
|
||||
|
||||
if (result.ok) {
|
||||
// DS Edge extra module info
|
||||
const empty = Array(17).fill('\x00').join('');
|
||||
try {
|
||||
const sticks_barcode = (await this.getBarcode()).map(barcode => barcode === empty ? l("Unknown") : barcode);
|
||||
result.infoItems.push({ key: l("Left Module Barcode"), value: sticks_barcode[1], cat: "fw" });
|
||||
result.infoItems.push({ key: l("Right Module Barcode"), value: sticks_barcode[0], cat: "fw" });
|
||||
} catch(_e) {
|
||||
// ignore module read errors here
|
||||
}
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
async flash(progressCallback = null) {
|
||||
la("ds5_edge_flash");
|
||||
try {
|
||||
const ret = await this.flashModules(progressCallback);
|
||||
if(ret) {
|
||||
return {
|
||||
success: true,
|
||||
message: "<b>" + this.l("Changes saved successfully") + "</b>.<br><br>" + this.l("If the calibration is not stored permanently, please double-check the wirings of the hardware mod."),
|
||||
isHtml: true
|
||||
};
|
||||
}
|
||||
} catch(error) {
|
||||
throw new Error(this.l("Error while saving changes"), { cause: error });
|
||||
}
|
||||
}
|
||||
|
||||
async getBarcode() {
|
||||
await this.sendFeatureReport(0x80, [21,34]);
|
||||
await sleep(100);
|
||||
|
||||
const data = lf("ds5_edge_get_barcode", await this.receiveFeatureReport(0x81));
|
||||
const td = new TextDecoder();
|
||||
const r_bc = td.decode(data.buffer.slice(21, 21+17));
|
||||
const l_bc = td.decode(data.buffer.slice(40, 40+17));
|
||||
return [r_bc, l_bc];
|
||||
}
|
||||
|
||||
async unlockModule(i) {
|
||||
const m_name = i == 0 ? "left module" : "right module";
|
||||
|
||||
await this.sendFeatureReport(0x80, [21, 6, i, 11]);
|
||||
await sleep(200);
|
||||
const ret = await this.waitUntilWritten([21, 6, 2]);
|
||||
if(!ret) {
|
||||
throw new Error(this.l("Cannot unlock") + " " + this.l(m_name));
|
||||
}
|
||||
}
|
||||
|
||||
async lockModule(i) {
|
||||
const m_name = i == 0 ? "left module" : "right module";
|
||||
|
||||
await this.sendFeatureReport(0x80, [21, 4, i, 8]);
|
||||
await sleep(200);
|
||||
const ret = await this.waitUntilWritten([21, 4, 2]);
|
||||
if(!ret) {
|
||||
throw new Error(this.l("Cannot lock") + " " + this.l(m_name));
|
||||
}
|
||||
}
|
||||
|
||||
async storeDataInto(i) {
|
||||
const m_name = i == 0 ? "left module" : "right module";
|
||||
|
||||
await this.sendFeatureReport(0x80, [21, 5, i]);
|
||||
await sleep(200);
|
||||
const ret = await this.waitUntilWritten([21, 3, 2]);
|
||||
if(!ret) {
|
||||
throw new Error(this.l("Cannot store data into") + " " + this.l(m_name));
|
||||
}
|
||||
}
|
||||
|
||||
async flashModules(progressCallback) {
|
||||
la("ds5_edge_flash_modules");
|
||||
try {
|
||||
progressCallback(0);
|
||||
|
||||
// Reload data, this ensures correctly writing data in the controller
|
||||
await sleep(100);
|
||||
progressCallback(10);
|
||||
|
||||
// Unlock modules
|
||||
await this.unlockModule(0);
|
||||
progressCallback(15);
|
||||
await this.unlockModule(1);
|
||||
progressCallback(30);
|
||||
|
||||
// Unlock NVS
|
||||
await this.nvsUnlock();
|
||||
await sleep(50);
|
||||
progressCallback(45);
|
||||
|
||||
// This should trigger write into modules
|
||||
const data = await this.getInMemoryModuleData();
|
||||
await sleep(50);
|
||||
progressCallback(60);
|
||||
await this.writeFinetuneData(data);
|
||||
|
||||
// Extra delay
|
||||
await sleep(100);
|
||||
|
||||
// Lock back modules
|
||||
await this.lockModule(0);
|
||||
progressCallback(80);
|
||||
await this.lockModule(1);
|
||||
progressCallback(100);
|
||||
|
||||
// Lock back NVS
|
||||
await sleep(100);
|
||||
const lockRes = await this.nvsLock();
|
||||
if(!lockRes.ok) throw (lockRes.error || new Error("NVS lock failed"));
|
||||
|
||||
await sleep(250);
|
||||
|
||||
return true;
|
||||
} catch(error) {
|
||||
la("ds5_edge_flash_modules_failed", {"r": error});
|
||||
throw error;
|
||||
}
|
||||
}
|
||||
|
||||
async waitUntilWritten(expected) {
|
||||
let attempts = 0;
|
||||
const maxAttempts = 10;
|
||||
|
||||
while (attempts < maxAttempts) {
|
||||
const data = await this.receiveFeatureReport(0x81);
|
||||
|
||||
// Check if all expected bytes match
|
||||
const allMatch = expected.every((expectedByte, i) =>
|
||||
data.getUint8(1 + i, true) === expectedByte
|
||||
);
|
||||
|
||||
if (allMatch) {
|
||||
return true;
|
||||
}
|
||||
|
||||
attempts++;
|
||||
await sleep(50);
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
async calibrateSticksEnd() {
|
||||
la("ds5_calibrate_sticks_end");
|
||||
try {
|
||||
// Write
|
||||
await this.sendFeatureReport(0x82, [2,1,1]);
|
||||
|
||||
let data = await this.receiveFeatureReport(0x83);
|
||||
|
||||
if(data.getUint32(0, false) != 0x83010101) {
|
||||
const d1 = dec2hex32(data.getUint32(0, false));
|
||||
la("ds5_calibrate_sticks_failed", {"s": 3, d1});
|
||||
return { ok: false, code: 4, d1 };
|
||||
}
|
||||
|
||||
await this.sendFeatureReport(0x82, [2,1,1]);
|
||||
data = await this.receiveFeatureReport(0x83);
|
||||
if(data.getUint32(0, false) != 0x83010103 && data.getUint32(0, false) != 0x83010312) {
|
||||
const d1 = dec2hex32(data.getUint32(0, false));
|
||||
la("ds5_calibrate_sticks_failed", {"s": 3, d1});
|
||||
return { ok: false, code: 5, d1 };
|
||||
}
|
||||
|
||||
return { ok: true };
|
||||
} catch(e) {
|
||||
la("ds5_calibrate_sticks_end_failed", {"r": e});
|
||||
return { ok: false, error: String(e) };
|
||||
}
|
||||
}
|
||||
|
||||
async calibrateRangeEnd() {
|
||||
la("ds5_calibrate_range_end");
|
||||
try {
|
||||
// Write
|
||||
await this.sendFeatureReport(0x82, [2,1,2]);
|
||||
|
||||
// Assert
|
||||
let data = await this.receiveFeatureReport(0x83);
|
||||
|
||||
if(data.getUint32(0, false) != 0x83010201) {
|
||||
const d1 = dec2hex32(data.getUint32(0, false));
|
||||
la("ds5_calibrate_range_end_failed", {d1});
|
||||
return { ok: false, code: 4, d1 };
|
||||
}
|
||||
|
||||
await this.sendFeatureReport(0x82, [2,1,2]);
|
||||
data = await this.receiveFeatureReport(0x83)
|
||||
if(data.getUint32(0, false) != 0x83010203) {
|
||||
const d1 = dec2hex32(data.getUint32(0, false));
|
||||
la("ds5_calibrate_range_end_failed", {d1});
|
||||
return { ok: false, code: 5, d1 };
|
||||
}
|
||||
|
||||
return { ok: true };
|
||||
} catch(e) {
|
||||
la("ds5_calibrate_range_end_failed", {"r": e});
|
||||
return { ok: false, error: String(e) };
|
||||
}
|
||||
}
|
||||
|
||||
async getInMemoryModuleData() {
|
||||
// DualSense Edge
|
||||
await this.sendFeatureReport(0x80, [12, 4]);
|
||||
await sleep(100);
|
||||
const data = await this.receiveFeatureReport(0x81);
|
||||
const cmd = data.getUint8(0, true);
|
||||
const [p1, p2, p3] = [1, 2, 3].map(i => data.getUint8(i, true));
|
||||
|
||||
if(cmd != 129 || p1 != 12 || (p2 != 2 && p2 != 4) || p3 != 2)
|
||||
return null;
|
||||
|
||||
return Array.from({ length: 12 }, (_, i) => data.getUint16(4 + i * 2, true));
|
||||
}
|
||||
|
||||
async writeFinetuneData(data) {
|
||||
const pkg = data.reduce((acc, val) => acc.concat([val & 0xff, val >> 8]), [12, 1]);
|
||||
await this.sendFeatureReport(0x80, pkg)
|
||||
}
|
||||
}
|
||||
|
||||
export default DS5EdgeController;
|
||||
1019
js/core.js
Normal file
1019
js/core.js
Normal file
File diff suppressed because it is too large
Load Diff
237
js/modals/calib-center-modal.js
Normal file
237
js/modals/calib-center-modal.js
Normal file
@@ -0,0 +1,237 @@
|
||||
'use strict';
|
||||
|
||||
import { sleep, la } from '../utils.js';
|
||||
import { l } from '../translations.js';
|
||||
|
||||
/**
|
||||
* Calibration Center Modal Class
|
||||
* Handles step-by-step manual stick center calibration
|
||||
*/
|
||||
export class CalibCenterModal {
|
||||
constructor(controllerInstance, { resetStickDiagrams, successAlert, set_progress }) {
|
||||
this.controller = controllerInstance;
|
||||
this.resetStickDiagrams = resetStickDiagrams;
|
||||
this.successAlert = successAlert;
|
||||
this.set_progress = set_progress;
|
||||
|
||||
this._initEventListeners();
|
||||
|
||||
// Hide the spinner in case it's showing after prior failure
|
||||
$("#calibNext").prop("disabled", false);
|
||||
$("#btnSpinner").hide();
|
||||
}
|
||||
|
||||
/**
|
||||
* Initialize event listeners for the calibration modal
|
||||
*/
|
||||
_initEventListeners() {
|
||||
$('#calibCenterModal').on('hidden.bs.modal', () => {
|
||||
console.log("Closing calibration modal");
|
||||
destroyCurrentInstance();
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Remove event listeners
|
||||
*/
|
||||
removeEventListeners() {
|
||||
$('#calibCenterModal').off('hidden.bs.modal');
|
||||
}
|
||||
|
||||
/**
|
||||
* Open the calibration modal
|
||||
*/
|
||||
async open() {
|
||||
la("calib_open");
|
||||
this.calibrationGenerator = this.calibrationSteps();
|
||||
await this.next();
|
||||
new bootstrap.Modal(document.getElementById('calibCenterModal'), {}).show();
|
||||
}
|
||||
|
||||
/**
|
||||
* Proceed to the next calibration step (legacy method)
|
||||
*/
|
||||
async next() {
|
||||
la("calib_next");
|
||||
const result = await this.calibrationGenerator.next();
|
||||
if (result.done) {
|
||||
this.calibrationGenerator = null;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Generator function for calibration steps
|
||||
*/
|
||||
async* calibrationSteps() {
|
||||
// Step 1: Initial setup
|
||||
la("calib_step", {"i": 1});
|
||||
this._updateUI(1, "Stick center calibration", "Start", true);
|
||||
yield 1;
|
||||
|
||||
// Step 2: Initialize calibration
|
||||
la("calib_step", {"i": 2});
|
||||
this._showSpinner("Initializing...");
|
||||
await sleep(100);
|
||||
await this._multiCalibSticksBegin();
|
||||
await this._hideSpinner();
|
||||
|
||||
this._updateUI(2, "Calibration in progress", "Continue", false);
|
||||
yield 2;
|
||||
|
||||
// Steps 3-5: Sample calibration data
|
||||
for (let sampleStep = 3; sampleStep <= 5; sampleStep++) {
|
||||
la("calib_step", {"i": sampleStep});
|
||||
this._showSpinner("Sampling...");
|
||||
await sleep(150);
|
||||
await this._multiCalibSticksSample();
|
||||
await this._hideSpinner();
|
||||
|
||||
this._updateUI(sampleStep, "Calibration in progress", "Continue", false);
|
||||
yield sampleStep;
|
||||
}
|
||||
|
||||
// Step 6: Final sampling and storage
|
||||
la("calib_step", {"i": 6});
|
||||
this._showSpinner("Sampling...");
|
||||
await this._multiCalibSticksSample();
|
||||
await sleep(200);
|
||||
$("#calibNextText").text(l("Storing calibration..."));
|
||||
await sleep(500);
|
||||
await this._multiCalibSticksEnd();
|
||||
await this._hideSpinner();
|
||||
|
||||
this._updateUI(6, "Stick center calibration", "Done", true);
|
||||
yield 6;
|
||||
|
||||
this._close();
|
||||
}
|
||||
|
||||
/**
|
||||
* "Old" fully automatic stick center calibration
|
||||
*/
|
||||
async multiCalibrateSticks() {
|
||||
if(!this.controller.isConnected())
|
||||
return;
|
||||
|
||||
this.set_progress(0);
|
||||
new bootstrap.Modal(document.getElementById('calibrateModal'), {}).show();
|
||||
|
||||
await sleep(1000);
|
||||
|
||||
// Use the controller manager's calibrateSticks method with UI progress updates
|
||||
this.set_progress(10);
|
||||
|
||||
const result = await this.controller.calibrateSticks((progress) => {
|
||||
this.set_progress(progress);
|
||||
});
|
||||
|
||||
await sleep(500);
|
||||
this._close();
|
||||
this.resetStickDiagrams();
|
||||
|
||||
if (result?.message) {
|
||||
this.successAlert(result.message);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Helper functions for step-by-step manual calibration UI
|
||||
*/
|
||||
async _multiCalibSticksBegin() {
|
||||
await this.controller.calibrateSticksBegin();
|
||||
}
|
||||
|
||||
async _multiCalibSticksEnd() {
|
||||
await this.controller.calibrateSticksEnd();
|
||||
}
|
||||
|
||||
async _multiCalibSticksSample() {
|
||||
await this.controller.calibrateSticksSample();
|
||||
}
|
||||
|
||||
/**
|
||||
* Close the calibration modal
|
||||
*/
|
||||
_close() {
|
||||
$(".modal.show").modal("hide");
|
||||
}
|
||||
|
||||
/**
|
||||
* Update the UI for a specific calibration step
|
||||
*/
|
||||
_updateUI(step, title, buttonText, allowDismiss) {
|
||||
// Hide all step lists and remove active class
|
||||
for (let j = 1; j < 7; j++) {
|
||||
$("#list-" + j).hide();
|
||||
$("#list-" + j + "-calib").removeClass("active");
|
||||
}
|
||||
|
||||
// Show current step and mark as active
|
||||
$("#list-" + step).show();
|
||||
$("#list-" + step + "-calib").addClass("active");
|
||||
|
||||
// Update title and button text
|
||||
$("#calibTitle").text(l(title));
|
||||
$("#calibNextText").text(l(buttonText));
|
||||
|
||||
// Show/hide cross icon
|
||||
if (allowDismiss) {
|
||||
$("#calibCross").show();
|
||||
} else {
|
||||
$("#calibCross").hide();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Show spinner and disable button
|
||||
*/
|
||||
_showSpinner(text) {
|
||||
$("#calibNextText").text(l(text));
|
||||
$("#btnSpinner").show();
|
||||
$("#calibNext").prop("disabled", true);
|
||||
}
|
||||
|
||||
/**
|
||||
* Hide spinner and enable button
|
||||
*/
|
||||
async _hideSpinner() {
|
||||
await sleep(200);
|
||||
$("#calibNext").prop("disabled", false);
|
||||
$("#btnSpinner").hide();
|
||||
}
|
||||
}
|
||||
|
||||
// Global reference to the current calibration instance
|
||||
let currentCalibCenterInstance = null;
|
||||
|
||||
/**
|
||||
* Helper function to safely clear the current calibration instance
|
||||
*/
|
||||
function destroyCurrentInstance() {
|
||||
if (currentCalibCenterInstance) {
|
||||
console.log("Destroying current calibration instance");
|
||||
currentCalibCenterInstance.removeEventListeners();
|
||||
currentCalibCenterInstance = null;
|
||||
}
|
||||
}
|
||||
|
||||
// Legacy function exports for backward compatibility
|
||||
export async function calibrate_stick_centers(controller, dependencies) {
|
||||
currentCalibCenterInstance = new CalibCenterModal(controller, dependencies);
|
||||
await currentCalibCenterInstance.open();
|
||||
}
|
||||
|
||||
async function calib_next() {
|
||||
if (currentCalibCenterInstance) {
|
||||
await currentCalibCenterInstance.next();
|
||||
}
|
||||
}
|
||||
|
||||
// "Old" fully automatic stick center calibration
|
||||
export async function auto_calibrate_stick_centers(controller, dependencies) {
|
||||
currentCalibCenterInstance = new CalibCenterModal(controller, dependencies);
|
||||
await currentCalibCenterInstance.multiCalibrateSticks();
|
||||
}
|
||||
|
||||
// Legacy compatibility - expose functions to window for HTML onclick handlers
|
||||
window.calib_next = calib_next;
|
||||
62
js/modals/calib-range-modal.js
Normal file
62
js/modals/calib-range-modal.js
Normal file
@@ -0,0 +1,62 @@
|
||||
'use strict';
|
||||
|
||||
import { sleep } from '../utils.js';
|
||||
|
||||
/**
|
||||
* Calibrate Stick Range Modal Class
|
||||
* Handles stick range calibration
|
||||
*/
|
||||
export class CalibRangeModal {
|
||||
constructor(controllerInstance, { resetStickDiagrams, successAlert }) {
|
||||
// Dependencies
|
||||
this.controller = controllerInstance;
|
||||
this.resetStickDiagrams = resetStickDiagrams;
|
||||
this.successAlert = successAlert;
|
||||
}
|
||||
|
||||
async open() {
|
||||
if(!this.controller.isConnected())
|
||||
return;
|
||||
|
||||
bootstrap.Modal.getOrCreateInstance('#rangeModal').show();
|
||||
|
||||
await sleep(1000);
|
||||
await this.controller.calibrateRangeBegin();
|
||||
}
|
||||
|
||||
async onClose() {
|
||||
bootstrap.Modal.getOrCreateInstance('#rangeModal').hide();
|
||||
this.resetStickDiagrams();
|
||||
|
||||
const result = await this.controller.calibrateRangeOnClose();
|
||||
if (result?.message) {
|
||||
this.successAlert(result.message);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Global reference to the current range calibration instance
|
||||
let currentCalibRangeInstance = null;
|
||||
|
||||
/**
|
||||
* Helper function to safely clear the current calibration instance
|
||||
*/
|
||||
function destroyCurrentInstance() {
|
||||
currentCalibRangeInstance = null;
|
||||
}
|
||||
|
||||
// Legacy function exports for backward compatibility
|
||||
export async function calibrate_range(controller, dependencies) {
|
||||
destroyCurrentInstance(); // Clean up any existing instance
|
||||
currentCalibRangeInstance = new CalibRangeModal(controller, dependencies);
|
||||
await currentCalibRangeInstance.open();
|
||||
}
|
||||
|
||||
async function calibrate_range_on_close() {
|
||||
if (currentCalibRangeInstance) {
|
||||
await currentCalibRangeInstance.onClose();
|
||||
}
|
||||
}
|
||||
|
||||
// Legacy compatibility - expose functions to window for HTML onclick handlers
|
||||
window.calibrate_range_on_close = calibrate_range_on_close;
|
||||
817
js/modals/finetune-modal.js
Normal file
817
js/modals/finetune-modal.js
Normal file
@@ -0,0 +1,817 @@
|
||||
'use strict';
|
||||
|
||||
import { draw_stick_position } from '../stick-renderer.js';
|
||||
import { dec2hex32, float_to_str } from '../utils.js';
|
||||
|
||||
const FINETUNE_INPUT_SUFFIXES = ["LL", "LT", "RL", "RT", "LR", "LB", "RR", "RB", "LX", "LY", "RX", "RY"];
|
||||
|
||||
/**
|
||||
* DS5 Finetuning Class
|
||||
* Handles controller stick calibration and fine-tuning operations
|
||||
*/
|
||||
export class Finetune {
|
||||
constructor() {
|
||||
this._mode = 'center'; // 'center' or 'circularity'
|
||||
this.original_data = [];
|
||||
this.last_written_data = [];
|
||||
this.active_stick = null; // 'left', 'right', or null
|
||||
this._centerStepSize = 5; // Default step size for center mode
|
||||
this._circularityStepSize = 5; // Default step size for circularity mode
|
||||
|
||||
// Dependencies
|
||||
this.controller = null;
|
||||
this.ll_data = null;
|
||||
this.rr_data = null;
|
||||
this.clearCircularity = null;
|
||||
|
||||
// Closure functions
|
||||
this.refresh_finetune_sticks = this._createRefreshSticksThrottled();
|
||||
this.update_finetune_warning_messages = this._createUpdateWarningMessagesClosure();
|
||||
this.flash_finetune_warning = this._createFlashWarningClosure();
|
||||
|
||||
// Continuous adjustment state
|
||||
this.continuous_adjustment = {
|
||||
initial_delay: null,
|
||||
repeat_delay: null,
|
||||
};
|
||||
}
|
||||
|
||||
get mode() {
|
||||
return this._mode;
|
||||
}
|
||||
|
||||
set mode(mode) {
|
||||
if (mode !== 'center' && mode !== 'circularity') {
|
||||
throw new Error(`Invalid finetune mode: ${mode}. Must be 'center' or 'circularity'`);
|
||||
}
|
||||
this._mode = mode;
|
||||
this._updateUI();
|
||||
}
|
||||
|
||||
get stepSize() {
|
||||
return this._mode === 'center' ? this._centerStepSize : this._circularityStepSize;
|
||||
}
|
||||
|
||||
set stepSize(size) {
|
||||
if (this._mode === 'center') {
|
||||
this._centerStepSize = size;
|
||||
} else {
|
||||
this._circularityStepSize = size;
|
||||
}
|
||||
this._updateStepSizeUI();
|
||||
this._saveStepSizeToLocalStorage();
|
||||
}
|
||||
|
||||
async init(controllerInstance, { ll_data, rr_data, clear_circularity }) {
|
||||
this.controller = controllerInstance;
|
||||
this.ll_data = ll_data;
|
||||
this.rr_data = rr_data;
|
||||
this.clearCircularity = clear_circularity;
|
||||
|
||||
this._initEventListeners();
|
||||
this._restoreShowRawNumbersCheckbox();
|
||||
this._restoreStepSizeFromLocalStorage();
|
||||
|
||||
// Lock NVS before
|
||||
const nv = await this.controller.queryNvStatus();
|
||||
if(!nv.locked) {
|
||||
const res = await this.controller.nvsLock();
|
||||
if(!res.ok) {
|
||||
return;
|
||||
}
|
||||
|
||||
const nv2 = await this.controller.queryNvStatus();
|
||||
if(!nv2.locked) {
|
||||
const errTxt = "0x" + dec2hex32(nv2.raw);
|
||||
throw new Error("ERROR: Cannot lock NVS (" + errTxt + ")");
|
||||
}
|
||||
} else if(nv.status !== 'locked') {
|
||||
throw new Error("ERROR: Cannot read NVS status. Finetuning is not safe on this device.");
|
||||
}
|
||||
|
||||
const data = await this._readFinetuneData();
|
||||
|
||||
const modal = new bootstrap.Modal(document.getElementById('finetuneModal'), {})
|
||||
modal.show();
|
||||
|
||||
const maxValue = this.controller.getFinetuneMaxValue();
|
||||
FINETUNE_INPUT_SUFFIXES.forEach((suffix, i) => {
|
||||
const el = $("#finetune" + suffix);
|
||||
el.attr('max', maxValue);
|
||||
el.val(data[i]);
|
||||
});
|
||||
|
||||
// Start in center mode
|
||||
this.setMode('center');
|
||||
this.setStickToFinetune('left');
|
||||
|
||||
// Initialize the raw numbers display state
|
||||
this._showRawNumbersChanged();
|
||||
|
||||
this.original_data = data;
|
||||
|
||||
this.refresh_finetune_sticks();
|
||||
}
|
||||
|
||||
/**
|
||||
* Initialize event listeners for the finetune modal
|
||||
*/
|
||||
_initEventListeners() {
|
||||
FINETUNE_INPUT_SUFFIXES.forEach((suffix) => {
|
||||
$("#finetune" + suffix).on('change', () => this._onFinetuneChange());
|
||||
});
|
||||
|
||||
// Set up mode toggle event listeners
|
||||
$("#finetuneModeCenter").on('change', (e) => {
|
||||
if (e.target.checked) {
|
||||
this.setMode('center');
|
||||
}
|
||||
});
|
||||
|
||||
$("#finetuneModeCircularity").on('change', (e) => {
|
||||
if (e.target.checked) {
|
||||
this.setMode('circularity');
|
||||
}
|
||||
});
|
||||
|
||||
$("#showRawNumbersCheckbox").on('change', () => {
|
||||
this._showRawNumbersChanged();
|
||||
});
|
||||
|
||||
$("#left-stick-card").on('click', () => {
|
||||
console.log("Left stick card clicked");
|
||||
this.setStickToFinetune('left');
|
||||
});
|
||||
|
||||
$("#right-stick-card").on('click', () => {
|
||||
this.setStickToFinetune('right');
|
||||
});
|
||||
|
||||
$('#finetuneModal').on('hidden.bs.modal', () => {
|
||||
console.log("Finetune modal hidden event triggered");
|
||||
destroyCurrentInstance();
|
||||
});
|
||||
|
||||
// Step size dropdown event listeners
|
||||
$('.dropdown-item[data-step]').on('click', (e) => {
|
||||
e.preventDefault();
|
||||
const stepSize = parseInt($(e.target).data('step'));
|
||||
this.stepSize = stepSize;
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Clean up event listeners for the finetune modal
|
||||
*/
|
||||
removeEventListeners() {
|
||||
FINETUNE_INPUT_SUFFIXES.forEach((suffix) => {
|
||||
$("#finetune" + suffix).off('change');
|
||||
});
|
||||
|
||||
// Remove mode toggle event listeners
|
||||
$("#finetuneModeCenter").off('change');
|
||||
$("#finetuneModeCircularity").off('change');
|
||||
|
||||
// Remove other event listeners
|
||||
$("#showRawNumbersCheckbox").off('change');
|
||||
$("#left-stick-card").off('click');
|
||||
$("#right-stick-card").off('click');
|
||||
|
||||
$('#finetuneModal').off('hidden.bs.modal');
|
||||
$('.dropdown-item[data-step]').off('click');
|
||||
}
|
||||
|
||||
/**
|
||||
* Handle mode switching based on controller input
|
||||
*/
|
||||
handleModeSwitching(changes) {
|
||||
if (changes.l1) {
|
||||
this.setMode('center');
|
||||
this._clearFinetuneAxisHighlights();
|
||||
} else if (changes.r1) {
|
||||
this.setMode('circularity');
|
||||
this._clearFinetuneAxisHighlights();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Handle stick switching based on controller input
|
||||
*/
|
||||
handleStickSwitching(changes) {
|
||||
if (changes.sticks) {
|
||||
this._updateActiveStickBasedOnMovement();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Handle D-pad adjustments for finetuning
|
||||
*/
|
||||
handleDpadAdjustment(changes) {
|
||||
if(!this.active_stick) return;
|
||||
|
||||
if (this._mode === 'center') {
|
||||
this._handleCenterModeAdjustment(changes);
|
||||
} else {
|
||||
this._handleCircularityModeAdjustment(changes);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Save finetune changes
|
||||
*/
|
||||
save() {
|
||||
// Unlock save button
|
||||
this.controller.setHasChangesToWrite(true);
|
||||
|
||||
this._close();
|
||||
}
|
||||
|
||||
/**
|
||||
* Cancel finetune changes and restore original data
|
||||
*/
|
||||
async cancel() {
|
||||
if(this.original_data.length == 12)
|
||||
await this._writeFinetuneData(this.original_data)
|
||||
|
||||
this._close();
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the finetune mode
|
||||
*/
|
||||
setMode(mode) {
|
||||
this.mode = mode;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set which stick to finetune
|
||||
*/
|
||||
setStickToFinetune(stick) {
|
||||
if(this.active_stick === stick) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Stop any continuous adjustments when switching sticks
|
||||
this.stopContinuousDpadAdjustment();
|
||||
this._clearFinetuneAxisHighlights();
|
||||
|
||||
this.active_stick = stick;
|
||||
|
||||
const other_stick = stick === 'left' ? 'right' : 'left';
|
||||
$(`#${this.active_stick}-stick-card`).addClass("stick-card-active");
|
||||
$(`#${other_stick}-stick-card`).removeClass("stick-card-active");
|
||||
}
|
||||
|
||||
// Private methods
|
||||
|
||||
/**
|
||||
* Restore the show raw numbers checkbox state from localStorage
|
||||
*/
|
||||
_restoreShowRawNumbersCheckbox() {
|
||||
const savedState = localStorage.getItem('showRawNumbersCheckbox');
|
||||
if (savedState) {
|
||||
const isChecked = savedState === 'true';
|
||||
$("#showRawNumbersCheckbox").prop('checked', isChecked);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if stick is in extreme position (close to edges)
|
||||
* @param {Object} stick - Stick object with x and y properties
|
||||
* @returns {boolean} True if stick is in extreme position
|
||||
*/
|
||||
_isStickInExtremePosition(stick) {
|
||||
const primeAxis = Math.max(Math.abs(stick.x), Math.abs(stick.y));
|
||||
const otherAxis = Math.min(Math.abs(stick.x), Math.abs(stick.y));
|
||||
return primeAxis >= 0.5 && otherAxis < 0.2;
|
||||
}
|
||||
|
||||
_updateUI() {
|
||||
// Clear circularity data - we'll call this from core.js
|
||||
this.clearCircularity();
|
||||
|
||||
const modal = $('#finetuneModal');
|
||||
if (this._mode === 'center') {
|
||||
$("#finetuneModeCenter").prop('checked', true);
|
||||
modal.removeClass('circularity-mode');
|
||||
} else if (this._mode === 'circularity') {
|
||||
$("#finetuneModeCircularity").prop('checked', true);
|
||||
modal.addClass('circularity-mode');
|
||||
}
|
||||
|
||||
// Update step size UI when mode changes
|
||||
this._updateStepSizeUI();
|
||||
}
|
||||
|
||||
async _onFinetuneChange() {
|
||||
const out = FINETUNE_INPUT_SUFFIXES.map((suffix) => {
|
||||
const el = $("#finetune" + suffix);
|
||||
const v = parseInt(el.val());
|
||||
return isNaN(v) ? 0 : v;
|
||||
});
|
||||
await this._writeFinetuneData(out);
|
||||
}
|
||||
|
||||
async _readFinetuneData() {
|
||||
const data = await this.controller.getInMemoryModuleData();
|
||||
if(!data) {
|
||||
throw new Error("ERROR: Cannot read calibration data");
|
||||
}
|
||||
|
||||
this.last_written_data = data;
|
||||
return data;
|
||||
}
|
||||
|
||||
async _writeFinetuneData(data) {
|
||||
if (data.length != 12) {
|
||||
return;
|
||||
}
|
||||
|
||||
// const deepEqual = (a, b) => JSON.stringify(a) === JSON.stringify(b);
|
||||
// if (deepEqual(data, this.last_written_data)) {
|
||||
// if (data == this.last_written_data) { //mm this will never be true, but fixing it (per above) breaks Edge writes
|
||||
// return;
|
||||
// }
|
||||
|
||||
this.last_written_data = data
|
||||
if (this.controller.isConnected()) {
|
||||
await this.controller.writeFinetuneData(data);
|
||||
}
|
||||
}
|
||||
|
||||
_createRefreshSticksThrottled() {
|
||||
let timeout = null;
|
||||
|
||||
return () => {
|
||||
if (timeout) return;
|
||||
|
||||
timeout = setTimeout(() => {
|
||||
const { left, right } = this.controller.button_states.sticks;
|
||||
this._ds5FinetuneUpdate("finetuneStickCanvasL", left.x, left.y);
|
||||
this._ds5FinetuneUpdate("finetuneStickCanvasR", right.x, right.y);
|
||||
|
||||
this.update_finetune_warning_messages();
|
||||
this._highlightActiveFinetuneAxis();
|
||||
|
||||
timeout = null;
|
||||
}, 10);
|
||||
};
|
||||
}
|
||||
|
||||
_createUpdateWarningMessagesClosure() {
|
||||
let timeout = null; // to stop unnecessary flicker in center mode
|
||||
|
||||
return () => {
|
||||
if(!this.active_stick) return;
|
||||
|
||||
const currentStick = this.controller.button_states.sticks[this.active_stick];
|
||||
if (this._mode === 'center') {
|
||||
const isNearCenter = Math.abs(currentStick.x) <= 0.5 && Math.abs(currentStick.y) <= 0.5;
|
||||
if(!isNearCenter && timeout) return;
|
||||
|
||||
clearTimeout(timeout);
|
||||
timeout = setTimeout(() => {
|
||||
timeout = null;
|
||||
if(this._mode !== 'center') return; // in case it changed during timeout
|
||||
|
||||
$('#finetuneCenterSuccess').toggle(isNearCenter);
|
||||
$('#finetuneCenterWarning').toggle(!isNearCenter);
|
||||
}, isNearCenter ? 0 : 200);
|
||||
}
|
||||
|
||||
if (this._mode === 'circularity') {
|
||||
// Check if stick is in extreme position (close to edges)
|
||||
const isInExtremePosition = this._isStickInExtremePosition(currentStick);
|
||||
$('#finetuneCircularitySuccess').toggle(isInExtremePosition);
|
||||
$('#finetuneCircularityWarning').toggle(!isInExtremePosition);
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
_clearFinetuneAxisHighlights(to_clear = {center: true, circularity: true}) {
|
||||
const { center, circularity } = to_clear;
|
||||
|
||||
if(this._mode === 'center' && center || this._mode === 'circularity' && circularity) {
|
||||
// Clear label highlights
|
||||
const labelIds = ["Lx-lbl", "Ly-lbl", "Rx-lbl", "Ry-lbl"];
|
||||
labelIds.forEach(suffix => {
|
||||
$(`#finetuneStickCanvas${suffix}`).removeClass("text-primary");
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
_highlightActiveFinetuneAxis(opts = {}) {
|
||||
if(!this.active_stick) return;
|
||||
|
||||
if (this._mode === 'center') {
|
||||
const { axis } = opts;
|
||||
if(!axis) return;
|
||||
|
||||
this._clearFinetuneAxisHighlights({center: true});
|
||||
|
||||
const labelSuffix = `${this.active_stick === 'left' ? "L" : "R"}${axis.toLowerCase()}`;
|
||||
$(`#finetuneStickCanvas${labelSuffix}-lbl`).addClass("text-primary");
|
||||
} else {
|
||||
this._clearFinetuneAxisHighlights({circularity: true});
|
||||
|
||||
const sticks = this.controller.button_states.sticks;
|
||||
const currentStick = sticks[this.active_stick];
|
||||
|
||||
// Only highlight if stick is moved significantly from center
|
||||
const deadzone = 0.5;
|
||||
if (Math.abs(currentStick.x) >= deadzone || Math.abs(currentStick.y) >= deadzone) {
|
||||
const quadrant = this._getStickQuadrant(currentStick.x, currentStick.y);
|
||||
const inputSuffix = this._getFinetuneInputSuffixForQuadrant(this.active_stick, quadrant);
|
||||
if (inputSuffix) {
|
||||
// Highlight the corresponding LX/LY label to observe
|
||||
const labelId = `finetuneStickCanvas${
|
||||
this.active_stick === 'left' ? 'L' : 'R'}${
|
||||
quadrant === 'left' || quadrant === 'right' ? 'x' : 'y'}-lbl`;
|
||||
$(`#${labelId}`).addClass("text-primary");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
_ds5FinetuneUpdate(name, plx, ply) {
|
||||
const showRawNumbers = $("#showRawNumbersCheckbox").is(":checked");
|
||||
const canvasId = `${name}${showRawNumbers ? '' : '_large'}`;
|
||||
const c = document.getElementById(canvasId);
|
||||
|
||||
if (!c) {
|
||||
console.error(`Canvas element not found: ${canvasId}`);
|
||||
return;
|
||||
}
|
||||
|
||||
const ctx = c.getContext("2d");
|
||||
|
||||
const margins = showRawNumbers ? 15 : 5;
|
||||
const radius = c.width / 2 - margins;
|
||||
const sz = c.width/2 - margins;
|
||||
const hb = radius + margins;
|
||||
const yb = radius + margins;
|
||||
ctx.clearRect(0, 0, c.width, c.height);
|
||||
|
||||
const isLeftStick = name === "finetuneStickCanvasL";
|
||||
const highlight = this.active_stick == (isLeftStick ? 'left' : 'right') && this._isDpadAdjustmentActive();
|
||||
if (this._mode === 'circularity') {
|
||||
// Draw stick position with circle
|
||||
draw_stick_position(ctx, hb, yb, sz, plx, ply, {
|
||||
circularity_data: isLeftStick ? this.ll_data : this.rr_data,
|
||||
highlight
|
||||
});
|
||||
} else {
|
||||
// Draw stick position with crosshair
|
||||
draw_stick_position(ctx, hb, yb, sz, plx, ply, {
|
||||
enable_zoom_center: true,
|
||||
highlight
|
||||
});
|
||||
}
|
||||
|
||||
$("#"+ name + "x-lbl").text(float_to_str(plx, 3));
|
||||
$("#"+ name + "y-lbl").text(float_to_str(ply, 3));
|
||||
}
|
||||
|
||||
_showRawNumbersChanged() {
|
||||
const showRawNumbers = $("#showRawNumbersCheckbox").is(":checked");
|
||||
const modal = $("#finetuneModal");
|
||||
modal.toggleClass("hide-raw-numbers", !showRawNumbers);
|
||||
localStorage.setItem('showRawNumbersCheckbox', showRawNumbers);
|
||||
|
||||
this.refresh_finetune_sticks();
|
||||
}
|
||||
|
||||
_close() {
|
||||
console.log("Closing finetune modal");
|
||||
$("#finetuneModal").modal("hide");
|
||||
}
|
||||
|
||||
_isStickAwayFromCenter(stick_pos, deadzone = 0.2) {
|
||||
return Math.abs(stick_pos.x) >= deadzone || Math.abs(stick_pos.y) >= deadzone;
|
||||
}
|
||||
|
||||
_updateActiveStickBasedOnMovement() {
|
||||
const sticks = this.controller.button_states.sticks;
|
||||
const deadzone = 0.2;
|
||||
|
||||
const left_is_away = this._isStickAwayFromCenter(sticks.left, deadzone);
|
||||
const right_is_away = this._isStickAwayFromCenter(sticks.right, deadzone);
|
||||
|
||||
if (left_is_away && right_is_away) {
|
||||
// Both sticks are away from center - clear highlighting
|
||||
this._clearActiveStick();
|
||||
} else if (left_is_away && !right_is_away) {
|
||||
// Only left stick is away from center
|
||||
this.setStickToFinetune('left');
|
||||
} else if (right_is_away && !left_is_away) {
|
||||
// Only right stick is away from center
|
||||
this.setStickToFinetune('right');
|
||||
}
|
||||
// If both sticks are centered, keep current active stick (no change)
|
||||
}
|
||||
|
||||
_clearActiveStick() {
|
||||
// Remove active class from both cards
|
||||
$("#left-stick-card").removeClass("stick-card-active");
|
||||
$("#right-stick-card").removeClass("stick-card-active");
|
||||
|
||||
this.active_stick = null; // Clear active stick
|
||||
this._clearFinetuneAxisHighlights();
|
||||
}
|
||||
|
||||
_getStickQuadrant(x, y) {
|
||||
// Determine which quadrant the stick is in based on x,y coordinates
|
||||
// x and y are normalized values between -1 and 1
|
||||
if (Math.abs(x) > Math.abs(y)) {
|
||||
return x > 0 ? 'right' : 'left';
|
||||
} else {
|
||||
return y > 0 ? 'down' : 'up';
|
||||
}
|
||||
}
|
||||
|
||||
_getFinetuneInputSuffixForQuadrant(stick, quadrant) {
|
||||
// This function should only be used in circularity mode
|
||||
// In center mode, we don't care about quadrants - use direct axis mapping instead
|
||||
if (this._mode === 'center') {
|
||||
// This function shouldn't be called in center mode
|
||||
console.warn('get_finetune_input_suffix_for_quadrant called in center mode - this should not happen');
|
||||
return null;
|
||||
}
|
||||
|
||||
// Circularity mode: map quadrants to specific calibration points
|
||||
if (stick === 'left') {
|
||||
switch (quadrant) {
|
||||
case 'left': return "LL";
|
||||
case 'up': return "LT";
|
||||
case 'right': return "LR";
|
||||
case 'down': return "LB";
|
||||
}
|
||||
} else if (stick === 'right') {
|
||||
switch (quadrant) {
|
||||
case 'left': return "RL";
|
||||
case 'up': return "RT";
|
||||
case 'right': return "RR";
|
||||
case 'down': return "RB";
|
||||
}
|
||||
}
|
||||
return null; // Invalid
|
||||
}
|
||||
|
||||
_handleCenterModeAdjustment(changes) {
|
||||
const adjustmentStep = this._centerStepSize; // Use center step size for center mode
|
||||
|
||||
// Define button mappings for center mode
|
||||
const buttonMappings = [
|
||||
{ buttons: ['left', 'square'], adjustment: adjustmentStep, axis: 'X' },
|
||||
{ buttons: ['right', 'circle'], adjustment: -adjustmentStep, axis: 'X' },
|
||||
{ buttons: ['up', 'triangle'], adjustment: adjustmentStep, axis: 'Y' },
|
||||
{ buttons: ['down', 'cross'], adjustment: -adjustmentStep, axis: 'Y' }
|
||||
];
|
||||
|
||||
// Check if any relevant button was released
|
||||
const relevantButtons = ['left', 'right', 'square', 'circle', 'up', 'down', 'triangle', 'cross'];
|
||||
if (relevantButtons.some(button => changes[button] === false)) {
|
||||
this.stopContinuousDpadAdjustment();
|
||||
return;
|
||||
}
|
||||
|
||||
// Check for button presses
|
||||
for (const mapping of buttonMappings) {
|
||||
// Check if active stick is away from center (> 0.5)
|
||||
const sticks = this.controller.button_states.sticks;
|
||||
const currentStick = sticks[this.active_stick];
|
||||
const stickAwayFromCenter = Math.abs(currentStick.x) > 0.5 || Math.abs(currentStick.y) > 0.5;
|
||||
if (stickAwayFromCenter && this._isNavigationKeyPressed()) {
|
||||
this.flash_finetune_warning();
|
||||
return;
|
||||
}
|
||||
|
||||
if (mapping.buttons.some(button => changes[button])) {
|
||||
this._highlightActiveFinetuneAxis({axis: mapping.axis});
|
||||
this._startContinuousDpadAdjustmentCenterMode(this.active_stick, mapping.axis, mapping.adjustment);
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
_isNavigationKeyPressed() {
|
||||
const nav_buttons = ['left', 'right', 'up', 'down', 'square', 'circle', 'triangle', 'cross'];
|
||||
return nav_buttons.some(button => this.controller.button_states[button] === true);
|
||||
}
|
||||
|
||||
_createFlashWarningClosure() {
|
||||
let timeout = null;
|
||||
|
||||
return () => {
|
||||
function toggle() {
|
||||
$("#finetuneCenterWarning").toggleClass(['alert-warning', 'alert-danger']);
|
||||
$("#finetuneCircularityWarning").toggleClass(['alert-warning', 'alert-danger']);
|
||||
}
|
||||
|
||||
if(timeout) return;
|
||||
|
||||
toggle(); // on
|
||||
timeout = setTimeout(() => {
|
||||
toggle(); // off
|
||||
timeout = null;
|
||||
}, 300);
|
||||
};
|
||||
}
|
||||
|
||||
_handleCircularityModeAdjustment({sticks: _, ...changes}) {
|
||||
const sticks = this.controller.button_states.sticks;
|
||||
const currentStick = sticks[this.active_stick];
|
||||
|
||||
// Only adjust if stick is moved significantly from center
|
||||
const isInExtremePosition = this._isStickInExtremePosition(currentStick);
|
||||
if (!isInExtremePosition) {
|
||||
this.stopContinuousDpadAdjustment();
|
||||
if(this._isNavigationKeyPressed()) {
|
||||
this.flash_finetune_warning();
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
const quadrant = this._getStickQuadrant(currentStick.x, currentStick.y);
|
||||
|
||||
// Use circularity step size for circularity mode
|
||||
const adjustmentStep = this._circularityStepSize;
|
||||
|
||||
// Define button mappings for each quadrant type
|
||||
const horizontalButtons = ['left', 'right', 'square', 'circle'];
|
||||
const verticalButtons = ['up', 'down', 'triangle', 'cross'];
|
||||
|
||||
let adjustment = 0;
|
||||
let relevantButtons = [];
|
||||
|
||||
if (quadrant === 'left' || quadrant === 'right') {
|
||||
// Horizontal quadrants: left increases, right decreases
|
||||
relevantButtons = horizontalButtons;
|
||||
if (changes.left || changes.square) {
|
||||
adjustment = adjustmentStep;
|
||||
} else if (changes.right || changes.circle) {
|
||||
adjustment = -adjustmentStep;
|
||||
}
|
||||
} else if (quadrant === 'up' || quadrant === 'down') {
|
||||
// Vertical quadrants: up increases, down decreases
|
||||
relevantButtons = verticalButtons;
|
||||
if (changes.up || changes.triangle) {
|
||||
adjustment = adjustmentStep;
|
||||
} else if (changes.down || changes.cross) {
|
||||
adjustment = -adjustmentStep;
|
||||
}
|
||||
}
|
||||
|
||||
// Check if any relevant button was released
|
||||
if (relevantButtons.some(button => changes[button] === false)) {
|
||||
this.stopContinuousDpadAdjustment();
|
||||
return;
|
||||
}
|
||||
|
||||
// Start continuous adjustment on button press
|
||||
if (adjustment !== 0) {
|
||||
this._startContinuousDpadAdjustment(this.active_stick, quadrant, adjustment);
|
||||
}
|
||||
}
|
||||
|
||||
_startContinuousDpadAdjustment(stick, quadrant, adjustment) {
|
||||
const inputSuffix = this._getFinetuneInputSuffixForQuadrant(stick, quadrant);
|
||||
this._startContinuousAdjustmentWithSuffix(inputSuffix, adjustment);
|
||||
}
|
||||
|
||||
_startContinuousDpadAdjustmentCenterMode(stick, targetAxis, adjustment) {
|
||||
// In center mode, directly map to X/Y axes
|
||||
const inputSuffix = stick === 'left' ?
|
||||
(targetAxis === 'X' ? 'LX' : 'LY') :
|
||||
(targetAxis === 'X' ? 'RX' : 'RY');
|
||||
this._startContinuousAdjustmentWithSuffix(inputSuffix, adjustment);
|
||||
}
|
||||
|
||||
_startContinuousAdjustmentWithSuffix(inputSuffix, adjustment) {
|
||||
this.stopContinuousDpadAdjustment();
|
||||
|
||||
const element = $(`#finetune${inputSuffix}`);
|
||||
if (!element.length) return;
|
||||
|
||||
// Perform initial adjustment immediately...
|
||||
this._performDpadAdjustment(element, adjustment);
|
||||
this.clearCircularity();
|
||||
|
||||
// ...then prime continuous adjustment
|
||||
this.continuous_adjustment.initial_delay = setTimeout(() => {
|
||||
this.continuous_adjustment.repeat_delay = setInterval(() => {
|
||||
this._performDpadAdjustment(element, adjustment);
|
||||
this.clearCircularity();
|
||||
}, 150);
|
||||
}, 400); // Initial delay before continuous adjustment starts (400ms)
|
||||
}
|
||||
|
||||
stopContinuousDpadAdjustment() {
|
||||
clearInterval(this.continuous_adjustment.repeat_delay);
|
||||
this.continuous_adjustment.repeat_delay = null;
|
||||
|
||||
clearTimeout(this.continuous_adjustment.initial_delay);
|
||||
this.continuous_adjustment.initial_delay = null;
|
||||
}
|
||||
|
||||
_isDpadAdjustmentActive() {
|
||||
return !!this.continuous_adjustment.initial_delay;
|
||||
}
|
||||
|
||||
async _performDpadAdjustment(element, adjustment) {
|
||||
const currentValue = parseInt(element.val()) || 0;
|
||||
const maxValue = this.controller.getFinetuneMaxValue();
|
||||
|
||||
const newValue = Math.max(0, Math.min(maxValue, currentValue + adjustment));
|
||||
element.val(newValue);
|
||||
|
||||
// Trigger the change event to update the finetune data
|
||||
await this._onFinetuneChange();
|
||||
}
|
||||
|
||||
/**
|
||||
* Update the step size UI display
|
||||
*/
|
||||
_updateStepSizeUI() {
|
||||
const currentStepSize = this._mode === 'center' ? this._centerStepSize : this._circularityStepSize;
|
||||
$('#stepSizeValue').text(currentStepSize);
|
||||
}
|
||||
|
||||
/**
|
||||
* Save step size to localStorage
|
||||
*/
|
||||
_saveStepSizeToLocalStorage() {
|
||||
localStorage.setItem('finetuneCenterStepSize', this._centerStepSize.toString());
|
||||
localStorage.setItem('finetuneCircularityStepSize', this._circularityStepSize.toString());
|
||||
}
|
||||
|
||||
/**
|
||||
* Restore step size from localStorage
|
||||
*/
|
||||
_restoreStepSizeFromLocalStorage() {
|
||||
// Restore center step size
|
||||
const savedCenterStepSize = localStorage.getItem('finetuneCenterStepSize');
|
||||
if (savedCenterStepSize) {
|
||||
this._centerStepSize = parseInt(savedCenterStepSize);
|
||||
}
|
||||
|
||||
// Restore circularity step size
|
||||
const savedCircularityStepSize = localStorage.getItem('finetuneCircularityStepSize');
|
||||
if (savedCircularityStepSize) {
|
||||
this._circularityStepSize = parseInt(savedCircularityStepSize);
|
||||
}
|
||||
|
||||
this._updateStepSizeUI();
|
||||
}
|
||||
}
|
||||
|
||||
// Global reference to the current finetune instance
|
||||
let currentFinetuneInstance = null;
|
||||
|
||||
/**
|
||||
* Helper function to safely clear the current finetune instance
|
||||
*/
|
||||
function destroyCurrentInstance() {
|
||||
if (currentFinetuneInstance) {
|
||||
currentFinetuneInstance.stopContinuousDpadAdjustment();
|
||||
currentFinetuneInstance.removeEventListeners();
|
||||
currentFinetuneInstance = null;
|
||||
}
|
||||
}
|
||||
|
||||
// Function to create and initialize finetune instance
|
||||
export async function ds5_finetune(controller, dependencies) {
|
||||
// Create new instance
|
||||
currentFinetuneInstance = new Finetune();
|
||||
await currentFinetuneInstance.init(controller, dependencies);
|
||||
}
|
||||
|
||||
export function finetune_handle_controller_input(changes) {
|
||||
if (currentFinetuneInstance) {
|
||||
currentFinetuneInstance.refresh_finetune_sticks();
|
||||
currentFinetuneInstance.handleModeSwitching(changes);
|
||||
currentFinetuneInstance.handleStickSwitching(changes);
|
||||
currentFinetuneInstance.handleDpadAdjustment(changes);
|
||||
}
|
||||
}
|
||||
|
||||
function finetune_save() {
|
||||
console.log("Saving finetune changes");
|
||||
if (currentFinetuneInstance) {
|
||||
currentFinetuneInstance.save();
|
||||
}
|
||||
}
|
||||
|
||||
async function finetune_cancel() {
|
||||
console.log("Cancelling finetune changes");
|
||||
if (currentFinetuneInstance) {
|
||||
await currentFinetuneInstance.cancel();
|
||||
}
|
||||
}
|
||||
|
||||
export function isFinetuneVisible() {
|
||||
return !!currentFinetuneInstance;
|
||||
}
|
||||
|
||||
window.finetune_cancel = finetune_cancel;
|
||||
window.finetune_save = finetune_save;
|
||||
213
js/stick-renderer.js
Normal file
213
js/stick-renderer.js
Normal file
@@ -0,0 +1,213 @@
|
||||
'use strict';
|
||||
|
||||
// Constants
|
||||
export const CIRCULARITY_DATA_SIZE = 48; // Number of angular positions to sample
|
||||
|
||||
/**
|
||||
* Draws analog stick position on a canvas with various visualization options.
|
||||
* @param {CanvasRenderingContext2D} ctx - Canvas rendering context
|
||||
* @param {number} center_x - X coordinate of stick center
|
||||
* @param {number} center_y - Y coordinate of stick center
|
||||
* @param {number} sz - Size/radius of the stick area
|
||||
* @param {number} stick_x - Current stick X position (-1 to 1)
|
||||
* @param {number} stick_y - Current stick Y position (-1 to 1)
|
||||
* @param {Object} opts - Options object
|
||||
* @param {number[]|null} opts.circularity_data - Array of circularity test data
|
||||
* @param {boolean} opts.enable_zoom_center - Whether to apply center zoom transformation
|
||||
* @param {boolean} opts.highlight - Whether to highlight the stick position
|
||||
*/
|
||||
export function draw_stick_position(ctx, center_x, center_y, sz, stick_x, stick_y, opts = {}) {
|
||||
const { circularity_data = null, enable_zoom_center = false, highlight } = opts;
|
||||
|
||||
// Draw base circle
|
||||
ctx.lineWidth = 1;
|
||||
ctx.fillStyle = '#ffffff';
|
||||
ctx.strokeStyle = '#000000';
|
||||
ctx.beginPath();
|
||||
ctx.arc(center_x, center_y, sz, 0, 2 * Math.PI);
|
||||
ctx.closePath();
|
||||
ctx.fill();
|
||||
ctx.stroke();
|
||||
|
||||
// Helper function for circularity visualization color
|
||||
function cc_to_color(cc) {
|
||||
const dd = Math.sqrt(Math.pow((1.0 - cc), 2));
|
||||
let hh;
|
||||
if(cc <= 1.0)
|
||||
hh = 220 - 220 * Math.min(1.0, Math.max(0, (dd - 0.05)) / 0.1);
|
||||
else
|
||||
hh = (245 + (360-245) * Math.min(1.0, Math.max(0, (dd - 0.05)) / 0.15)) % 360;
|
||||
return hh;
|
||||
}
|
||||
|
||||
// Draw circularity visualization if data provided
|
||||
if (circularity_data?.length > 0) {
|
||||
const MAX_N = CIRCULARITY_DATA_SIZE;
|
||||
|
||||
for(let i = 0; i < MAX_N; i++) {
|
||||
const kd = circularity_data[i];
|
||||
const kd1 = circularity_data[(i+1) % CIRCULARITY_DATA_SIZE];
|
||||
if (kd === undefined || kd1 === undefined) continue;
|
||||
const ka = i * Math.PI * 2 / MAX_N;
|
||||
const ka1 = ((i+1)%MAX_N) * 2 * Math.PI / MAX_N;
|
||||
|
||||
const kx = Math.cos(ka) * kd;
|
||||
const ky = Math.sin(ka) * kd;
|
||||
const kx1 = Math.cos(ka1) * kd1;
|
||||
const ky1 = Math.sin(ka1) * kd1;
|
||||
|
||||
ctx.beginPath();
|
||||
ctx.moveTo(center_x, center_y);
|
||||
ctx.lineTo(center_x+kx*sz, center_y+ky*sz);
|
||||
ctx.lineTo(center_x+kx1*sz, center_y+ky1*sz);
|
||||
ctx.lineTo(center_x, center_y);
|
||||
ctx.closePath();
|
||||
|
||||
const cc = (kd + kd1) / 2;
|
||||
const hh = cc_to_color(cc);
|
||||
ctx.fillStyle = 'hsla(' + parseInt(hh) + ', 100%, 50%, 0.5)';
|
||||
ctx.fill();
|
||||
}
|
||||
}
|
||||
|
||||
// Draw circularity error text if enough data provided
|
||||
if (circularity_data?.filter(n => n > 0.3).length > 10) {
|
||||
const circularityError = calculateCircularityError(circularity_data);
|
||||
|
||||
ctx.fillStyle = '#fff';
|
||||
ctx.strokeStyle = '#444';
|
||||
ctx.lineWidth = 3;
|
||||
ctx.textAlign = 'center';
|
||||
ctx.textBaseline = 'middle';
|
||||
|
||||
ctx.font = '24px Arial';
|
||||
const text_y = center_y + sz * 0.5;
|
||||
const text = `${circularityError.toFixed(1)} %`;
|
||||
|
||||
ctx.strokeText(text, center_x, text_y);
|
||||
ctx.fillText(text, center_x, text_y);
|
||||
}
|
||||
|
||||
// Draw crosshairs
|
||||
ctx.strokeStyle = '#aaaaaa';
|
||||
ctx.lineWidth = 1;
|
||||
ctx.beginPath();
|
||||
ctx.moveTo(center_x-sz, center_y);
|
||||
ctx.lineTo(center_x+sz, center_y);
|
||||
ctx.closePath();
|
||||
ctx.stroke();
|
||||
|
||||
ctx.beginPath();
|
||||
ctx.moveTo(center_x, center_y-sz);
|
||||
ctx.lineTo(center_x, center_y+sz);
|
||||
ctx.closePath();
|
||||
ctx.stroke();
|
||||
|
||||
// Apply center zoom transformation if enabled
|
||||
let display_x = stick_x;
|
||||
let display_y = stick_y;
|
||||
if (enable_zoom_center) {
|
||||
const transformed = apply_center_zoom(stick_x, stick_y);
|
||||
display_x = transformed.x;
|
||||
display_y = transformed.y;
|
||||
|
||||
// Draw light gray circle at 50% radius to show border of zoomed center
|
||||
ctx.strokeStyle = '#d3d3d3'; // light gray
|
||||
ctx.lineWidth = 1;
|
||||
ctx.beginPath();
|
||||
ctx.arc(center_x, center_y, sz * 0.5, 0, 2 * Math.PI);
|
||||
ctx.stroke();
|
||||
}
|
||||
|
||||
ctx.fillStyle = '#000000';
|
||||
ctx.strokeStyle = '#000000';
|
||||
|
||||
// Draw stick line with variable thickness
|
||||
// Calculate distance from center
|
||||
const stick_distance = Math.sqrt(display_x*display_x + display_y*display_y);
|
||||
const boundary_radius = 0.5; // 50% radius
|
||||
|
||||
// Determine if we need to draw a two-segment line
|
||||
const use_two_segments = enable_zoom_center && stick_distance > boundary_radius;
|
||||
if (use_two_segments) {
|
||||
// Calculate boundary point
|
||||
const boundary_x = (display_x / stick_distance) * boundary_radius;
|
||||
const boundary_y = (display_y / stick_distance) * boundary_radius;
|
||||
|
||||
// First segment: thicker line from center to boundary
|
||||
ctx.lineWidth = 3;
|
||||
ctx.beginPath();
|
||||
ctx.moveTo(center_x, center_y);
|
||||
ctx.lineTo(center_x + boundary_x*sz, center_y + boundary_y*sz);
|
||||
ctx.stroke();
|
||||
|
||||
// Second segment: thinner line from boundary to stick position
|
||||
ctx.lineWidth = 1;
|
||||
ctx.beginPath();
|
||||
ctx.moveTo(center_x + boundary_x*sz, center_y + boundary_y*sz);
|
||||
ctx.lineTo(center_x + display_x*sz, center_y + display_y*sz);
|
||||
ctx.stroke();
|
||||
} else {
|
||||
// Single line from center to stick position
|
||||
ctx.lineWidth = enable_zoom_center ? 3 : 1;
|
||||
ctx.beginPath();
|
||||
ctx.moveTo(center_x, center_y);
|
||||
ctx.lineTo(center_x + display_x*sz, center_y + display_y*sz);
|
||||
ctx.stroke();
|
||||
}
|
||||
|
||||
// Draw filled circle at stick position
|
||||
ctx.beginPath();
|
||||
ctx.arc(center_x+display_x*sz, center_y+display_y*sz, 3, 0, 2*Math.PI);
|
||||
|
||||
if (typeof highlight === 'boolean') {
|
||||
ctx.fillStyle = highlight ? '#2989f7ff' : '#030b84ff';
|
||||
}
|
||||
ctx.fill();
|
||||
}
|
||||
|
||||
/**
|
||||
* Calculates circularity error for stick movement data.
|
||||
* @param {number[]} data - Array of distance values at different angular positions
|
||||
* @returns {number} RMS deviation as percentage
|
||||
*/
|
||||
function calculateCircularityError(data) {
|
||||
// Sum of squared deviations from ideal distance of 1.0, only for values > 0.2
|
||||
const sumSquaredDeviations = data.reduce((acc, val) =>
|
||||
val > 0.2 ? acc + Math.pow(val - 1, 2) : acc, 0);
|
||||
|
||||
// Calculate RMS deviation as percentage
|
||||
const validDataCount = data.filter(val => val > 0.2).length;
|
||||
return validDataCount > 0 ? Math.sqrt(sumSquaredDeviations / validDataCount) * 100 : 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Applies center zoom transformation to stick coordinates.
|
||||
* @param {number} x - X coordinate
|
||||
* @param {number} y - Y coordinate
|
||||
* @returns {Object} Transformed coordinates {x, y}
|
||||
*/
|
||||
function apply_center_zoom(x, y) {
|
||||
// Calculate distance from center
|
||||
const distance = Math.sqrt(x * x + y * y);
|
||||
|
||||
// If distance is 0, return original values
|
||||
if (distance === 0) {
|
||||
return { x, y};
|
||||
}
|
||||
|
||||
// Calculate angle
|
||||
const angle = Math.atan2(y, x);
|
||||
|
||||
// Apply center zoom transformation
|
||||
const new_distance =
|
||||
distance <= 0.05
|
||||
? (distance / 0.05) * 0.5 // 0 to 0.05 maps to 0 to 0.5 (half the radius)
|
||||
: 0.5 + ((distance - 0.05) / 0.95) * 0.5 // 0.05 to 1.0 maps to 0.5 to 1.0 (other half)
|
||||
|
||||
// Convert back to x, y coordinates
|
||||
return {
|
||||
x: Math.cos(angle) * new_distance,
|
||||
y: Math.sin(angle) * new_distance
|
||||
};
|
||||
}
|
||||
91
js/template-loader.js
Normal file
91
js/template-loader.js
Normal file
@@ -0,0 +1,91 @@
|
||||
'use strict';
|
||||
|
||||
// Cache for loaded templates
|
||||
const templateCache = new Map();
|
||||
|
||||
/**
|
||||
* Load a template from the templates directory or bundled assets
|
||||
* @param {string} templateName - Name of the template file without extension
|
||||
* @returns {Promise<string>} - Promise that resolves with the template HTML
|
||||
*/
|
||||
async function loadTemplate(templateName) {
|
||||
// Check if template is already in cache
|
||||
if (templateCache.has(templateName)) {
|
||||
return templateCache.get(templateName);
|
||||
}
|
||||
|
||||
// Check if we have bundled assets (production mode)
|
||||
if (window.BUNDLED_ASSETS && window.BUNDLED_ASSETS.templates) {
|
||||
const templateHtml = window.BUNDLED_ASSETS.templates[templateName];
|
||||
if (templateHtml) {
|
||||
templateCache.set(templateName, templateHtml);
|
||||
return templateHtml;
|
||||
}
|
||||
}
|
||||
|
||||
// Fallback to fetching from server (development mode)
|
||||
// Only append .html if the templateName doesn't already have an extension
|
||||
const hasExtension = templateName.includes('.');
|
||||
const templatePath = hasExtension ? `templates/${templateName}` : `templates/${templateName}.html`;
|
||||
|
||||
const response = await fetch(templatePath);
|
||||
if (!response.ok) {
|
||||
throw new Error(`Failed to load template: ${templateName}`);
|
||||
}
|
||||
|
||||
const templateHtml = await response.text();
|
||||
templateCache.set(templateName, templateHtml);
|
||||
return templateHtml;
|
||||
}
|
||||
|
||||
/**
|
||||
* Load SVG assets from bundled assets or server
|
||||
* @param {string} assetPath - Path to the SVG asset
|
||||
* @returns {Promise<string>} - Promise that resolves with the SVG content
|
||||
*/
|
||||
async function loadSvgAsset(assetPath) {
|
||||
// Check if we have bundled assets (production mode)
|
||||
if (window.BUNDLED_ASSETS && window.BUNDLED_ASSETS.svg) {
|
||||
const svgContent = window.BUNDLED_ASSETS.svg[assetPath];
|
||||
if (svgContent) {
|
||||
return svgContent;
|
||||
}
|
||||
}
|
||||
|
||||
// Fallback to fetching from server (development mode)
|
||||
const response = await fetch(`assets/${assetPath}`);
|
||||
if (!response.ok) {
|
||||
throw new Error(`Failed to load SVG asset: ${assetPath}`);
|
||||
}
|
||||
|
||||
return await response.text();
|
||||
}
|
||||
|
||||
/**
|
||||
* Load all templates and insert them into the DOM
|
||||
*/
|
||||
export async function loadAllTemplates() {
|
||||
// Load SVG icons
|
||||
const iconsHtml = await loadSvgAsset('icons.svg');
|
||||
const iconsContainer = document.createElement('div');
|
||||
iconsContainer.innerHTML = iconsHtml;
|
||||
document.body.prepend(iconsContainer);
|
||||
|
||||
// Load modals
|
||||
const faqModalHtml = await loadTemplate('faq-modal');
|
||||
const popupModalHtml = await loadTemplate('popup-modal');
|
||||
const finetuneModalHtml = await loadTemplate('finetune-modal');
|
||||
const calibCenterModalHtml = await loadTemplate('calib-center-modal');
|
||||
const welcomeModalHtml = await loadTemplate('welcome-modal');
|
||||
const calibrateModalHtml = await loadTemplate('calibrate-modal');
|
||||
const rangeModalHtml = await loadTemplate('range-modal');
|
||||
const edgeProgressModalHtml = await loadTemplate('edge-progress-modal');
|
||||
const edgeModalHtml = await loadTemplate('edge-modal');
|
||||
const donateModalHtml = await loadTemplate('donate-modal');
|
||||
|
||||
// Create modals container
|
||||
const modalsContainer = document.createElement('div');
|
||||
modalsContainer.id = 'modals-container';
|
||||
modalsContainer.innerHTML = faqModalHtml + popupModalHtml + finetuneModalHtml + calibCenterModalHtml + welcomeModalHtml + calibrateModalHtml + rangeModalHtml + edgeProgressModalHtml + edgeModalHtml + donateModalHtml;
|
||||
document.body.appendChild(modalsContainer);
|
||||
}
|
||||
191
js/translations.js
Normal file
191
js/translations.js
Normal file
@@ -0,0 +1,191 @@
|
||||
'use strict';
|
||||
|
||||
import { la, createCookie, readCookie } from './utils.js';
|
||||
|
||||
// Alphabetical order
|
||||
const available_langs = {
|
||||
"ar_ar": { "name": "العربية", "file": "ar_ar.json", "direction": "rtl"},
|
||||
"bg_bg": { "name": "Български", "file": "bg_bg.json", "direction": "ltr"},
|
||||
"cz_cz": { "name": "Čeština", "file": "cz_cz.json", "direction": "ltr"},
|
||||
"da_dk": { "name": "Dansk", "file": "da_dk.json", "direction": "ltr"},
|
||||
"de_de": { "name": "Deutsch", "file": "de_de.json", "direction": "ltr"},
|
||||
"es_es": { "name": "Español", "file": "es_es.json", "direction": "ltr"},
|
||||
"fr_fr": { "name": "Français", "file": "fr_fr.json", "direction": "ltr"},
|
||||
"hu_hu": { "name": "Magyar", "file": "hu_hu.json", "direction": "ltr"},
|
||||
"it_it": { "name": "Italiano", "file": "it_it.json", "direction": "ltr"},
|
||||
"jp_jp": { "name": "日本語", "file": "jp_jp.json", "direction": "ltr"},
|
||||
"ko_kr": { "name": "한국어", "file": "ko_kr.json", "direction": "ltr"},
|
||||
"nl_nl": { "name": "Nederlands", "file": "nl_nl.json", "direction": "ltr"},
|
||||
"pl_pl": { "name": "Polski", "file": "pl_pl.json", "direction": "ltr"},
|
||||
"pt_br": { "name": "Português do Brasil", "file": "pt_br.json", "direction": "ltr"},
|
||||
"pt_pt": { "name": "Português", "file": "pt_pt.json", "direction": "ltr"},
|
||||
"rs_rs": { "name": "Srpski", "file": "rs_rs.json", "direction": "ltr"},
|
||||
"ru_ru": { "name": "Русский", "file": "ru_ru.json", "direction": "ltr"},
|
||||
"tr_tr": { "name": "Türkçe", "file": "tr_tr.json", "direction": "ltr"},
|
||||
"ua_ua": { "name": "Українська", "file": "ua_ua.json", "direction": "ltr"},
|
||||
"zh_cn": { "name": "中文", "file": "zh_cn.json", "direction": "ltr"},
|
||||
"zh_tw": { "name": "中文(繁)", "file": "zh_tw.json", "direction": "ltr"}
|
||||
};
|
||||
|
||||
// Translation state - will be imported from core.js app object
|
||||
let translationState = null;
|
||||
let welcomeModal = null;
|
||||
let handleLanguageChange = null;
|
||||
|
||||
export function lang_init(appState, handleLanguageChangeCb, welcomeModalCb) {
|
||||
translationState = appState;
|
||||
handleLanguageChange = handleLanguageChangeCb;
|
||||
welcomeModal = welcomeModalCb;
|
||||
|
||||
let id_iter = 0;
|
||||
const items = document.getElementsByClassName('ds-i18n');
|
||||
for(let item of items) {
|
||||
if (item.id.length == 0) {
|
||||
item.id = `ds-i18n-${id_iter++}`;
|
||||
}
|
||||
|
||||
translationState.lang_orig_text[item.id] = $(item).html();
|
||||
}
|
||||
translationState.lang_orig_text[".title"] = document.title;
|
||||
|
||||
const force_lang = readCookie("force_lang");
|
||||
if (force_lang != null) {
|
||||
lang_set(force_lang, true).catch(error => {
|
||||
console.error("Failed to set forced language:", error);
|
||||
});
|
||||
} else {
|
||||
const nlang = navigator.language.replace('-', '_').toLowerCase();
|
||||
const ljson = available_langs[nlang];
|
||||
if(ljson) {
|
||||
la("lang_init", {"l": nlang});
|
||||
lang_translate(ljson["file"], nlang, ljson["direction"]).catch(error => {
|
||||
console.error("Failed to load initial language:", error);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
const langs = Object.keys(available_langs);
|
||||
const olangs = [
|
||||
'<li><a class="dropdown-item" href="#" onclick="lang_set(\'en_us\');">English</a></li>',
|
||||
...langs.map(lang => {
|
||||
const name = available_langs[lang]["name"];
|
||||
return `<li><a class="dropdown-item" href="#" onclick="lang_set('${lang}');">${name}</a></li>`;
|
||||
}),
|
||||
'<li><hr class="dropdown-divider"></li>',
|
||||
'<li><a class="dropdown-item" href="https://github.com/dualshock-tools/dualshock-tools.github.io/blob/main/TRANSLATIONS.md" target="_blank">Missing your language?</a></li>'
|
||||
].join('');
|
||||
$("#availLangs").html(olangs);
|
||||
}
|
||||
|
||||
async function lang_set(lang, skip_modal=false) {
|
||||
la("lang_set", { l: lang });
|
||||
|
||||
lang_reset_page();
|
||||
if(lang != "en_us") {
|
||||
const { file, direction } = available_langs[lang];
|
||||
await lang_translate(file, lang, direction);
|
||||
}
|
||||
|
||||
await handleLanguageChange(lang);
|
||||
createCookie("force_lang", lang);
|
||||
if(!skip_modal && welcomeModal) {
|
||||
createCookie("welcome_accepted", "0");
|
||||
welcomeModal();
|
||||
}
|
||||
}
|
||||
|
||||
function lang_reset_page() {
|
||||
lang_set_direction("ltr", "en_us");
|
||||
|
||||
// Reset translation state to disable translations
|
||||
translationState.lang_cur = {};
|
||||
translationState.lang_disabled = true;
|
||||
|
||||
const { lang_orig_text } = translationState;
|
||||
const items = document.getElementsByClassName('ds-i18n');
|
||||
for(let item of items) {
|
||||
$(item).html(lang_orig_text[item.id]);
|
||||
};
|
||||
$("#authorMsg").html("");
|
||||
$("#curLang").html("English");
|
||||
document.title = lang_orig_text[".title"];
|
||||
}
|
||||
|
||||
function lang_set_direction(new_direction, lang_name) {
|
||||
const lang_prefix = lang_name.split("_")[0]
|
||||
$("html").attr("lang", lang_prefix);
|
||||
|
||||
if(new_direction == translationState.lang_cur_direction)
|
||||
return;
|
||||
|
||||
if(new_direction == "rtl") {
|
||||
$('#bootstrap-css').attr('integrity', 'sha384-dpuaG1suU0eT09tx5plTaGMLBsfDLzUCCUXOY2j/LSvXYuG6Bqs43ALlhIqAJVRb');
|
||||
$('#bootstrap-css').attr('href', 'https://cdn.jsdelivr.net/npm/bootstrap@5.3.3/dist/css/bootstrap.rtl.min.css');
|
||||
} else {
|
||||
$('#bootstrap-css').attr('integrity', 'sha384-QWTKZyjpPEjISv5WaRU9OFeRpok6YctnYmDr5pNlyT2bRjXh0JMhjY6hW+ALEwIH');
|
||||
$('#bootstrap-css').attr('href', 'https://cdn.jsdelivr.net/npm/bootstrap@5.3.3/dist/css/bootstrap.min.css');
|
||||
}
|
||||
$("html").attr("dir", new_direction);
|
||||
translationState.lang_cur_direction = new_direction;
|
||||
}
|
||||
|
||||
export function l(text) {
|
||||
if(!translationState || translationState.lang_disabled)
|
||||
return text;
|
||||
|
||||
const [out] = translationState.lang_cur[text] || [];
|
||||
if(out) return out;
|
||||
|
||||
console.log("Missing translation for: '" + text + "'");
|
||||
return text;
|
||||
}
|
||||
|
||||
function lang_translate(target_file, target_lang, target_direction) {
|
||||
return new Promise((resolve, reject) => {
|
||||
$.getJSON("lang/" + target_file)
|
||||
.done(function(data) {
|
||||
const { lang_orig_text, lang_cur } = translationState;
|
||||
lang_set_direction(target_direction, target_lang);
|
||||
|
||||
$.each(data, function( key, val ) {
|
||||
if(lang_cur[key]) {
|
||||
console.log("Warn: already exists " + key);
|
||||
} else {
|
||||
lang_cur[key] = [val];
|
||||
}
|
||||
});
|
||||
|
||||
if(Object.keys(lang_cur).length > 0) {
|
||||
translationState.lang_disabled = false;
|
||||
}
|
||||
|
||||
const items = document.getElementsByClassName('ds-i18n');
|
||||
for(let item of items) {
|
||||
const originalText = lang_orig_text[item.id];
|
||||
const [translatedText] = lang_cur[originalText] || [];
|
||||
if (translatedText) {
|
||||
$(item).html(translatedText);
|
||||
} else {
|
||||
console.log("Cannot find mapping for " + originalText);
|
||||
$(item).html(originalText);
|
||||
}
|
||||
}
|
||||
|
||||
const old_title = lang_orig_text[".title"];
|
||||
document.title = lang_cur[old_title];
|
||||
if(lang_cur[".authorMsg"]) {
|
||||
$("#authorMsg").html(lang_cur[".authorMsg"]);
|
||||
}
|
||||
$("#curLang").html(available_langs[target_lang]["name"]);
|
||||
|
||||
resolve();
|
||||
})
|
||||
.fail(function(jqxhr, textStatus, error) {
|
||||
console.error("Failed to load translation file:", target_file, error);
|
||||
reject(error);
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
// Make lang_set available globally for onclick handlers in HTML
|
||||
window.lang_set = lang_set;
|
||||
155
js/utils.js
Normal file
155
js/utils.js
Normal file
@@ -0,0 +1,155 @@
|
||||
'use strict';
|
||||
|
||||
/**
|
||||
* Utility functions for DualShock controller operations
|
||||
*/
|
||||
|
||||
/**
|
||||
* Sleep for specified milliseconds
|
||||
* @param {number} ms Milliseconds to sleep
|
||||
* @returns {Promise} Promise that resolves after the specified time
|
||||
*/
|
||||
export async function sleep(ms) {
|
||||
await new Promise(r => setTimeout(r, ms));
|
||||
}
|
||||
/**
|
||||
* Convert float to string with specified precision
|
||||
* @param {number} f Float number to convert
|
||||
* @param {number} precision Number of decimal places
|
||||
* @returns {string} Formatted string
|
||||
*/
|
||||
export function float_to_str(f, precision = 2) {
|
||||
if(precision <=2 && f < 0.004 && f >= -0.004) return "+0.00";
|
||||
return (f<0?"":"+") + f.toFixed(precision);
|
||||
}
|
||||
|
||||
/**
|
||||
* Convert buffer to hexadecimal string
|
||||
* @param {ArrayBuffer} buffer Buffer to convert
|
||||
* @returns {string} Hexadecimal string representation
|
||||
*/
|
||||
export function buf2hex(buffer) {
|
||||
return [...new Uint8Array(buffer)].map(x => x.toString(16).padStart(2, '0')).join('');
|
||||
}
|
||||
|
||||
/**
|
||||
* Convert decimal to 16-bit hexadecimal string
|
||||
* @param {number} i Decimal number
|
||||
* @returns {string} 4-character uppercase hex string
|
||||
*/
|
||||
export function dec2hex(i) {
|
||||
return (i + 0x10000).toString(16).substr(-4).toUpperCase();
|
||||
}
|
||||
|
||||
/**
|
||||
* Convert decimal to 32-bit hexadecimal string
|
||||
* @param {number} i Decimal number
|
||||
* @returns {string} 8-character uppercase hex string
|
||||
*/
|
||||
export function dec2hex32(i) {
|
||||
return (i + 0x100000000).toString(16).substr(-8).toUpperCase();
|
||||
}
|
||||
|
||||
/**
|
||||
* Convert decimal to 8-bit hexadecimal string
|
||||
* @param {number} i Decimal number
|
||||
* @returns {string} 2-character uppercase hex string
|
||||
*/
|
||||
export function dec2hex8(i) {
|
||||
return (i + 0x100).toString(16).substr(-2).toUpperCase();
|
||||
}
|
||||
|
||||
/**
|
||||
* Format MAC address from DataView
|
||||
* @returns {string} Formatted MAC address (XX:XX:XX:XX:XX:XX)
|
||||
*/
|
||||
export function format_mac_from_view(view, start_index_inclusive) {
|
||||
const bytes = [];
|
||||
for (let i = 0; i < 6; i++) {
|
||||
const idx = start_index_inclusive + (5 - i);
|
||||
bytes.push(dec2hex8(view.getUint8(idx, false)));
|
||||
}
|
||||
return bytes.join(":");
|
||||
}
|
||||
|
||||
/**
|
||||
* Reverse a string (for ASCII strings only, not UTF)
|
||||
* @param {string} s String to reverse
|
||||
* @returns {string} Reversed string
|
||||
*/
|
||||
export function reverse_str(s) {
|
||||
return s.split('').reverse().join('');
|
||||
}
|
||||
|
||||
export let la = undefined;
|
||||
export function lf(operation, data) { la(operation, buf2hex(data.buffer)); return data; }
|
||||
|
||||
export function initAnalyticsApi({gj, gu}) {
|
||||
la = (k, v = {}) => {
|
||||
$.ajax({
|
||||
type: 'POST',
|
||||
url: "https://the.al/ds4_a/l",
|
||||
data: JSON.stringify({u: gu, j: gj, k, v}),
|
||||
contentType: "application/json",
|
||||
dataType: 'json'
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
export function lerp_color(a, b, t) {
|
||||
// a, b: hex color strings, t: 0.0-1.0
|
||||
function hex2rgb(hex) {
|
||||
hex = hex.replace('#', '');
|
||||
if (hex.length === 3) hex = hex.split('').map(x => x + x).join('');
|
||||
const num = parseInt(hex, 16);
|
||||
return [(num >> 16) & 255, (num >> 8) & 255, num & 255];
|
||||
}
|
||||
function rgb2hex(r, g, b) {
|
||||
return '#' + [r, g, b].map(x => x.toString(16).padStart(2, '0')).join('');
|
||||
}
|
||||
const c1 = hex2rgb(a);
|
||||
const c2 = hex2rgb(b);
|
||||
const c = [
|
||||
Math.round(c1[0] + (c2[0] - c1[0]) * t),
|
||||
Math.round(c1[1] + (c2[1] - c1[1]) * t),
|
||||
Math.round(c1[2] + (c2[2] - c1[2]) * t)
|
||||
];
|
||||
return rgb2hex(c[0], c[1], c[2]);
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a cookie with specified name, value, and expiration days
|
||||
* @param {string} name Cookie name
|
||||
* @param {string} value Cookie value
|
||||
* @param {number} days Number of days until expiration
|
||||
*/
|
||||
export function createCookie(name, value, days) {
|
||||
const expires = days ? "; expires=" + new Date(Date.now() + days * 24 * 60 * 60 * 1000).toGMTString() : "";
|
||||
document.cookie = encodeURIComponent(name) + "=" + encodeURIComponent(value) + expires + "; path=/";
|
||||
}
|
||||
|
||||
/**
|
||||
* Read a cookie value by name
|
||||
* @param {string} name Cookie name
|
||||
* @returns {string|null} Cookie value or null if not found
|
||||
*/
|
||||
export function readCookie(name) {
|
||||
const nameEQ = encodeURIComponent(name) + "=";
|
||||
const ca = document.cookie.split(';');
|
||||
for (let i = 0; i < ca.length; i++) {
|
||||
let c = ca[i];
|
||||
while (c.charAt(0) === ' ')
|
||||
c = c.substring(1, c.length);
|
||||
if (c.indexOf(nameEQ) === 0)
|
||||
return decodeURIComponent(c.substring(nameEQ.length, c.length));
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Delete a cookie by setting its expiration to the past
|
||||
* @param {string} name Cookie name to delete
|
||||
*/
|
||||
export function eraseCookie(name) {
|
||||
createCookie(name, "", -1);
|
||||
}
|
||||
@@ -34,7 +34,7 @@
|
||||
"Please move both sticks to the <b>bottom-right corner</b> and release them.": "الرجاء حرك كلا العصي إلى <b>أسفل اليمين</b> وتركهما.",
|
||||
"Calibration completed successfully!": "انتهت المعايرة بنجاح!",
|
||||
"Next": "التالي",
|
||||
"Recentering the controller sticks. ": "إعادة تسجيل عصا وحدة التحكم. ",
|
||||
"Recentering the controller sticks.": "إعادة تسجيل عصا وحدة التحكم.",
|
||||
"Please do not close this window and do not disconnect your controller. ": "الرجاء عدم إغلاق هذه النافذة وعدم قطع اتصال يد التحكم. ",
|
||||
"Range calibration": "معايرة المدى",
|
||||
"<b>The controller is now sampling data!</b>": "<b>يد التحكم تقوم الآن بأخذ عينات من البيانات!</b>",
|
||||
@@ -58,16 +58,16 @@
|
||||
"SW Version": "إصدار البرمجيات",
|
||||
"Device Type": "نوع الجهاز",
|
||||
"Range calibration completed": "أكملت معايرة المدى",
|
||||
"Range calibration failed: ": "فشل في معايرة المدى،",
|
||||
"Range calibration failed": "فشل في معايرة المدى،",
|
||||
"Cannot unlock NVS": "لا يمكن فتح قفل NVS",
|
||||
"Cannot relock NVS": "لا يمكن إعادة قفل NVS",
|
||||
"Error 1": "خطأ 1",
|
||||
"Error 2": "خطأ 2",
|
||||
"Error 3": "خطأ 3",
|
||||
"Stick calibration failed: ": "فشل في معايرة العصا،",
|
||||
"Stick calibration failed": "فشل في معايرة العصا،",
|
||||
"Stick calibration completed": "أكملت معايرة العصا",
|
||||
"NVS Lock failed: ": "فشل في قفل NVS",
|
||||
"NVS Unlock failed: ": "فشل فتح قفل NVS",
|
||||
"NVS Lock failed": "فشل في قفل NVS",
|
||||
"NVS Unlock failed": "فشل فتح قفل NVS",
|
||||
"Please connect only one controller at time.": "الرجاء ربط يد تحكم واحدة فقط.",
|
||||
"Sony DualShock 4 V1": "Sony DualShock 4 الإصدار الأول",
|
||||
"Sony DualShock 4 V2": "Sony DualShock 4 الإصدار الثاني",
|
||||
@@ -136,12 +136,9 @@
|
||||
"This feature is experimental.": "هذه الخاصية تجريبية.",
|
||||
"Please let me know if the board model of your controller is not detected correctly.": "من فضلك أخبرني إذا لم يتم اكتشاف نوع لوحة التحكم بشكل صحيح.",
|
||||
"Board model detection thanks to": "كشف نوع اللوحة بفضل",
|
||||
"Please connect the device using a USB cable.": "يُرجى توصيل اليد باستخدام كابل USB.",
|
||||
"This DualSense controller has outdated firmware.": "يد تحكم DualSense هذه تستخدم برمجيات قديمة.",
|
||||
"Please update the firmware and try again.": "الرجاء حدث البرمجيات وحاول مرة أخرى.",
|
||||
"Joystick Info": "معلومات عصا التحكم",
|
||||
"Err R:": "نسبة خطأ اليمين:",
|
||||
"Err L:": "نسبة خطأ اليسار:",
|
||||
"Check circularity": "التحقق من الدوران",
|
||||
"Can I reset a permanent calibration to previous calibration?": "هل يمكنني إعادة تعيين معايرة دائمة إلى المعايرة السابقة؟",
|
||||
"No.": "لا.",
|
||||
@@ -159,7 +156,7 @@
|
||||
"Make sure to touch the edges of the joystick frame and rotate slowly, preferably in each direction - clockwise and anti-clockwise.": "تحقق من لمس حواف إطار عصا التحكم وتدويرها ببطء، ويفضل أن يكون ذلك في اتجاه عقارب الساعة وعلى عكس اتجاه عقرب الساعة.",
|
||||
"Only after you have done that, you click on \"Done\".": "فقط بعد أن تقوم بذلك، انقر فوق \"تم\".",
|
||||
"Changes saved successfully": "تم حفظ التغييرات بنجاح",
|
||||
"Error while saving changes:": "حدث خطأ أثناء حفظ التغييرات:",
|
||||
"Error while saving changes": "حدث خطأ أثناء حفظ التغييرات:",
|
||||
"Save changes permanently": "حفظ التغييرات بشكل دائم",
|
||||
"Reboot controller": "إعادة تشغيل عصا التحكم",
|
||||
"Controller Info": "معلومات عصا التحكم",
|
||||
@@ -187,52 +184,79 @@
|
||||
"Bluetooth Address": "عنوان البلوتوث",
|
||||
"Show all": "عرض الكل",
|
||||
"(beta)": "",
|
||||
"10x zoom": "",
|
||||
"30th Anniversary": "",
|
||||
"<b>Externally</b>: by applying +1.8V directly to the visible test point without opening the controller": "",
|
||||
"<b>Externally</b>: by applying +1.8V directly to the visible test point without opening the controller.": "",
|
||||
"<b>Internally</b>: by soldering a wire from a +1.8V source to the write-protect TP.": "",
|
||||
"Astro Bot": "",
|
||||
"Calibration": "",
|
||||
"Calibration is being stored in the stick modules.": "",
|
||||
"Cancel": "",
|
||||
"Cannot lock": "",
|
||||
"Cannot store data into": "",
|
||||
"Cannot unlock": "",
|
||||
"Center (L1)": "",
|
||||
"Center X": "",
|
||||
"Center Y": "",
|
||||
"Chroma Indigo": "",
|
||||
"Chroma Pearl": "",
|
||||
"Chroma Teal": "",
|
||||
"Circularity (R1)": "",
|
||||
"Cobalt Blue": "",
|
||||
"Color": "",
|
||||
"Color detection thanks to": "",
|
||||
"Cosmic Red": "",
|
||||
"Debug": "",
|
||||
"DualSense Edge Calibration": "",
|
||||
"Error triggering rumble": "",
|
||||
"Finetune stick calibration": "",
|
||||
"For more info or help, feel free to reach out on Discord.": "",
|
||||
"Fortnite": "",
|
||||
"Galactic Purple": "",
|
||||
"God of War Ragnarok": "",
|
||||
"Grey Camouflage": "",
|
||||
"I'm actively working on adding compatibility, the primary challenge lies in storing data into the stick modules.": "",
|
||||
"If the calibration is not stored permanently, please double-check the wirings of the hardware mod.": "",
|
||||
"If this tool has been helpful to you or you want to see DualSense Edge support arrive faster, please consider supporting the project with a": "",
|
||||
"Info": "",
|
||||
"Left Module Barcode": "",
|
||||
"Left stick": "",
|
||||
"Midnight Black": "",
|
||||
"More details and images": "",
|
||||
"Move the stick to select it for tuning, then without touching the stick use the D-pad buttons to adjust the center point. Flick it and adjust it again if it is off center or flickers.": "",
|
||||
"Normal": "",
|
||||
"Nova Pink": "",
|
||||
"Please connect a DualShock 4, a DualSense or DualSense Edge controller to your computer and press Connect.": "",
|
||||
"Please note: the stick modules on the DS Edge <b>cannot be calibrated via software alone</b>.To store a custom calibration on the stick's internal memory, a <b>hardware modification</b> is required.": "",
|
||||
"Please release the stick to center position before adjusting with D-pad buttons.": "",
|
||||
"Press L2 to test the strong (left) haptic motor": "",
|
||||
"Press R2 to test the weak (right) haptic motor": "",
|
||||
"Press the D-pad or face buttons in the direction you want the stick position to move.": "",
|
||||
"Push the stick straight up/down/left/right as far as possible.": "",
|
||||
"Right Module Barcode": "",
|
||||
"Right stick": "",
|
||||
"Save": "",
|
||||
"Show raw numbers": "",
|
||||
"Spider-Man 2": "",
|
||||
"Starlight Blue": "",
|
||||
"Sterling Silver": "",
|
||||
"Support for calibrating DualSense Edge stick modules is now available as an <b>experimental feature</b>.": "",
|
||||
"Test the Haptic Motors": "",
|
||||
"Tests": "",
|
||||
"Thank you for your generosity and support!": "",
|
||||
"The DualShock Calibration GUI does not currently support the DualSense Edge.": "",
|
||||
"The Last of Us": "",
|
||||
"The device is connected via Bluetooth. Disconnect and reconnect using a USB cable instead.": "",
|
||||
"The motor strength will match how hard you press the trigger": "",
|
||||
"This involves temporarily disabling write protection by applying <b>+1.8V</b> to a specific test point on each module.": "",
|
||||
"This is only for advanced users. If you're not sure what you're doing, please do not attempt it.": "",
|
||||
"This screen allows to finetune raw calibration data on your controller": "",
|
||||
"Volcanic Red": "",
|
||||
"We are not responsible for any damage caused by attempting this modification.": "",
|
||||
"While holding the stick to be adjusted straight up/down/left/right, <em>observe the highlighted value below the circle</em>, then use the D-pad buttons to adjust the value to ±0.99 (just below ±1.00).": "",
|
||||
"White": "",
|
||||
"You can do this in two ways:": "",
|
||||
"Your device might not be a genuine Sony controller. If it is not a clone then please report this issue.": "",
|
||||
"here": "",
|
||||
"left module": "",
|
||||
"right module": "",
|
||||
|
||||
@@ -32,7 +32,7 @@
|
||||
"Please move both sticks to the <b>bottom-right corner</b> and release them.": "Моля, преместете двата джойстика в <b>долния десен ъгъл</b> и ги освободете.",
|
||||
"Calibration completed successfully!": "Калибрацията завърши успешно!",
|
||||
"Next": "Следващо",
|
||||
"Recentering the controller sticks. ": "Повторно центриране на джойстиците на контролера. ",
|
||||
"Recentering the controller sticks.": "Повторно центриране на джойстиците на контролера.",
|
||||
"Please do not close this window and do not disconnect your controller. ": "Моля, не затваряйте този прозорец и не изключвайте контролера си. ",
|
||||
"Range calibration": "Калибриране на обхвата",
|
||||
"<b>The controller is now sampling data!</b>": "<b>Контролерът в момента примерява данни!</b>",
|
||||
@@ -56,16 +56,16 @@
|
||||
"SW Version": "Версия на софтуера",
|
||||
"Device Type": "Тип устройство",
|
||||
"Range calibration completed": "Калибрация на обхвата завършена",
|
||||
"Range calibration failed: ": "Калибрация на обхвата неуспешна: ",
|
||||
"Range calibration failed": "Калибрация на обхвата неуспешна",
|
||||
"Cannot unlock NVS": "Не може да се отключи NVS",
|
||||
"Cannot relock NVS": "Не може да се затвори NVS",
|
||||
"Error 1": "Грешка 1",
|
||||
"Error 2": "Грешка 2",
|
||||
"Error 3": "Грешка 3",
|
||||
"Stick calibration failed: ": "Калибрация на джойстиците неуспешна: ",
|
||||
"Stick calibration failed": "Калибрация на джойстиците неуспешна",
|
||||
"Stick calibration completed": "Калибрация на джойстиците завършена",
|
||||
"NVS Lock failed: ": "Заключване на NVS неуспешно: ",
|
||||
"NVS Unlock failed: ": "Отключване на NVS неуспешно: ",
|
||||
"NVS Lock failed": "Заключване на NVS неуспешно",
|
||||
"NVS Unlock failed": "Отключване на NVS неуспешно",
|
||||
"Please connect only one controller at time.": "Моля, свържете само един контролер по време на",
|
||||
"Sony DualShock 4 V1": "Sony DualShock 4 V1",
|
||||
"Sony DualShock 4 V2": "Sony DualShock 4 V2",
|
||||
@@ -134,12 +134,9 @@
|
||||
"This feature is experimental.": "Тази функция е експериментална.",
|
||||
"Please let me know if the board model of your controller is not detected correctly.": "Моля, уведомете ме, ако моделът на платката на вашия контролер не е разпознат правилно.",
|
||||
"Board model detection thanks to": "Разпознаване на модела на платката благодарение на",
|
||||
"Please connect the device using a USB cable.": "Моля, свържете устройството с USB кабел.",
|
||||
"This DualSense controller has outdated firmware.": "Този контролер DualSense има остарял фърмуер.",
|
||||
"Please update the firmware and try again.": "Моля, актуализирайте фърмуера и опитайте отново.",
|
||||
"Joystick Info": "Информация за джойстика",
|
||||
"Err R:": "Грешка Д:",
|
||||
"Err L:": "Грешка Л:",
|
||||
"Check circularity": "Проверка на кръговостта",
|
||||
"Can I reset a permanent calibration to previous calibration?": "Мога ли да върна постоянна калибровка към предишна калибровка?",
|
||||
"No.": "Не.",
|
||||
@@ -157,31 +154,40 @@
|
||||
"Make sure to touch the edges of the joystick frame and rotate slowly, preferably in each direction - clockwise and anti-clockwise.": "Убедете се, че докосвате краищата на рамката на джойстика и завъртате бавно, предпочитано в двете посоки - по часовниковата стрелка и обратно на часовниковата стрелка.",
|
||||
"Only after you have done that, you click on \"Done\".": "Само след като сте направили това, натиснете \"Готово\".",
|
||||
"Changes saved successfully": "Промените са запазени успешно",
|
||||
"Error while saving changes:": "Грешка при запазване на промените:",
|
||||
"Error while saving changes": "Грешка при запазване на промените:",
|
||||
"Save changes permanently": "Запазете промените постоянно",
|
||||
"Reboot controller": "Рестартирайте контролера",
|
||||
"(beta)": "",
|
||||
"10x zoom": "",
|
||||
"30th Anniversary": "",
|
||||
"<b>Externally</b>: by applying +1.8V directly to the visible test point without opening the controller": "",
|
||||
"<b>Externally</b>: by applying +1.8V directly to the visible test point without opening the controller.": "",
|
||||
"<b>Internally</b>: by soldering a wire from a +1.8V source to the write-protect TP.": "",
|
||||
"Astro Bot": "",
|
||||
"Battery Barcode": "",
|
||||
"Bluetooth Address": "",
|
||||
"Calibration": "",
|
||||
"Calibration is being stored in the stick modules.": "",
|
||||
"Cancel": "",
|
||||
"Cannot lock": "",
|
||||
"Cannot store data into": "",
|
||||
"Cannot unlock": "",
|
||||
"Center (L1)": "",
|
||||
"Center X": "",
|
||||
"Center Y": "",
|
||||
"Chroma Indigo": "",
|
||||
"Chroma Pearl": "",
|
||||
"Chroma Teal": "",
|
||||
"Circularity (R1)": "",
|
||||
"Cobalt Blue": "",
|
||||
"Color": "",
|
||||
"Color detection thanks to": "",
|
||||
"Controller Info": "",
|
||||
"Cosmic Red": "",
|
||||
"Debug": "",
|
||||
"Debug Info": "",
|
||||
"Debug buttons": "",
|
||||
"DualSense Edge Calibration": "",
|
||||
"Error triggering rumble": "",
|
||||
"FW Build Date": "",
|
||||
"FW Series": "",
|
||||
"FW Type": "",
|
||||
@@ -190,6 +196,7 @@
|
||||
"FW Version": "",
|
||||
"Finetune stick calibration": "",
|
||||
"For more info or help, feel free to reach out on Discord.": "",
|
||||
"Fortnite": "",
|
||||
"Galactic Purple": "",
|
||||
"God of War Ragnarok": "",
|
||||
"Grey Camouflage": "",
|
||||
@@ -198,28 +205,43 @@
|
||||
"I'm actively working on adding compatibility, the primary challenge lies in storing data into the stick modules.": "",
|
||||
"If the calibration is not stored permanently, please double-check the wirings of the hardware mod.": "",
|
||||
"If this tool has been helpful to you or you want to see DualSense Edge support arrive faster, please consider supporting the project with a": "",
|
||||
"Info": "",
|
||||
"Left Module Barcode": "",
|
||||
"Left stick": "",
|
||||
"MCU Unique ID": "",
|
||||
"Midnight Black": "",
|
||||
"More details and images": "",
|
||||
"Move the stick to select it for tuning, then without touching the stick use the D-pad buttons to adjust the center point. Flick it and adjust it again if it is off center or flickers.": "",
|
||||
"Normal": "",
|
||||
"Nova Pink": "",
|
||||
"PCBA ID": "",
|
||||
"Please connect a DualShock 4, a DualSense or DualSense Edge controller to your computer and press Connect.": "",
|
||||
"Please note: the stick modules on the DS Edge <b>cannot be calibrated via software alone</b>.To store a custom calibration on the stick's internal memory, a <b>hardware modification</b> is required.": "",
|
||||
"Please release the stick to center position before adjusting with D-pad buttons.": "",
|
||||
"Press L2 to test the strong (left) haptic motor": "",
|
||||
"Press R2 to test the weak (right) haptic motor": "",
|
||||
"Press the D-pad or face buttons in the direction you want the stick position to move.": "",
|
||||
"Push the stick straight up/down/left/right as far as possible.": "",
|
||||
"Right Module Barcode": "",
|
||||
"Right stick": "",
|
||||
"SBL FW Version": "",
|
||||
"Save": "",
|
||||
"Serial Number": "",
|
||||
"Show all": "",
|
||||
"Show raw numbers": "",
|
||||
"Software": "",
|
||||
"Spider FW Version": "",
|
||||
"Spider-Man 2": "",
|
||||
"Starlight Blue": "",
|
||||
"Sterling Silver": "",
|
||||
"Support for calibrating DualSense Edge stick modules is now available as an <b>experimental feature</b>.": "",
|
||||
"Test the Haptic Motors": "",
|
||||
"Tests": "",
|
||||
"Thank you for your generosity and support!": "",
|
||||
"The DualShock Calibration GUI does not currently support the DualSense Edge.": "",
|
||||
"The Last of Us": "",
|
||||
"The device is connected via Bluetooth. Disconnect and reconnect using a USB cable instead.": "",
|
||||
"The motor strength will match how hard you press the trigger": "",
|
||||
"This involves temporarily disabling write protection by applying <b>+1.8V</b> to a specific test point on each module.": "",
|
||||
"This is only for advanced users. If you're not sure what you're doing, please do not attempt it.": "",
|
||||
"This screen allows to finetune raw calibration data on your controller": "",
|
||||
@@ -230,8 +252,10 @@
|
||||
"Venom FW Version": "",
|
||||
"Volcanic Red": "",
|
||||
"We are not responsible for any damage caused by attempting this modification.": "",
|
||||
"While holding the stick to be adjusted straight up/down/left/right, <em>observe the highlighted value below the circle</em>, then use the D-pad buttons to adjust the value to ±0.99 (just below ±1.00).": "",
|
||||
"White": "",
|
||||
"You can do this in two ways:": "",
|
||||
"Your device might not be a genuine Sony controller. If it is not a clone then please report this issue.": "",
|
||||
"here": "",
|
||||
"left module": "",
|
||||
"right module": "",
|
||||
|
||||
@@ -32,7 +32,7 @@
|
||||
"Please move both sticks to the <b>bottom-right corner</b> and release them.": "Přesuňte prosím obě páčky do <b>pravého dolního rohu</b> a uvolněte je.",
|
||||
"Calibration completed successfully!": "KKalibrace úspěšně dokončena!",
|
||||
"Next": "Další",
|
||||
"Recentering the controller sticks. ": "Vycentrování páček. ",
|
||||
"Recentering the controller sticks.": "Vycentrování páček.",
|
||||
"Please do not close this window and do not disconnect your controller. ": "Nezavírejte toto okno a neodpojujte ovladač. ",
|
||||
"Range calibration": "Kalibrace rozsahu",
|
||||
"<b>The controller is now sampling data!</b>": "<b>Regulátor nyní vzorkuje data!</b>",
|
||||
@@ -56,16 +56,16 @@
|
||||
"SW Version": "Verze SW",
|
||||
"Device Type": "Typ zařízení",
|
||||
"Range calibration completed": "Kalibrace rozsahu dokončena",
|
||||
"Range calibration failed: ": "Kalibrace rozsahu se nezdařila: ",
|
||||
"Range calibration failed": "Kalibrace rozsahu se nezdařila",
|
||||
"Cannot unlock NVS": "Nelze odemknout NVS",
|
||||
"Cannot relock NVS": "Nelze znovu zamknout NVS",
|
||||
"Error 1": "Chyba 1",
|
||||
"Error 2": "Chyba 2",
|
||||
"Error 3": "Chyba 3",
|
||||
"Stick calibration failed: ": "Kalibrace páček se nezdařila: ",
|
||||
"Stick calibration failed": "Kalibrace páček se nezdařila",
|
||||
"Stick calibration completed": "Kalibrace páček dokončena",
|
||||
"NVS Lock failed: ": "Zámek NVS se nezdařil: ",
|
||||
"NVS Unlock failed: ": "Odemknutí NVS se nezdařilo: ",
|
||||
"NVS Lock failed": "Zámek NVS se nezdařil",
|
||||
"NVS Unlock failed": "Odemknutí NVS se nezdařilo",
|
||||
"Please connect only one controller at time.": "Připojte vždy pouze jeden ovladač.",
|
||||
"Sony DualShock 4 V1": "Sony DualShock 4 V1",
|
||||
"Sony DualShock 4 V2": "Sony DualShock 4 V2",
|
||||
@@ -134,22 +134,21 @@
|
||||
"This feature is experimental.": "Tato funkce je experimentální.",
|
||||
"Please let me know if the board model of your controller is not detected correctly.": "Prosím, dejte mi vědět, pokud model základní desky vašeho ovládače není správně detekován",
|
||||
"Board model detection thanks to": "díky za detekci modelu základní desky",
|
||||
"Please connect the device using a USB cable.": "Připojte zařízení pomocí kabelu USB.",
|
||||
"This DualSense controller has outdated firmware.": "Tento ovladač DualSense má zastaralý firmware.",
|
||||
"Please update the firmware and try again.": "Aktualizujte firmware a zkuste to znovu.",
|
||||
"Joystick Info": "Informace o joysticku",
|
||||
"Err R:": "Chyba R",
|
||||
"Err L:": "Chyba L",
|
||||
"Check circularity": "Zkontrolujte rozsah",
|
||||
"(Dualsense) Will updating the firmware reset calibration?": "",
|
||||
"(beta)": "",
|
||||
"10x zoom": "",
|
||||
"30th Anniversary": "",
|
||||
"<b>Externally</b>: by applying +1.8V directly to the visible test point without opening the controller": "",
|
||||
"<b>Externally</b>: by applying +1.8V directly to the visible test point without opening the controller.": "",
|
||||
"<b>Internally</b>: by soldering a wire from a +1.8V source to the write-protect TP.": "",
|
||||
"After range calibration, joysticks always go in corners.": "",
|
||||
"Astro Bot": "",
|
||||
"Battery Barcode": "",
|
||||
"Bluetooth Address": "",
|
||||
"Calibration": "",
|
||||
"Calibration is being stored in the stick modules.": "",
|
||||
"Can I reset a permanent calibration to previous calibration?": "",
|
||||
"Can you overwrite a permanent calibration?": "",
|
||||
@@ -157,19 +156,26 @@
|
||||
"Cannot lock": "",
|
||||
"Cannot store data into": "",
|
||||
"Cannot unlock": "",
|
||||
"Center (L1)": "",
|
||||
"Center X": "",
|
||||
"Center Y": "",
|
||||
"Changes saved successfully": "",
|
||||
"Chroma Indigo": "",
|
||||
"Chroma Pearl": "",
|
||||
"Chroma Teal": "",
|
||||
"Circularity (R1)": "",
|
||||
"Cobalt Blue": "",
|
||||
"Color": "",
|
||||
"Color detection thanks to": "",
|
||||
"Controller Info": "",
|
||||
"Cosmic Red": "",
|
||||
"Debug": "",
|
||||
"Debug Info": "",
|
||||
"Debug buttons": "",
|
||||
"Does this software resolve stickdrift?": "",
|
||||
"DualSense Edge Calibration": "",
|
||||
"Error while saving changes:": "",
|
||||
"Error triggering rumble": "",
|
||||
"Error while saving changes": "",
|
||||
"FW Build Date": "",
|
||||
"FW Series": "",
|
||||
"FW Type": "",
|
||||
@@ -178,6 +184,7 @@
|
||||
"FW Version": "",
|
||||
"Finetune stick calibration": "",
|
||||
"For more info or help, feel free to reach out on Discord.": "",
|
||||
"Fortnite": "",
|
||||
"Galactic Purple": "",
|
||||
"God of War Ragnarok": "",
|
||||
"Grey Camouflage": "",
|
||||
@@ -187,19 +194,27 @@
|
||||
"I'm actively working on adding compatibility, the primary challenge lies in storing data into the stick modules.": "",
|
||||
"If the calibration is not stored permanently, please double-check the wirings of the hardware mod.": "",
|
||||
"If this tool has been helpful to you or you want to see DualSense Edge support arrive faster, please consider supporting the project with a": "",
|
||||
"Info": "",
|
||||
"Left Module Barcode": "",
|
||||
"Left stick": "",
|
||||
"MCU Unique ID": "",
|
||||
"Make sure to touch the edges of the joystick frame and rotate slowly, preferably in each direction - clockwise and anti-clockwise.": "",
|
||||
"Midnight Black": "",
|
||||
"More details and images": "",
|
||||
"Move the stick to select it for tuning, then without touching the stick use the D-pad buttons to adjust the center point. Flick it and adjust it again if it is off center or flickers.": "",
|
||||
"No.": "",
|
||||
"Normal": "",
|
||||
"Nova Pink": "",
|
||||
"Only after you have done that, you click on \"Done\".": "",
|
||||
"PCBA ID": "",
|
||||
"Please connect a DualShock 4, a DualSense or DualSense Edge controller to your computer and press Connect.": "",
|
||||
"Please note: the stick modules on the DS Edge <b>cannot be calibrated via software alone</b>.To store a custom calibration on the stick's internal memory, a <b>hardware modification</b> is required.": "",
|
||||
"Please read the instructions.": "",
|
||||
"Please release the stick to center position before adjusting with D-pad buttons.": "",
|
||||
"Press L2 to test the strong (left) haptic motor": "",
|
||||
"Press R2 to test the weak (right) haptic motor": "",
|
||||
"Press the D-pad or face buttons in the direction you want the stick position to move.": "",
|
||||
"Push the stick straight up/down/left/right as far as possible.": "",
|
||||
"Reboot controller": "",
|
||||
"Right Module Barcode": "",
|
||||
"Right stick": "",
|
||||
@@ -208,14 +223,21 @@
|
||||
"Save changes permanently": "",
|
||||
"Serial Number": "",
|
||||
"Show all": "",
|
||||
"Show raw numbers": "",
|
||||
"Software": "",
|
||||
"Spider FW Version": "",
|
||||
"Spider-Man 2": "",
|
||||
"Starlight Blue": "",
|
||||
"Sterling Silver": "",
|
||||
"Stickdrift is caused by a physical defect; namely dirt, worn potentiometer or in some cases a worn spring.": "",
|
||||
"Support for calibrating DualSense Edge stick modules is now available as an <b>experimental feature</b>.": "",
|
||||
"Test the Haptic Motors": "",
|
||||
"Tests": "",
|
||||
"Thank you for your generosity and support!": "",
|
||||
"The DualShock Calibration GUI does not currently support the DualSense Edge.": "",
|
||||
"The Last of Us": "",
|
||||
"The device is connected via Bluetooth. Disconnect and reconnect using a USB cable instead.": "",
|
||||
"The motor strength will match how hard you press the trigger": "",
|
||||
"This involves temporarily disabling write protection by applying <b>+1.8V</b> to a specific test point on each module.": "",
|
||||
"This is only for advanced users. If you're not sure what you're doing, please do not attempt it.": "",
|
||||
"This issue happens because you have clicked \"Done\" immediately after starting a range calibration.": "",
|
||||
@@ -228,10 +250,12 @@
|
||||
"Venom FW Version": "",
|
||||
"Volcanic Red": "",
|
||||
"We are not responsible for any damage caused by attempting this modification.": "",
|
||||
"While holding the stick to be adjusted straight up/down/left/right, <em>observe the highlighted value below the circle</em>, then use the D-pad buttons to adjust the value to ±0.99 (just below ±1.00).": "",
|
||||
"White": "",
|
||||
"Yes. Simply do another permanent calibration.": "",
|
||||
"You can do this in two ways:": "",
|
||||
"You have to rotate the joysticks before you press \"Done\".": "",
|
||||
"Your device might not be a genuine Sony controller. If it is not a clone then please report this issue.": "",
|
||||
"here": "",
|
||||
"left module": "",
|
||||
"right module": "",
|
||||
|
||||
265
lang/da_dk.json
Normal file
265
lang/da_dk.json
Normal file
@@ -0,0 +1,265 @@
|
||||
{
|
||||
".authorMsg": "- Oversættelse til dansk af Claus Christensen",
|
||||
"DualShock Calibration GUI": "DualShock Kalibrerings GUI",
|
||||
"Unsupported browser. Please use a web browser with WebHID support (e.g. Chrome).": "Browseren understøttes ikke. Brug venligst en webbrowser med WebHID-understøttelse (f.eks. Chrome).",
|
||||
"Connect": "Tilslut",
|
||||
"Connected to:": "Tilsluttet til:",
|
||||
"Disconnect": "Afbryd",
|
||||
"Calibrate stick center": "Kalibrér styrepindens centrum",
|
||||
"Calibrate stick range": "Kalibrér styrepindens rækkevidde",
|
||||
"Sections below are not useful, just some debug infos or manual commands": "Afsnittene nedenfor er ikke relevante, blot nogle fejlfindingsoplysninger eller manuelle kommandoer",
|
||||
"NVS Status": "NVS Status",
|
||||
"Unknown": "Ukendt",
|
||||
"Debug buttons": "Fejlfindingsknapper",
|
||||
"Query NVS status": "Forespørg NVS status",
|
||||
"NVS unlock": "lås NVS op",
|
||||
"NVS lock": "lås NVS",
|
||||
"Get BDAddr": "Hent BDAddr",
|
||||
"Fast calibrate stick center (OLD)": "Hurtig kalibrering af styrepindens centrum (GAMMEL)",
|
||||
"Stick center calibration": "Kalibrering af styrepindens centrum",
|
||||
"Welcome": "Velkommen",
|
||||
"Step 1": "Trin 1",
|
||||
"Step 2": "Trin 2",
|
||||
"Step 3": "Trin 3",
|
||||
"Step 4": "Trin 4",
|
||||
"Completed": "Fuldført",
|
||||
"Welcome to the stick center-calibration wizard!": "Velkommen til guiden til kalibrering af styrepindens centrum!",
|
||||
"This tool will guide you in re-centering the analog sticks of your controller. It consists in four steps: you will be asked to move both sticks in a direction and release them.": "Dette værktøj vil guide dig i at centrere de analoge styrepinde på din controller igen. Det består af fire trin: Du vil blive bedt om at bevæge begge styrepinde i én retning og derefter slippe dem.",
|
||||
"Please be aware that, <i>once the calibration is running, it cannot be canceled</i>. Do not close this page or disconnect your controller until is completed.": "Vær venligst opmærksom på, at <i>når kalibreringen først er i gang, kan den ikke annulleres</i>. Luk ikke denne side, og frakobl ikke din controller, før processen er afsluttet.",
|
||||
"Press <b>Start</b> to begin calibration.": "Tryk på <b>\"Start\"</b> for at begynde kalibreringen.",
|
||||
"Please move both sticks to the <b>top-left corner</b> and release them.": "Flyt begge styrepinde til det <b>øverste venstre hjørne</b>, og slip dem.",
|
||||
"When the sticks are back in the center, press <b>Continue</b>.": "Når styrepindene er tilbage i centrum, skak du trykke på <b>\"Fortsæt\"</b>.",
|
||||
"Please move both sticks to the <b>top-right corner</b> and release them.": "Flyt begge styrepinde til det <b>øverste højre hjørne</b>, og slip dem.",
|
||||
"Please move both sticks to the <b>bottom-left corner</b> and release them.": "Flyt begge styrepinde til det <b>nederste venstre hjørne</b>, og slip dem.",
|
||||
"Please move both sticks to the <b>bottom-right corner</b> and release them.": "Flyt begge styrepinde til det <b>nederste højre hjørne</b>, og slip dem.",
|
||||
"Calibration completed successfully!": "Kalibreringen er gennemført med succes!",
|
||||
"Next": "Næste",
|
||||
"Recentering the controller sticks.": "Genjustering af controllerens styrepinde.",
|
||||
"Please do not close this window and do not disconnect your controller. ": "Luk venligst ikke dette vindue, og frakobl ikke din controller. ",
|
||||
"Range calibration": "Rækkeviddekalibrering",
|
||||
"<b>The controller is now sampling data!</b>": "<b>Controlleren indsamler nu data!</b>",
|
||||
"Rotate the sticks slowly to cover the whole range. Press \"Done\" when completed.": "Rotér styrepindene langsomt for at dække hele rækkevidden. Tryk på \"Færdig\", når du er færdig.",
|
||||
"Done": "Færdig",
|
||||
"Hi, thank you for using this software.": "Hej, tak fordi du bruger denne software.",
|
||||
"If you're finding it helpful and you want to support my efforts, feel free to": "Hvis du finder den nyttig, og du ønsker at støtte mine bestræbelser, er du velkommen til at",
|
||||
"buy me a coffee": "købe mig en kaffe",
|
||||
"! :)": "! :)",
|
||||
"Do you have any suggestion or issue? Drop me a message via email or discord.": "Har du forslag eller oplever du problemer? Send mig en besked via e-mail eller Discord.",
|
||||
"Cheers!": "Cheers!",
|
||||
"Support this project": "Støt dette projekt",
|
||||
"unknown": "ukendt",
|
||||
"original": "original",
|
||||
"clone": "klon",
|
||||
"locked": "låst",
|
||||
"unlocked": "ulåst",
|
||||
"error": "fejl",
|
||||
"Build Date": "Build Dato",
|
||||
"HW Version": "HW Version",
|
||||
"SW Version": "SW Version",
|
||||
"Device Type": "Enhedstype",
|
||||
"Range calibration completed": "Rækkeviddekalibrering gennemført",
|
||||
"Range calibration failed": "Rækkeviddekalibrering mislykkedes",
|
||||
"Cannot unlock NVS": "Kan ikke låse NVS op",
|
||||
"Cannot relock NVS": "Kan ikke låse NVS igen",
|
||||
"Error 1": "Fejl 1",
|
||||
"Error 2": "Fejl 2",
|
||||
"Error 3": "Fejl 3",
|
||||
"Stick calibration failed": "Kalibrering af styrepinde mislykkedes",
|
||||
"Stick calibration completed": "Kalibrering af styrepinde gennemført",
|
||||
"NVS Lock failed": "NVS låsning mislykkedes",
|
||||
"NVS Unlock failed": "NVS oplåsning mislykkedes",
|
||||
"Please connect only one controller at time.": "Forbind kun én controller ad gangen.",
|
||||
"Sony DualShock 4 V1": "Sony DualShock 4 V1",
|
||||
"Sony DualShock 4 V2": "Sony DualShock 4 V2",
|
||||
"Sony DualSense": "Sony DualSense",
|
||||
"Sony DualSense Edge": "Sony DualSense Edge",
|
||||
"Connected invalid device: ": "Forbundet til en ugyldig enhed: ",
|
||||
"The device appears to be a DS4 clone. All functionalities are disabled.": "Enheden ser ud til at være en DS4-klon. Alle funktioner er deaktiveret.",
|
||||
"Error: ": "Fejl: ",
|
||||
"My handle on discord is: the_al": "Mit brugernavn på Discord er: the_al",
|
||||
"Initializing...": "Initialiserer...",
|
||||
"Storing calibration...": "Gemmer kalibrering...",
|
||||
"Sampling...": "Sampling...",
|
||||
"Calibration in progress": "Kalibrering er i gang",
|
||||
"Start": "Start",
|
||||
"Continue": "Fortsæt",
|
||||
"You can check the calibration with the": "Du kan tjekke kalibreringen med",
|
||||
"Have a nice day :)": "Hav en god dag :)",
|
||||
"Welcome to the Calibration GUI": "Velkommen til Kalibrerings GUI",
|
||||
"Just few things to know before you can start:": "Bare et par ting, du skal vide, før du går i gang:",
|
||||
"This website is not affiliated with Sony, PlayStation & co.": "Denne hjemmeside er ikke tilknyttet Sony, PlayStation & co.",
|
||||
"This service is provided without warranty. Use at your own risk.": "Denne service leveres uden garanti og benyttes på eget ansvar.",
|
||||
"Keep the internal battery of the controller connected and ensure it is well charged. If the battery dies during operations, the controller will be damaged and rendered unusable.": "Hold controllerens interne batteri tilsluttet, og sørg for, at det er godt opladet. Hvis batteriet løber tør for strøm under processen, kan controlleren blive beskadiget og ubrugelig.",
|
||||
"Before doing the permanent calibration, try the temporary one to ensure that everything is working well.": "Før du foretager en permanent kalibrering, bør du prøve en midlertidig for at sikre, at alt fungerer korrekt.",
|
||||
"Understood": "Forstået",
|
||||
"Version": "Version",
|
||||
"Frequently Asked Questions": "Ofte stillede spørgsmål",
|
||||
"Close": "Luk",
|
||||
"Welcome to the F.A.Q. section! Below, you'll find answers to some of the most commonly asked questions about this website. If you have any other inquiries or need further assistance, feel free to reach out to me directly. Your feedback and questions are always welcome!": "<b>Velkommen til sektionen med ofte stillede spørgsmål!</b><br> Her finder du svar på nogle af de mest almindelige spørgsmål om denne hjemmeside. Hvis du har andre spørgsmål eller har brug for yderligere hjælp, er du altid velkommen til at kontakte mig direkte. Din feedback og dine spørgsmål er altid velkomne!",
|
||||
"How does it work?": "Hvordan fungerer det?",
|
||||
"Behind the scenes, this website is the culmination of one year of dedicated effort in reverse-engineering DualShock controllers for fun/hobby from a random guy on the internet.": "Bag kulisserne er denne hjemmeside resultatet af et års dedikeret arbejde med reverse-engineering af DualShock controllere for sjov/hobby, udført af en tilfældig fyr på internettet.",
|
||||
"Through": "Gennem",
|
||||
"this research": "denne forskning",
|
||||
", it was discovered that there exist some undocumented commands on DualShock controllers that can be sent via USB and are used during factory assembly process. If these commands are sent, the controller starts the recalibration of analog sticks.": ", blev det opdaget, at der findes nogle udokumenterede kommandoer på DualShock-controllere, som kan sendes via USB og anvendes under fabriksmonteringsprocessen. Når disse kommandoer sendes, starter controlleren en genkalibrering af de analoge styrepinde.",
|
||||
"While the primary focus of this research wasn't initially centered on recalibration, it became apparent that a service offering this capability could greatly benefit numerous individuals. And thus, here we are.": "Selvom det oprindelige fokus for denne forskning oprindeligt ikke var rettet mod genkalibrering, blev det hurtigt klart, at en service med denne funktion kunne være til stor gavn for mange. Og dermed er vi her.",
|
||||
"Does the calibration remain effective during gameplay on PS4/PS5?": "Bliver kalibreringen ved med at være aktiv under gameplay på PS4/PS5?",
|
||||
"Yes, if you tick the checkbox \"Write changes permanently in the controller\". In that case, the calibration is flashed directly in the controller firmware. This ensures that it remains in place regardless of the console it's connected to.": "Ja, hvis du sætter kryds i boksen \"Skriv ændringer permanent i controlleren\", bliver kalibreringen skrevet direkte ind i controllerens firmware. Det sikrer, at den forbliver aktiv, uanset hvilken konsol controlleren tilsluttes.",
|
||||
"Is this an officially endorsed service?": "Er dette en officielt godkendt service?",
|
||||
"No, this service is simply a creation by a DualShock enthusiast.": "Nej, denne service er blot skabt af en DualShock-entusiast.",
|
||||
"Does this website detects if a controller is a clone?": "Kan denne hjemmeside registrere, om en controller er en klon?",
|
||||
"Yes, only DualShock4 at the moment. This happened because I accidentally purchased some clones, spent time identifying the differences and added this functionality to prevent future deception.": "Ja, kun DualShock4 i øjeblikket. Det skete, fordi jeg ved en fejl købte nogle kloner, brugte tid på at identificere forskellene og tilføjede denne funktionalitet for at forhindre fremtidigt bedrag.",
|
||||
"Unfortunately, the clones cannot be calibrated anyway, because they only clone the behavior of a DualShock4 during a normal gameplay, not all the undocumented functionalities.": "Desværre kan klonerne ikke kalibreres, fordi de kun efterligner DualShock4’s adfærd under almindeligt gameplay og ikke alle de udokumenterede funktioner.",
|
||||
"If you want to extend this detection functionality to DualSense, please ship me a fake DualSense and you'll see it in few weeks.": "Hvis du ønsker at udvide denne detektionsfunktionalitet til DualSense, så send mig en falsk DualSense, og du vil kunne se resultaterne om et par uger.",
|
||||
"What development is in plan?": "Hvilke forbedringer er planlagt?",
|
||||
"I maintain two separate to-do lists for this project, although the priority has yet to be established.": "Jeg vedligeholder to separate to-do-lister for dette projekt, selvom prioriteringen endnu ikke er fastlagt.",
|
||||
"The first list is about enhancing support for DualShock4 and DualSense controllers:": "Den første liste handler om at forbedre understøttelsen af DualShock4- og DualSense-controllere:",
|
||||
"Implement calibration of L2/R2 triggers.": "Implementering af kalibrering for L2/R2-aftrækker.",
|
||||
"Improve detection of clones, particularly beneficial for those seeking to purchase used controllers with assurance of authenticity.": "Forbedring af registreringen af kloner, hvilket især er nyttigt for dem, der ønsker at købe brugte controllere med garanti for ægthed.",
|
||||
"Enhance user interface (e.g. provide additional controller information)": "Forbedring af brugergrænsefladen (f.eks. ved at vise flere oplysninger om controlleren).",
|
||||
"Add support for recalibrating IMUs.": "Tilføjelse af understøttelse for genkalibrering af IMU’er.",
|
||||
"Additionally, explore the possibility of reviving non-functioning DualShock controllers (further discussion available on Discord for interested parties).": "Undersøgelse af muligheden for at genoplive ikke-fungerende DualShock-controllere (yderligere diskussion er tilgængelig på Discord for interesserede).",
|
||||
"The second list contains new controllers I aim to support:": "Den anden liste indeholder nye controllere, jeg har til hensigt at understøtte:",
|
||||
"DualSense Edge": "DualSense Edge",
|
||||
"DualShock 3": "DualShock 3",
|
||||
"XBox Controllers": "Xbox Controller",
|
||||
"Each of these tasks presents both immense interest and significant time investment. To provide context, supporting a new controller typically demands 6-12 months of full-time research, alongside a stroke of good fortune.": "Hver af disse opgaver er både utroligt spændende og kræver en betydelig tidsmæssig investering. For at sætte det i perspektiv kræver det typisk 6-12 måneders fuldtidsforskning at tilføje understøttelse af en ny controller - og en god portion held.",
|
||||
"I love this service, it helped me! How can I contribute?": "Jeg elsker denne service, den har hjulpet mig! Hvordan kan jeg bidrage?",
|
||||
"I'm glad to hear that you found this helpful! If you're interested in contributing, here are a few ways you can help me:": "Jeg er glad for at høre, at du fandt dette nyttigt! Hvis du er interesseret i at bidrage, er her nogle måder, du kan hjælpe mig på:",
|
||||
"Consider making a": "Overvej at give en",
|
||||
"donation": "donation",
|
||||
"to support my late-night caffeine-fueled reverse-engineering efforts.": ", for at støtte mine sene nætter med koffein-drevne reverse-engineering indsatser.",
|
||||
"Ship me a controller you would love to add (send me an email for organization).": "Send mig en controller, du gerne vil have tilføjet (send en e-mail for at aftale det praktiske).",
|
||||
"Translate this website in your language": "Oversæt denne hjemmeside til dit sprog",
|
||||
", to help more people like you!": ", for at hjælpe flere personer som dig!",
|
||||
"This website uses analytics to improve the service.": "Hjemmesiden anvender analyseværktøjer for at forbedre servicen.",
|
||||
"Board Model": "Board Model",
|
||||
"This feature is experimental.": "Denne funktion er eksperimentel.",
|
||||
"Please let me know if the board model of your controller is not detected correctly.": "Giv mig venligst besked, hvis board modellen på din controller ikke bliver registreret korrekt.",
|
||||
"Board model detection thanks to": "Board model detektion, tak til",
|
||||
"This DualSense controller has outdated firmware.": "Denne DualSense controller har forældet firmware.",
|
||||
"Please update the firmware and try again.": "Opdater venligst firmwaren og prøv igen.",
|
||||
"Joystick Info": "Joystick Info",
|
||||
"Check circularity": "Tjek cirkularitet",
|
||||
"Can I reset a permanent calibration to previous calibration?": "Kan jeg nulstille en permanent kalibrering til en tidligere kalibrering?",
|
||||
"No.": "Nej.",
|
||||
"Can you overwrite a permanent calibration?": "Kan man overskrive en permanent kalibrering?",
|
||||
"Yes. Simply do another permanent calibration.": "Ja. Du skal blot foretage en ny permanent kalibrering.",
|
||||
"Does this software resolve stickdrift?": "Kan denne software løse styrepinddrift?",
|
||||
"Stickdrift is caused by a physical defect; namely dirt, worn potentiometer or in some cases a worn spring.": "Styrepinddrift skyldes en fysisk fejl; nemlig snavs, en slidt potentiometer eller i nogle tilfælde en slidt fjeder.",
|
||||
"This software will not fix stick drift on its own if you already experience that. What it will help with, is ensuring the new joystick(s) will function properly after replacing the old one(s) to work well with.": "Denne software kan ikke alene rette styrepinddrift, hvis du allerede oplever det. Det, den kan hjælpe med, er at sikre, at den nye styrepind eller de nye styrepinde fungerer korrekt efter udskiftning af de gamle.",
|
||||
"I have noticed some controllers out of the box have worse factory calibration than if I would recalibrate them. Especially true for circularity of SCUF controllers with a unique shell.": "Jeg har bemærket, at nogle controllere direkte fra fabrikken har dårligere kalibrering end efter en genkalibrering. Det gælder især for cirkulariteten på SCUF-controllere med en unik skal.",
|
||||
"(Dualsense) Will updating the firmware reset calibration?": "(Dualsense) Vil en opdatering af firmwaren nulstille kalibreringen?",
|
||||
"After range calibration, joysticks always go in corners.": "Efter rækkeviddekalibrering, bevæger styrepindene sig altid ud i hjørnerne.",
|
||||
"This issue happens because you have clicked \"Done\" immediately after starting a range calibration.": "Dette problem opstår, fordi du har klikket på \"Færdig\" lige efter at have startet en rækkeviddekalibrering.",
|
||||
"Please read the instructions.": "Læs venligst vejledningen.",
|
||||
"You have to rotate the joysticks before you press \"Done\".": "Du skal dreje styrepindene, inden du trykker på \"Færdig\".",
|
||||
"Make sure to touch the edges of the joystick frame and rotate slowly, preferably in each direction - clockwise and anti-clockwise.": "Sørg for at røre ved kanterne af styrepindens ramme og drej langsomt, helst i begge retninger - med uret og mod uret.",
|
||||
"Only after you have done that, you click on \"Done\".": "Først når du har gjort det, skal du klikke på \"Færdig\".",
|
||||
"Changes saved successfully": "Ændringer gemt med succes",
|
||||
"Error while saving changes": "Fejl under gemning af ændringer",
|
||||
"Save changes permanently": "Gem ændringer permanent",
|
||||
"Reboot controller": "Genstart Controller",
|
||||
"Controller Info": "Controller Info",
|
||||
"Debug Info": "Fejlfindingsinfo",
|
||||
"Software": "Software",
|
||||
"Hardware": "Hardware",
|
||||
"FW Build Date": "FW Build Dato",
|
||||
"FW Type": "FW Type",
|
||||
"FW Series": "FW Serie",
|
||||
"Serial Number": "Serienummer",
|
||||
"Battery Barcode": "Batteri Stregkode",
|
||||
"VCM Left Barcode": "VCM Venstre Stregkode",
|
||||
"VCM Right Barcode": "VCM Højre Stregkode",
|
||||
"Show all": "Vis alt",
|
||||
"Finetune stick calibration": "Finjuster styrepindskalibrering",
|
||||
"(beta)": "(beta)",
|
||||
"This screen allows to finetune raw calibration data on your controller": "Denne skærm giver mulighed for at finjustere de rå kalibreringsdata på din controller.",
|
||||
"Left stick": "Venstre styrepind",
|
||||
"Right stick": "Højre styrepind",
|
||||
"Center X": "Centrér X",
|
||||
"Center Y": "Centrér Y",
|
||||
"Save": "Gem",
|
||||
"Cancel": "Afbryd",
|
||||
"The DualShock Calibration GUI does not currently support the DualSense Edge.": "DualShock Kalibrerings GUI understøtter i øjeblikket ikke DualSense Edge.",
|
||||
"I'm actively working on adding compatibility, the primary challenge lies in storing data into the stick modules.": "Jeg arbejder aktivt på at tilføje kompatibilitet, den primære udfordring ligger i at gemme data i stick modulerne.",
|
||||
"If this tool has been helpful to you or you want to see DualSense Edge support arrive faster, please consider supporting the project with a": "Hvis dette værktøj har været nyttigt for dig, eller du gerne vil se DualSense Edge understøttelse komme hurtigere, så overvej venligst at støtte projektet med en",
|
||||
"Thank you for your generosity and support!": "Tak for din gavmildhed og støtte!",
|
||||
"30th Anniversary": "30th Anniversary",
|
||||
"<b>Externally</b>: by applying +1.8V directly to the visible test point without opening the controller.": "<b>Eksternt</b>: ved at påføre +1,8V direkte på det synlige testpunkt uden at åbne controlleren.",
|
||||
"<b>Internally</b>: by soldering a wire from a +1.8V source to the write-protect TP.": "<b>Intern</b>: ved at lodde en ledning fra en +1,8V kilde til skrivebeskyttelses-testpunktet (TP).",
|
||||
"Astro Bot": "Astro Bot",
|
||||
"Bluetooth Address": "Bluetooth Adresse",
|
||||
"Calibration is being stored in the stick modules.": "Kalibreringen bliver gemt i styrepindmodulerne.",
|
||||
"Cannot lock": "Kan ikke låse",
|
||||
"Cannot store data into": "Kan ikke gemme data i",
|
||||
"Cannot unlock": "Kan ikke låse op",
|
||||
"Chroma Indigo": "Chroma Indigo",
|
||||
"Chroma Pearl": "Chroma Pearl",
|
||||
"Chroma Teal": "Chroma Teal",
|
||||
"Cobalt Blue": "Cobalt Blue",
|
||||
"Color": "Farve",
|
||||
"Color detection thanks to": "Farvedetektering, tak til",
|
||||
"Cosmic Red": "Cosmic Red",
|
||||
"DualSense Edge Calibration": "DualSense Edge Kalibrering",
|
||||
"FW Update": "FW Opdatering",
|
||||
"FW Update Info": "FW Opdateringsinfo",
|
||||
"FW Version": "FW Version",
|
||||
"For more info or help, feel free to reach out on Discord.": "For mere info eller hjælp, er du velkommen til at kontakte os på Discord.",
|
||||
"Fortnite": "Fortnite",
|
||||
"Galactic Purple": "Galactic Purple",
|
||||
"God of War Ragnarok": "God of War Ragnarok",
|
||||
"Grey Camouflage": "Grey Camouflage",
|
||||
"HW Model": "HW Model",
|
||||
"If the calibration is not stored permanently, please double-check the wirings of the hardware mod.": "Hvis kalibreringen ikke gemmes permanent, skal du dobbelttjekke kabelføringen af hardware-modifikationen.",
|
||||
"Left Module Barcode": "Venstre Modul Stregkode",
|
||||
"MCU Unique ID": "MCU Unikt ID",
|
||||
"Midnight Black": "Midnight Black",
|
||||
"More details and images": "Flere detaljer og billeder",
|
||||
"Nova Pink": "Nova Pink",
|
||||
"PCBA ID": "PCBA ID",
|
||||
"Please connect a DualShock 4, a DualSense or DualSense Edge controller to your computer and press Connect.": "Forbind venligst en DualShock 4-, DualSense- eller DualSense Edge-controller til din computer, og tryk på Tilslut.",
|
||||
"Right Module Barcode": "Højre Modul Stregkode",
|
||||
"SBL FW Version": "SBL FW Version",
|
||||
"Spider FW Version": "Spider FW Version",
|
||||
"Spider-Man 2": "Spider-Man 2",
|
||||
"Starlight Blue": "Starlight Blue",
|
||||
"Sterling Silver": "Sterling Silver",
|
||||
"Support for calibrating DualSense Edge stick modules is now available as an <b>experimental feature</b>.": "Understøttelse af kalibrering af DualSense Edge styrepindmoduler er nu tilgængelig som en <b>eksperimentel funktion</b>.",
|
||||
"The Last of Us": "The Last of Us",
|
||||
"This involves temporarily disabling write protection by applying <b>+1.8V</b> to a specific test point on each module.": "Dette involverer midlertidigt at deaktivere skrivebeskyttelsen ved, at anvende <b>+1,8V</b> til et specifikt testpunkt på hver modul.",
|
||||
"This is only for advanced users. If you're not sure what you're doing, please do not attempt it.": "Dette er kun for avancerede brugere. Hvis du er usikker på hvad du laver, bør du ikke forsøge det.",
|
||||
"Touchpad FW Version": "Touchpad FW Version",
|
||||
"Touchpad ID": "Touchpad ID",
|
||||
"Venom FW Version": "Venom FW Version",
|
||||
"Volcanic Red": "Volcanic Red",
|
||||
"We are not responsible for any damage caused by attempting this modification.": "Vi påtager os intet ansvar for eventuelle skader forårsaget af denne ændring.",
|
||||
"White": "Hvid",
|
||||
"You can do this in two ways:": "Du kan gøre dette på to måder:",
|
||||
"here": "her",
|
||||
"left module": "venstre modul",
|
||||
"right module": "højre modul",
|
||||
"10x zoom": "10x zoom",
|
||||
"Calibration": "Kalibrering",
|
||||
"Debug": "Fejlfinding",
|
||||
"Error triggering rumble": "Fejl ved aktivering af vibration",
|
||||
"Info": "Info",
|
||||
"Normal": "Normal",
|
||||
"Please note: the stick modules on the DS Edge <b>cannot be calibrated via software alone</b>.": "Bemærk venligst: Styrepindmodulerne på DS Edge <b>kan ikke kalibreres udelukkende via software</b>.",
|
||||
"To store a custom calibration on the stick's internal memory, a <b>hardware modification</b> is required.": "For at gemme en brugerdefineret kalibrering i styrepindens interne hukommelse kræves der en <b>hardwaremodifikation</b>.",
|
||||
"Press L2 to test the strong (left) haptic motor": "Tryk på L2 for at teste den stærke (venstre) haptiske motor",
|
||||
"Press R2 to test the weak (right) haptic motor": "Tryk på R2 for at teste den svage (højre) haptiske motor",
|
||||
"Test the Haptic Motors": "Test de haptiske motorer",
|
||||
"Tests": "Test",
|
||||
"The motor strength will match how hard you press the trigger": "Motorstyrken vil matche, hvor hårdt du trykker på aftrækkeren",
|
||||
"Center (L1)": "",
|
||||
"Circularity (R1)": "",
|
||||
"Move the stick to select it for tuning, then without touching the stick use the D-pad buttons to adjust the center point. Flick it and adjust it again if it is off center or flickers.": "",
|
||||
"Please release the stick to center position before adjusting with D-pad buttons.": "",
|
||||
"Press the D-pad or face buttons in the direction you want the stick position to move.": "",
|
||||
"Push the stick straight up/down/left/right as far as possible.": "",
|
||||
"Show raw numbers": "",
|
||||
"The device is connected via Bluetooth. Disconnect and reconnect using a USB cable instead.": "",
|
||||
"While holding the stick to be adjusted straight up/down/left/right, <em>observe the highlighted value below the circle</em>, then use the D-pad buttons to adjust the value to ±0.99 (just below ±1.00).": "",
|
||||
"Your device might not be a genuine Sony controller. If it is not a clone then please report this issue.": "",
|
||||
"": ""
|
||||
}
|
||||
@@ -34,7 +34,7 @@
|
||||
"Please move both sticks to the <b>bottom-right corner</b> and release them.": "Bewege bitte beide Sticks in die <b>untere rechte Ecke</b> und lasse sie los.",
|
||||
"Calibration completed successfully!": "Kalibrierung erfolgreich abgeschlossen!",
|
||||
"Next": "Weiter",
|
||||
"Recentering the controller sticks. ": "Controller-Sticks zurücksetzen. ",
|
||||
"Recentering the controller sticks.": "Controller-Sticks zurücksetzen.",
|
||||
"Please do not close this window and do not disconnect your controller. ": "Bitte schließe das Fenster nicht und trenne deinen Controller nicht. ",
|
||||
"Range calibration": "Bereichskalibrierung",
|
||||
"<b>The controller is now sampling data!</b>": "<b>Der Controller erfasst jetzt Daten!</b>",
|
||||
@@ -58,16 +58,16 @@
|
||||
"SW Version": "SW-Version",
|
||||
"Device Type": "Gerätetyp",
|
||||
"Range calibration completed": "Bereichskalibrierung abgeschlossen",
|
||||
"Range calibration failed: ": "Bereichskalibrierung fehlgeschlagen: ",
|
||||
"Range calibration failed": "Bereichskalibrierung fehlgeschlagen",
|
||||
"Cannot unlock NVS": "NVS kann nicht entsperrt werden",
|
||||
"Cannot relock NVS": "NVS kann nicht wieder gesperrt werden",
|
||||
"Error 1": "Fehler 1",
|
||||
"Error 2": "Fehler 2",
|
||||
"Error 3": "Fehler 3",
|
||||
"Stick calibration failed: ": "Stick-Kalibrierung fehlgeschlagen: ",
|
||||
"Stick calibration failed": "Stick-Kalibrierung fehlgeschlagen",
|
||||
"Stick calibration completed": "Stick-Kalibrierung abgeschlossen",
|
||||
"NVS Lock failed: ": "NVS-Sperrung fehlgeschlagen: ",
|
||||
"NVS Unlock failed: ": "NVS-Entsperrung fehlgeschlagen: ",
|
||||
"NVS Lock failed": "NVS-Sperrung fehlgeschlagen",
|
||||
"NVS Unlock failed": "NVS-Entsperrung fehlgeschlagen",
|
||||
"Please connect only one controller at time.": "Bitte verbinde jeweils nur einen Controller.",
|
||||
"Sony DualShock 4 V1": "Sony DualShock 4 V1",
|
||||
"Sony DualShock 4 V2": "Sony DualShock 4 V2",
|
||||
@@ -136,12 +136,9 @@
|
||||
"This feature is experimental.": "Diese Funktion ist experimentell.",
|
||||
"Please let me know if the board model of your controller is not detected correctly.": "Bitte lasse mich wissen, wenn das Platinentyp Ihres Controllers nicht korrekt erkannt wird.",
|
||||
"Board model detection thanks to": "Platinentyp-Erkennung dank",
|
||||
"Please connect the device using a USB cable.": "Bitte verbinde das Gerät mit einem USB-Kabel.",
|
||||
"This DualSense controller has outdated firmware.": "Dieser DualSense-Controller hat eine veraltete Firmware.",
|
||||
"Please update the firmware and try again.": "Bitte aktualisiere die Firmware und versuche es erneut.",
|
||||
"Joystick Info": "Joystick-Informationen",
|
||||
"Err R:": "Fehler R:",
|
||||
"Err L:": "Fehler L:",
|
||||
"Check circularity": "Kreisförmigkeit prüfen",
|
||||
"Can I reset a permanent calibration to previous calibration?": "Kann man eine permanente Kalibrierung auf eine vorherige zurücksetzen?",
|
||||
"No.": "Nein.",
|
||||
@@ -159,7 +156,7 @@
|
||||
"Make sure to touch the edges of the joystick frame and rotate slowly, preferably in each direction - clockwise and anti-clockwise.": "Stelle sicher, dass du die Ränder des Joystick-Gehäuses berührst und drehe sie langsam, am besten in beide Richtungen.",
|
||||
"Only after you have done that, you click on \"Done\".": "Erst wenn du das gemacht hast, klickst du auf \"Fertig\".",
|
||||
"Changes saved successfully": "Änderungen erfolgreich gespeichert",
|
||||
"Error while saving changes:": "Fehler beim Speichern der Änderungen",
|
||||
"Error while saving changes": "Fehler beim Speichern der Änderungen",
|
||||
"Save changes permanently": "Änderungen Permanent speichern",
|
||||
"Reboot controller": "Controller Neustarten",
|
||||
"Controller Info": "Controller Infos",
|
||||
@@ -187,43 +184,68 @@
|
||||
"I'm actively working on adding compatibility, the primary challenge lies in storing data into the stick modules.": "Ich arbeite aktiv daran, die Kompatibilität hinzuzufügen. Die größte Herausforderung besteht darin, Daten in die Stick-Module zu speichern.",
|
||||
"If this tool has been helpful to you or you want to see DualSense Edge support arrive faster, please consider supporting the project with a": "Wenn Ihnen dieses Tool geholfen hat oder Sie möchten, dass die DualSense-Edge-Unterstützung schneller verfügbar ist, ziehen Sie bitte in Betracht, das Projekt mit einem Beitrag zu unterstützen",
|
||||
"Thank you for your generosity and support!": "Vielen Dank für Ihre Großzügigkeit und Unterstützung!",
|
||||
"10x zoom": "",
|
||||
"30th Anniversary": "",
|
||||
"<b>Externally</b>: by applying +1.8V directly to the visible test point without opening the controller": "",
|
||||
"<b>Externally</b>: by applying +1.8V directly to the visible test point without opening the controller.": "",
|
||||
"<b>Internally</b>: by soldering a wire from a +1.8V source to the write-protect TP.": "",
|
||||
"Astro Bot": "",
|
||||
"Bluetooth Address": "",
|
||||
"Calibration": "",
|
||||
"Calibration is being stored in the stick modules.": "",
|
||||
"Cannot lock": "",
|
||||
"Cannot store data into": "",
|
||||
"Cannot unlock": "",
|
||||
"Center (L1)": "",
|
||||
"Chroma Indigo": "",
|
||||
"Chroma Pearl": "",
|
||||
"Chroma Teal": "",
|
||||
"Circularity (R1)": "",
|
||||
"Cobalt Blue": "",
|
||||
"Color": "",
|
||||
"Color detection thanks to": "",
|
||||
"Cosmic Red": "",
|
||||
"Debug": "",
|
||||
"DualSense Edge Calibration": "",
|
||||
"Error triggering rumble": "",
|
||||
"FW Update": "",
|
||||
"FW Update Info": "",
|
||||
"FW Version": "",
|
||||
"For more info or help, feel free to reach out on Discord.": "",
|
||||
"Fortnite": "",
|
||||
"Galactic Purple": "",
|
||||
"God of War Ragnarok": "",
|
||||
"Grey Camouflage": "",
|
||||
"HW Model": "",
|
||||
"If the calibration is not stored permanently, please double-check the wirings of the hardware mod.": "",
|
||||
"Info": "",
|
||||
"Left Module Barcode": "",
|
||||
"MCU Unique ID": "",
|
||||
"Midnight Black": "",
|
||||
"More details and images": "",
|
||||
"Move the stick to select it for tuning, then without touching the stick use the D-pad buttons to adjust the center point. Flick it and adjust it again if it is off center or flickers.": "",
|
||||
"Normal": "",
|
||||
"Nova Pink": "",
|
||||
"PCBA ID": "",
|
||||
"Please connect a DualShock 4, a DualSense or DualSense Edge controller to your computer and press Connect.": "",
|
||||
"Please note: the stick modules on the DS Edge <b>cannot be calibrated via software alone</b>.To store a custom calibration on the stick's internal memory, a <b>hardware modification</b> is required.": "",
|
||||
"Please release the stick to center position before adjusting with D-pad buttons.": "",
|
||||
"Press L2 to test the strong (left) haptic motor": "",
|
||||
"Press R2 to test the weak (right) haptic motor": "",
|
||||
"Press the D-pad or face buttons in the direction you want the stick position to move.": "",
|
||||
"Push the stick straight up/down/left/right as far as possible.": "",
|
||||
"Right Module Barcode": "",
|
||||
"SBL FW Version": "",
|
||||
"Show raw numbers": "",
|
||||
"Spider FW Version": "",
|
||||
"Spider-Man 2": "",
|
||||
"Starlight Blue": "",
|
||||
"Sterling Silver": "",
|
||||
"Support for calibrating DualSense Edge stick modules is now available as an <b>experimental feature</b>.": "",
|
||||
"Test the Haptic Motors": "",
|
||||
"Tests": "",
|
||||
"The Last of Us": "",
|
||||
"The device is connected via Bluetooth. Disconnect and reconnect using a USB cable instead.": "",
|
||||
"The motor strength will match how hard you press the trigger": "",
|
||||
"This involves temporarily disabling write protection by applying <b>+1.8V</b> to a specific test point on each module.": "",
|
||||
"This is only for advanced users. If you're not sure what you're doing, please do not attempt it.": "",
|
||||
"Touchpad FW Version": "",
|
||||
@@ -231,8 +253,10 @@
|
||||
"Venom FW Version": "",
|
||||
"Volcanic Red": "",
|
||||
"We are not responsible for any damage caused by attempting this modification.": "",
|
||||
"While holding the stick to be adjusted straight up/down/left/right, <em>observe the highlighted value below the circle</em>, then use the D-pad buttons to adjust the value to ±0.99 (just below ±1.00).": "",
|
||||
"White": "",
|
||||
"You can do this in two ways:": "",
|
||||
"Your device might not be a genuine Sony controller. If it is not a clone then please report this issue.": "",
|
||||
"here": "",
|
||||
"left module": "",
|
||||
"right module": "",
|
||||
|
||||
@@ -32,7 +32,7 @@
|
||||
"Please move both sticks to the <b>bottom-right corner</b> and release them.": "Mueva ambos análogos hacia la esquina <b>inferior-derecha</b> y luego suéltelos.",
|
||||
"Calibration completed successfully!": "Calibración realizada con exito!",
|
||||
"Next": "Siguiente",
|
||||
"Recentering the controller sticks. ": "Re-centrando los análogos del mando. ",
|
||||
"Recentering the controller sticks.": "Re-centrando los análogos del mando.",
|
||||
"Please do not close this window and do not disconnect your controller. ": "Por favor, no cierre esta ventana y/o desconecte el mando. ",
|
||||
"Range calibration": "Calibración de rango",
|
||||
"<b>The controller is now sampling data!</b>": "<b>El mando ahora esta captando información!</b>",
|
||||
@@ -56,16 +56,16 @@
|
||||
"SW Version": "Versión SW",
|
||||
"Device Type": "Tipo de dispositivo",
|
||||
"Range calibration completed": "Calibración de Rango completada",
|
||||
"Range calibration failed: ": "Calibración de Rango fallida",
|
||||
"Range calibration failed": "Calibración de Rango fallida",
|
||||
"Cannot unlock NVS": "No fue posible desbloquear la NVS",
|
||||
"Cannot relock NVS": "No fue posible re-bloquear la NVS",
|
||||
"Error 1": "Error 1",
|
||||
"Error 2": "Error 2",
|
||||
"Error 3": "Error 3",
|
||||
"Stick calibration failed: ": "Calibración de análogos fallida: ",
|
||||
"Stick calibration failed": "Calibración de análogos fallida",
|
||||
"Stick calibration completed": "Calibración de análogos completada",
|
||||
"NVS Lock failed: ": "Bloqueo NVS Fallido: ",
|
||||
"NVS Unlock failed: ": "Desbloqueo NVS Fallido: ",
|
||||
"NVS Lock failed": "Bloqueo NVS Fallido",
|
||||
"NVS Unlock failed": "Desbloqueo NVS Fallido",
|
||||
"Please connect only one controller at time.": "Por favor, conecte solo un mando a la vez.",
|
||||
"Sony DualShock 4 V1": "Sony DualShock 4 V1",
|
||||
"Sony DualShock 4 V2": "Sony DualShock 4 V2",
|
||||
@@ -134,22 +134,21 @@
|
||||
"This feature is experimental.": "Esta función es experimental.",
|
||||
"Please let me know if the board model of your controller is not detected correctly.": "Por favor, avísame si el modelo de la placa de tu controlador no se detecta correctamente.",
|
||||
"Board model detection thanks to": "Detección del modelo de la placa gracias a",
|
||||
"Please connect the device using a USB cable.": "Por favor, conecta el dispositivo usando un cable USB.",
|
||||
"This DualSense controller has outdated firmware.": "Este mando DualSense tiene un firmware desactualizado.",
|
||||
"Please update the firmware and try again.": "Por favor, actualiza el firmware y vuelve a intentarlo.",
|
||||
"Joystick Info": "Información del joystick",
|
||||
"Err R:": "Error D:",
|
||||
"Err L:": "Error I:",
|
||||
"Check circularity": "Comprobar circularidad",
|
||||
"(Dualsense) Will updating the firmware reset calibration?": "",
|
||||
"(beta)": "",
|
||||
"10x zoom": "",
|
||||
"30th Anniversary": "",
|
||||
"<b>Externally</b>: by applying +1.8V directly to the visible test point without opening the controller": "",
|
||||
"<b>Externally</b>: by applying +1.8V directly to the visible test point without opening the controller.": "",
|
||||
"<b>Internally</b>: by soldering a wire from a +1.8V source to the write-protect TP.": "",
|
||||
"After range calibration, joysticks always go in corners.": "",
|
||||
"Astro Bot": "",
|
||||
"Battery Barcode": "",
|
||||
"Bluetooth Address": "",
|
||||
"Calibration": "",
|
||||
"Calibration is being stored in the stick modules.": "",
|
||||
"Can I reset a permanent calibration to previous calibration?": "",
|
||||
"Can you overwrite a permanent calibration?": "",
|
||||
@@ -157,19 +156,26 @@
|
||||
"Cannot lock": "",
|
||||
"Cannot store data into": "",
|
||||
"Cannot unlock": "",
|
||||
"Center (L1)": "",
|
||||
"Center X": "",
|
||||
"Center Y": "",
|
||||
"Changes saved successfully": "",
|
||||
"Chroma Indigo": "",
|
||||
"Chroma Pearl": "",
|
||||
"Chroma Teal": "",
|
||||
"Circularity (R1)": "",
|
||||
"Cobalt Blue": "",
|
||||
"Color": "",
|
||||
"Color detection thanks to": "",
|
||||
"Controller Info": "",
|
||||
"Cosmic Red": "",
|
||||
"Debug": "",
|
||||
"Debug Info": "",
|
||||
"Debug buttons": "",
|
||||
"Does this software resolve stickdrift?": "",
|
||||
"DualSense Edge Calibration": "",
|
||||
"Error while saving changes:": "",
|
||||
"Error triggering rumble": "",
|
||||
"Error while saving changes": "",
|
||||
"FW Build Date": "",
|
||||
"FW Series": "",
|
||||
"FW Type": "",
|
||||
@@ -178,6 +184,7 @@
|
||||
"FW Version": "",
|
||||
"Finetune stick calibration": "",
|
||||
"For more info or help, feel free to reach out on Discord.": "",
|
||||
"Fortnite": "",
|
||||
"Galactic Purple": "",
|
||||
"God of War Ragnarok": "",
|
||||
"Grey Camouflage": "",
|
||||
@@ -187,19 +194,27 @@
|
||||
"I'm actively working on adding compatibility, the primary challenge lies in storing data into the stick modules.": "",
|
||||
"If the calibration is not stored permanently, please double-check the wirings of the hardware mod.": "",
|
||||
"If this tool has been helpful to you or you want to see DualSense Edge support arrive faster, please consider supporting the project with a": "",
|
||||
"Info": "",
|
||||
"Left Module Barcode": "",
|
||||
"Left stick": "",
|
||||
"MCU Unique ID": "",
|
||||
"Make sure to touch the edges of the joystick frame and rotate slowly, preferably in each direction - clockwise and anti-clockwise.": "",
|
||||
"Midnight Black": "",
|
||||
"More details and images": "",
|
||||
"Move the stick to select it for tuning, then without touching the stick use the D-pad buttons to adjust the center point. Flick it and adjust it again if it is off center or flickers.": "",
|
||||
"No.": "",
|
||||
"Normal": "",
|
||||
"Nova Pink": "",
|
||||
"Only after you have done that, you click on \"Done\".": "",
|
||||
"PCBA ID": "",
|
||||
"Please connect a DualShock 4, a DualSense or DualSense Edge controller to your computer and press Connect.": "",
|
||||
"Please note: the stick modules on the DS Edge <b>cannot be calibrated via software alone</b>.To store a custom calibration on the stick's internal memory, a <b>hardware modification</b> is required.": "",
|
||||
"Please read the instructions.": "",
|
||||
"Please release the stick to center position before adjusting with D-pad buttons.": "",
|
||||
"Press L2 to test the strong (left) haptic motor": "",
|
||||
"Press R2 to test the weak (right) haptic motor": "",
|
||||
"Press the D-pad or face buttons in the direction you want the stick position to move.": "",
|
||||
"Push the stick straight up/down/left/right as far as possible.": "",
|
||||
"Reboot controller": "",
|
||||
"Right Module Barcode": "",
|
||||
"Right stick": "",
|
||||
@@ -208,14 +223,21 @@
|
||||
"Save changes permanently": "",
|
||||
"Serial Number": "",
|
||||
"Show all": "",
|
||||
"Show raw numbers": "",
|
||||
"Software": "",
|
||||
"Spider FW Version": "",
|
||||
"Spider-Man 2": "",
|
||||
"Starlight Blue": "",
|
||||
"Sterling Silver": "",
|
||||
"Stickdrift is caused by a physical defect; namely dirt, worn potentiometer or in some cases a worn spring.": "",
|
||||
"Support for calibrating DualSense Edge stick modules is now available as an <b>experimental feature</b>.": "",
|
||||
"Test the Haptic Motors": "",
|
||||
"Tests": "",
|
||||
"Thank you for your generosity and support!": "",
|
||||
"The DualShock Calibration GUI does not currently support the DualSense Edge.": "",
|
||||
"The Last of Us": "",
|
||||
"The device is connected via Bluetooth. Disconnect and reconnect using a USB cable instead.": "",
|
||||
"The motor strength will match how hard you press the trigger": "",
|
||||
"This involves temporarily disabling write protection by applying <b>+1.8V</b> to a specific test point on each module.": "",
|
||||
"This is only for advanced users. If you're not sure what you're doing, please do not attempt it.": "",
|
||||
"This issue happens because you have clicked \"Done\" immediately after starting a range calibration.": "",
|
||||
@@ -228,10 +250,12 @@
|
||||
"Venom FW Version": "",
|
||||
"Volcanic Red": "",
|
||||
"We are not responsible for any damage caused by attempting this modification.": "",
|
||||
"While holding the stick to be adjusted straight up/down/left/right, <em>observe the highlighted value below the circle</em>, then use the D-pad buttons to adjust the value to ±0.99 (just below ±1.00).": "",
|
||||
"White": "",
|
||||
"Yes. Simply do another permanent calibration.": "",
|
||||
"You can do this in two ways:": "",
|
||||
"You have to rotate the joysticks before you press \"Done\".": "",
|
||||
"Your device might not be a genuine Sony controller. If it is not a clone then please report this issue.": "",
|
||||
"here": "",
|
||||
"left module": "",
|
||||
"right module": "",
|
||||
|
||||
@@ -23,19 +23,19 @@
|
||||
"Completed": "Terminé",
|
||||
"Welcome to the stick center-calibration wizard!": "Bienvenue dans l'assistant de calibrage de centrage du joystick !",
|
||||
"This tool will guide you in re-centering the analog sticks of your controller. It consists in four steps: you will be asked to move both sticks in a direction and release them.": "Cet outil va vous guider afin de recentrer les joysticks analogiques de votre manette. Il consiste en quatres étapes: il vous sera demandé de bouger les deux joysticks dans une direction puis de les relacher.",
|
||||
"Please be aware that, <i>;once the calibration is running, it cannot be canceled</i>;. Do not close this page or disconnect your controller until is completed.": "Veuillez noter <i>;qu’une fois le calibrage lancée, il n’est pas possible de l'annuler</i>;. Ne fermez pas cette page ou ne déconnectez pas la manette tant que le calibrage n’est pas terminée.",
|
||||
"Press <b>;Start</b>; to begin calibration.": "Appuyez sur <b>;Démarrer</b>; pour commencer le calibrage.",
|
||||
"Please move both sticks to the <b>;top-left corner</b>; and release them.": "Veuillez déplacer les deux joysticks <b>;en haut à gauche</b>; puis relachez-les.",
|
||||
"When the sticks are back in the center, press <b>;Continue</b>;.": "Une fois les deux joysticks recentrés, appuyez sur <b>;Continuer</b>;.",
|
||||
"Please move both sticks to the <b>;top-right corner</b>; and release them.": "Veuillez déplacer les deux joysticks <b>;en haut à droite</b>; puis relachez-les.",
|
||||
"Please move both sticks to the <b>;bottom-left corner</b>; and release them.": "Veuillez déplacer les deux joysticks <b>;en bas à gauche</b>; puis relachez-les.",
|
||||
"Please move both sticks to the <b>;bottom-right corner</b>; and release them.": "Veuillez déplacer les deux joysticks <b>;en bas à droite</b>; puis relachez-les.",
|
||||
"Please be aware that, <i>once the calibration is running, it cannot be canceled</i>. Do not close this page or disconnect your controller until is completed.": "Veuillez noter <i>qu'une fois le calibrage lancée, il n'est pas possible de l'annuler</i>. Ne fermez pas cette page ou ne déconnectez pas la manette tant que le calibrage n'est pas terminée.",
|
||||
"Press <b>Start</b> to begin calibration.": "Appuyez sur <b>Démarrer</b> pour commencer le calibrage.",
|
||||
"Please move both sticks to the <b>top-left corner</b> and release them.": "Veuillez déplacer les deux joysticks <b>en haut à gauche</b> puis relachez-les.",
|
||||
"When the sticks are back in the center, press <b>Continue</b>.": "Une fois les deux joysticks recentrés, appuyez sur <b>Continuer</b>.",
|
||||
"Please move both sticks to the <b>top-right corner</b> and release them.": "Veuillez déplacer les deux joysticks <b>en haut à droite</b> puis relachez-les.",
|
||||
"Please move both sticks to the <b>bottom-left corner</b> and release them.": "Veuillez déplacer les deux joysticks <b>en bas à gauche</b> puis relachez-les.",
|
||||
"Please move both sticks to the <b>bottom-right corner</b> and release them.": "Veuillez déplacer les deux joysticks <b>en bas à droite</b> puis relachez-les.",
|
||||
"Calibration completed successfully!": "Calibrage terminé avec succès !",
|
||||
"Next": "Suivant",
|
||||
"Recentering the controller sticks. ": "Recentrement des joysticks de la manette en cours. ",
|
||||
"Recentering the controller sticks.": "Recentrement des joysticks de la manette en cours.",
|
||||
"Please do not close this window and do not disconnect your controller. ": "Veuillez ne pas fermer cette fenêtre et ne déconnectez pas votre manette. ",
|
||||
"Range calibration": "Calibrage de la portée du joystick",
|
||||
"<b>;The controller is now sampling data!</b>;": "<b>;La manette est maintenant en train d'échantillonner les données !</b>;",
|
||||
"<b>The controller is now sampling data!</b>": "<b>La manette est maintenant en train d'échantillonner les données !</b>",
|
||||
"Rotate the sticks slowly to cover the whole range. Press \"Done\" when completed.": "Faites tourner doucement les joysticks afin de couvrir toute leur portée. Appuyez sur \"Terminer\" une fois terminé.",
|
||||
"Done": "Terminer",
|
||||
"Hi, thank you for using this software.": "Salut, merci d'avoir utilisé cet outil.",
|
||||
@@ -56,16 +56,16 @@
|
||||
"SW Version": "Version du SW",
|
||||
"Device Type": "Type d'appareil",
|
||||
"Range calibration completed": "Calibrage de la portée terminé",
|
||||
"Range calibration failed: ": "Échec du calibrage de la portée: ",
|
||||
"Range calibration failed": "Échec du calibrage de la portée",
|
||||
"Cannot unlock NVS": "Impossible de dévérouiller le NVS",
|
||||
"Cannot relock NVS": "Impossible de vérouiller le NVS",
|
||||
"Error 1": "Erreur 1",
|
||||
"Error 2": "Erreur 2",
|
||||
"Error 3": "Erreur 3",
|
||||
"Stick calibration failed: ": "Échec du calibrage des joysticks: ",
|
||||
"Stick calibration failed": "Échec du calibrage des joysticks",
|
||||
"Stick calibration completed": "Calibrage des joysticks terminé",
|
||||
"NVS Lock failed: ": "Échec du vérouillage du NVS: ",
|
||||
"NVS Unlock failed: ": "Échec du dévérouillage du NVS: ",
|
||||
"NVS Lock failed": "Échec du vérouillage du NVS",
|
||||
"NVS Unlock failed": "Échec du dévérouillage du NVS",
|
||||
"Please connect only one controller at time.": "Veuillez ne connecter qu'une seule manette à la fois.",
|
||||
"Sony DualShock 4 V1": "Sony DualShock 4 V1",
|
||||
"Sony DualShock 4 V2": "Sony DualShock 4 V2",
|
||||
@@ -134,22 +134,21 @@
|
||||
"This feature is experimental.": "Cette fonctionnalité est expérimentale.",
|
||||
"Please let me know if the board model of your controller is not detected correctly.": "Veuillez me faire savoir si le modèle de la carte de votre manette n'est pas détecté correctement.",
|
||||
"Board model detection thanks to": "Détection du modèle de la carte grâce à",
|
||||
"Please connect the device using a USB cable.": "Veuillez connecter l'appareil à l'aide d'un câble USB.",
|
||||
"This DualSense controller has outdated firmware.": "Cette manette DualSense a un firmware obsolète.",
|
||||
"Please update the firmware and try again.": "Veuillez mettre à jour le firmware et réessayer.",
|
||||
"Joystick Info": "Infos Joystick",
|
||||
"Err R:": "Err D:",
|
||||
"Err L:": "Err G:",
|
||||
"Check circularity": "Vérifier la circularité",
|
||||
"(Dualsense) Will updating the firmware reset calibration?": "",
|
||||
"(beta)": "",
|
||||
"10x zoom": "",
|
||||
"30th Anniversary": "",
|
||||
"<b>Externally</b>: by applying +1.8V directly to the visible test point without opening the controller": "",
|
||||
"<b>Externally</b>: by applying +1.8V directly to the visible test point without opening the controller.": "",
|
||||
"<b>Internally</b>: by soldering a wire from a +1.8V source to the write-protect TP.": "",
|
||||
"After range calibration, joysticks always go in corners.": "",
|
||||
"Astro Bot": "",
|
||||
"Battery Barcode": "",
|
||||
"Bluetooth Address": "",
|
||||
"Calibration": "",
|
||||
"Calibration is being stored in the stick modules.": "",
|
||||
"Can I reset a permanent calibration to previous calibration?": "",
|
||||
"Can you overwrite a permanent calibration?": "",
|
||||
@@ -157,19 +156,26 @@
|
||||
"Cannot lock": "",
|
||||
"Cannot store data into": "",
|
||||
"Cannot unlock": "",
|
||||
"Center (L1)": "",
|
||||
"Center X": "",
|
||||
"Center Y": "",
|
||||
"Changes saved successfully": "",
|
||||
"Chroma Indigo": "",
|
||||
"Chroma Pearl": "",
|
||||
"Chroma Teal": "",
|
||||
"Circularity (R1)": "",
|
||||
"Cobalt Blue": "",
|
||||
"Color": "",
|
||||
"Color detection thanks to": "",
|
||||
"Controller Info": "",
|
||||
"Cosmic Red": "",
|
||||
"Debug": "",
|
||||
"Debug Info": "",
|
||||
"Debug buttons": "",
|
||||
"Does this software resolve stickdrift?": "",
|
||||
"DualSense Edge Calibration": "",
|
||||
"Error while saving changes:": "",
|
||||
"Error triggering rumble": "",
|
||||
"Error while saving changes": "",
|
||||
"FW Build Date": "",
|
||||
"FW Series": "",
|
||||
"FW Type": "",
|
||||
@@ -178,6 +184,7 @@
|
||||
"FW Version": "",
|
||||
"Finetune stick calibration": "",
|
||||
"For more info or help, feel free to reach out on Discord.": "",
|
||||
"Fortnite": "",
|
||||
"Galactic Purple": "",
|
||||
"God of War Ragnarok": "",
|
||||
"Grey Camouflage": "",
|
||||
@@ -187,19 +194,27 @@
|
||||
"I'm actively working on adding compatibility, the primary challenge lies in storing data into the stick modules.": "",
|
||||
"If the calibration is not stored permanently, please double-check the wirings of the hardware mod.": "",
|
||||
"If this tool has been helpful to you or you want to see DualSense Edge support arrive faster, please consider supporting the project with a": "",
|
||||
"Info": "",
|
||||
"Left Module Barcode": "",
|
||||
"Left stick": "",
|
||||
"MCU Unique ID": "",
|
||||
"Make sure to touch the edges of the joystick frame and rotate slowly, preferably in each direction - clockwise and anti-clockwise.": "",
|
||||
"Midnight Black": "",
|
||||
"More details and images": "",
|
||||
"Move the stick to select it for tuning, then without touching the stick use the D-pad buttons to adjust the center point. Flick it and adjust it again if it is off center or flickers.": "",
|
||||
"No.": "",
|
||||
"Normal": "",
|
||||
"Nova Pink": "",
|
||||
"Only after you have done that, you click on \"Done\".": "",
|
||||
"PCBA ID": "",
|
||||
"Please connect a DualShock 4, a DualSense or DualSense Edge controller to your computer and press Connect.": "",
|
||||
"Please note: the stick modules on the DS Edge <b>cannot be calibrated via software alone</b>.To store a custom calibration on the stick's internal memory, a <b>hardware modification</b> is required.": "",
|
||||
"Please read the instructions.": "",
|
||||
"Please release the stick to center position before adjusting with D-pad buttons.": "",
|
||||
"Press L2 to test the strong (left) haptic motor": "",
|
||||
"Press R2 to test the weak (right) haptic motor": "",
|
||||
"Press the D-pad or face buttons in the direction you want the stick position to move.": "",
|
||||
"Push the stick straight up/down/left/right as far as possible.": "",
|
||||
"Reboot controller": "",
|
||||
"Right Module Barcode": "",
|
||||
"Right stick": "",
|
||||
@@ -208,14 +223,21 @@
|
||||
"Save changes permanently": "",
|
||||
"Serial Number": "",
|
||||
"Show all": "",
|
||||
"Show raw numbers": "",
|
||||
"Software": "",
|
||||
"Spider FW Version": "",
|
||||
"Spider-Man 2": "",
|
||||
"Starlight Blue": "",
|
||||
"Sterling Silver": "",
|
||||
"Stickdrift is caused by a physical defect; namely dirt, worn potentiometer or in some cases a worn spring.": "",
|
||||
"Support for calibrating DualSense Edge stick modules is now available as an <b>experimental feature</b>.": "",
|
||||
"Test the Haptic Motors": "",
|
||||
"Tests": "",
|
||||
"Thank you for your generosity and support!": "",
|
||||
"The DualShock Calibration GUI does not currently support the DualSense Edge.": "",
|
||||
"The Last of Us": "",
|
||||
"The device is connected via Bluetooth. Disconnect and reconnect using a USB cable instead.": "",
|
||||
"The motor strength will match how hard you press the trigger": "",
|
||||
"This involves temporarily disabling write protection by applying <b>+1.8V</b> to a specific test point on each module.": "",
|
||||
"This is only for advanced users. If you're not sure what you're doing, please do not attempt it.": "",
|
||||
"This issue happens because you have clicked \"Done\" immediately after starting a range calibration.": "",
|
||||
@@ -228,10 +250,12 @@
|
||||
"Venom FW Version": "",
|
||||
"Volcanic Red": "",
|
||||
"We are not responsible for any damage caused by attempting this modification.": "",
|
||||
"While holding the stick to be adjusted straight up/down/left/right, <em>observe the highlighted value below the circle</em>, then use the D-pad buttons to adjust the value to ±0.99 (just below ±1.00).": "",
|
||||
"White": "",
|
||||
"Yes. Simply do another permanent calibration.": "",
|
||||
"You can do this in two ways:": "",
|
||||
"You have to rotate the joysticks before you press \"Done\".": "",
|
||||
"Your device might not be a genuine Sony controller. If it is not a clone then please report this issue.": "",
|
||||
"here": "",
|
||||
"left module": "",
|
||||
"right module": "",
|
||||
|
||||
@@ -33,7 +33,7 @@
|
||||
"Please move both sticks to the <b>bottom-right corner</b> and release them.": "Kérlek, mozgasd mindkét hüvelykujjkart átlósan a <b>jobb alsó sarokba</b>, és engedd el őket.",
|
||||
"Calibration completed successfully!": "A kalibrálás sikeresen befejeződött!",
|
||||
"Next": "Következő",
|
||||
"Recentering the controller sticks. ": "A kontroller hüvelykujjkar középállásának újrakalibrálása. ",
|
||||
"Recentering the controller sticks.": "A kontroller hüvelykujjkar középállásának újrakalibrálása.",
|
||||
"Please do not close this window and do not disconnect your controller. ": "Kérlek, ne zárd be ezt az ablakot, és ne válaszd le a kontrollert. ",
|
||||
"Range calibration": "Elmozdulási tartomány kalibrálása",
|
||||
"<b>The controller is now sampling data!</b>": "<b>A kontroller most az adatokat mintavételezi!</b>",
|
||||
@@ -57,16 +57,16 @@
|
||||
"SW Version": "SW verzió",
|
||||
"Device Type": "Eszköz típusa",
|
||||
"Range calibration completed": "A tartománykalibráció befejeződött",
|
||||
"Range calibration failed: ": "A tartománykalibráció meghiúsult: ",
|
||||
"Range calibration failed": "A tartománykalibráció meghiúsult",
|
||||
"Cannot unlock NVS": "NVS feloldása nem lehetséges",
|
||||
"Cannot relock NVS": "NVS újbóli zárolása nem lehetséges",
|
||||
"Error 1": "Hiba 1",
|
||||
"Error 2": "Hiba 2",
|
||||
"Error 3": "Hiba 3",
|
||||
"Stick calibration failed: ": "Hüvelykujjkar kalibrálása sikertelen: ",
|
||||
"Stick calibration failed": "Hüvelykujjkar kalibrálása sikertelen",
|
||||
"Stick calibration completed": "Hüvelykujjkar kalibrálása befejeződött",
|
||||
"NVS Lock failed: ": "NVS zárolása sikertelen: ",
|
||||
"NVS Unlock failed: ": "NVS feloldása sikertelen: ",
|
||||
"NVS Lock failed": "NVS zárolása sikertelen",
|
||||
"NVS Unlock failed": "NVS feloldása sikertelen",
|
||||
"Please connect only one controller at time.": "Kérlek, egyidejűleg csak egy kontrollert csatlakoztass.",
|
||||
"Sony DualShock 4 V1": "Sony DualShock 4 V1",
|
||||
"Sony DualShock 4 V2": "Sony DualShock 4 V2",
|
||||
@@ -135,12 +135,9 @@
|
||||
"This feature is experimental.": "Ez egy kisérleti funkció",
|
||||
"Please let me know if the board model of your controller is not detected correctly.": "Kérlek értesítsd a fejlesztőt, ha az alaplap verziója nem egyezik meg a felimert verzióval!",
|
||||
"Board model detection thanks to": "Az alaplapfelismerési funkciőért köszönet illeti:",
|
||||
"Please connect the device using a USB cable.": "Kérlek csatlakoztasd az eszközt USB kábel használatával.",
|
||||
"This DualSense controller has outdated firmware.": "Ennek a DualSense vezérlőnek elavult a firmware-e.",
|
||||
"Please update the firmware and try again.": "Kérlek frissítsd a firmware-t, és próbáld újra.",
|
||||
"Joystick Info": "Analógkar Információ",
|
||||
"Err R:": "Hibaarány J:",
|
||||
"Err L:": "Hibaarány B:",
|
||||
"Check circularity": "Körkörösség ellenőrzése",
|
||||
"Can I reset a permanent calibration to previous calibration?": "Visszaállíthatok egy végleges kalibrációt az előző kalibrációra?",
|
||||
"No.": "Nem",
|
||||
@@ -158,7 +155,7 @@
|
||||
"Make sure to touch the edges of the joystick frame and rotate slowly, preferably in each direction - clockwise and anti-clockwise.": "Ügyelj arra, hogy a hüvelykujjakrok érjenek el a keret széléig és annak mentén forgasd lassan, lehetőleg mindkét irányban - óramutató járásával megegyezően és ellentétesen is.",
|
||||
"Only after you have done that, you click on \"Done\".": "Csak miután ezt megtetted, azután kattints a \"Kész\" gombra.",
|
||||
"Changes saved successfully": "A változások sikeresen mentésre kerültek",
|
||||
"Error while saving changes:": "A változások mentése közben hiba lépett fel",
|
||||
"Error while saving changes": "A változások mentése közben hiba lépett fel",
|
||||
"Save changes permanently": "A változtatások végleges mentése a kontrollerbe",
|
||||
"Reboot controller": "Kontroller újraindítása",
|
||||
"Controller Info": "Információk a kontrollerről",
|
||||
@@ -198,14 +195,15 @@
|
||||
"I'm actively working on adding compatibility, the primary challenge lies in storing data into the stick modules.": "Aktívan dolgozom a kompatibilitás hozzáadásán, a legnagyobb kihívást az adatok hüvelykujjkar modulokba történő tárolása jelenti.",
|
||||
"If this tool has been helpful to you or you want to see DualSense Edge support arrive faster, please consider supporting the project with a": "Ha ez az eszköz hasznos volt számodra, vagy szeretnéd, hogy a DualSense Edge támogatása gyorsabban megérkezzen, kérlek, fontold meg a projekt támogatását",
|
||||
"Thank you for your generosity and support!": "Köszönöm nagylelkűségedet és támogatásodat!",
|
||||
"<b>Externally</b>: by applying +1.8V directly to the visible test point without opening the controller": "<b>Külsőleg</b>: +1,8 V közvetlen alkalmazásával a látható tesztpontra, anélkül, hogy a kontrollert szétszednéd.",
|
||||
"<b>Externally</b>: by applying +1.8V directly to the visible test point without opening the controller.": "<b>Külsőleg</b>: +1,8 V közvetlen alkalmazásával a látható tesztpontra, anélkül, hogy a kontrollert szétszednéd.",
|
||||
"<b>Internally</b>: by soldering a wire from a +1.8V source to the write-protect TP.": "<b>Belsőleg</b>: egy vezeték forrasztásával egy +1,8 V-os forrásból az írásvédelmi tesztponthoz.",
|
||||
"Calibration is being stored in the stick modules.": "A kalibráció mentése a hüvelykujjkar modulokban történik.",
|
||||
"DualSense Edge Calibration": "DualSense Edge kalibráció",
|
||||
"For more info or help, feel free to reach out on Discord.": "További információért vagy segítségért nyugodtan keress fel a Discordon.",
|
||||
"More details and images": "További részletek és képek",
|
||||
"Please connect a DualShock 4, a DualSense or DualSense Edge controller to your computer and press Connect.": "Kérlek, csatlakoztass egy DualShock 4, DualSense vagy DualSense Edge kontrollert a számítógépedhez, és nyomd meg a Csatlakozás gombot.",
|
||||
"Please note: the stick modules on the DS Edge <b>cannot be calibrated via software alone</b>.To store a custom calibration on the stick's internal memory, a <b>hardware modification</b> is required.": "Kérlek, vedd figyelembe: a DS Edge hüvelykujjkar moduljai <b>nem kalibrálhatók kizárólag szoftveresen</b>. <b>Hardveres módosítás</b> szükséges az egyedi kalibrációnak a modulok belső memóriájában történő tárolásához.",
|
||||
"Please note: the stick modules on the DS Edge <b>cannot be calibrated via software alone</b>.": "Kérlek, vedd figyelembe: a DS Edge hüvelykujjkar moduljai <b>nem kalibrálhatók kizárólag szoftveresen</b>.",
|
||||
"To store a custom calibration on the stick's internal memory, a <b>hardware modification</b> is required.": "<b>Hardveres módosítás</b> szükséges az egyedi kalibrációnak a modulok belső memóriájában történő tárolásához.",
|
||||
"Support for calibrating DualSense Edge stick modules is now available as an <b>experimental feature</b>.": "A DualSense Edge hüvelykujjkar modulok kalibrálásának támogatása mostantól <b>kísérleti funkcióként</b> elérhető.",
|
||||
"This involves temporarily disabling write protection by applying <b>+1.8V</b> to a specific test point on each module.": "Ez magában foglalja az írásvédelem ideiglenes letiltását az egyes modulokon található specifikus tesztpont <b>+1,8 V</b>-os betáplálásával.",
|
||||
"This is only for advanced users. If you're not sure what you're doing, please do not attempt it.": "Ez kizárólag haladó felhasználóknak szól. Ha nem vagy biztos abban, hogy mit csinálsz, kérlek, ne próbáld meg.",
|
||||
@@ -222,18 +220,45 @@
|
||||
"Right Module Barcode": "Jobb modul vonalkódja",
|
||||
"left module": "bal modul",
|
||||
"right module": "jobb modul",
|
||||
"30th Anniversary": "",
|
||||
"Astro Bot": "",
|
||||
"Cobalt Blue": "",
|
||||
"Cosmic Red": "",
|
||||
"Galactic Purple": "",
|
||||
"God of War Ragnarok": "",
|
||||
"Grey Camouflage": "",
|
||||
"Midnight Black": "",
|
||||
"Nova Pink": "",
|
||||
"Starlight Blue": "",
|
||||
"Sterling Silver": "",
|
||||
"Volcanic Red": "",
|
||||
"White": "",
|
||||
"30th Anniversary": "30th Anniversary",
|
||||
"Astro Bot": "Astro Bot",
|
||||
"Cobalt Blue": "Cobalt Blue",
|
||||
"Cosmic Red": "Cosmic Red",
|
||||
"Galactic Purple": "Galactic Purple",
|
||||
"God of War Ragnarok": "God of War Ragnarok",
|
||||
"Grey Camouflage": "Grey Camouflage",
|
||||
"Midnight Black": "Midnight Black",
|
||||
"Nova Pink": "Nova Pink",
|
||||
"Starlight Blue": "Starlight Blue",
|
||||
"Sterling Silver": "Sterling Silver",
|
||||
"Volcanic Red": "Volcanic Red",
|
||||
"White": "Fehér",
|
||||
"10x zoom": "",
|
||||
"Calibration": "",
|
||||
"Center (L1)": "",
|
||||
"Chroma Indigo": "",
|
||||
"Chroma Pearl": "",
|
||||
"Chroma Teal": "",
|
||||
"Circularity (R1)": "",
|
||||
"Debug": "",
|
||||
"Error triggering rumble": "",
|
||||
"Fortnite": "",
|
||||
"Info": "",
|
||||
"Move the stick to select it for tuning, then without touching the stick use the D-pad buttons to adjust the center point. Flick it and adjust it again if it is off center or flickers.": "",
|
||||
"Normal": "",
|
||||
"Please release the stick to center position before adjusting with D-pad buttons.": "",
|
||||
"Press L2 to test the strong (left) haptic motor": "",
|
||||
"Press R2 to test the weak (right) haptic motor": "",
|
||||
"Press the D-pad or face buttons in the direction you want the stick position to move.": "",
|
||||
"Push the stick straight up/down/left/right as far as possible.": "",
|
||||
"Show raw numbers": "",
|
||||
"Spider-Man 2": "",
|
||||
"Test the Haptic Motors": "",
|
||||
"Tests": "",
|
||||
"The Last of Us": "",
|
||||
"The device is connected via Bluetooth. Disconnect and reconnect using a USB cable instead.": "",
|
||||
"The motor strength will match how hard you press the trigger": "",
|
||||
"While holding the stick to be adjusted straight up/down/left/right, <em>observe the highlighted value below the circle</em>, then use the D-pad buttons to adjust the value to ±0.99 (just below ±1.00).": "",
|
||||
"Your device might not be a genuine Sony controller. If it is not a clone then please report this issue.": "",
|
||||
"": ""
|
||||
}
|
||||
@@ -33,7 +33,7 @@
|
||||
"Please move both sticks to the <b>bottom-right corner</b> and release them.": "Muovi entrambi gli analogici <b>in basso a destra</b> e rilasciali.",
|
||||
"Calibration completed successfully!": "Calibrazione completata con successo!",
|
||||
"Next": "Avanti",
|
||||
"Recentering the controller sticks. ": "Ricentro gli analogici. ",
|
||||
"Recentering the controller sticks.": "Ricentro gli analogici.",
|
||||
"Please do not close this window and do not disconnect your controller. ": "Non chiudere questa finestra e non disconnettere il controller. ",
|
||||
"Range calibration": "Calibrazione del range",
|
||||
"<b>The controller is now sampling data!</b>": "<b>Il controller sta campionando i dati!</b>",
|
||||
@@ -57,16 +57,16 @@
|
||||
"SW Version": "Versione SW",
|
||||
"Device Type": "Tipo Device",
|
||||
"Range calibration completed": "Calibrazione range completata",
|
||||
"Range calibration failed: ": "Calibrazione range fallita: ",
|
||||
"Range calibration failed": "Calibrazione range fallita",
|
||||
"Cannot unlock NVS": "Impossibile sbloccare NVS",
|
||||
"Cannot relock NVS": "Impossibile ribloccare NVS",
|
||||
"Error 1": "Errore 1",
|
||||
"Error 2": "Errore 2",
|
||||
"Error 3": "Errore 3",
|
||||
"Stick calibration failed: ": "Calibrazione analogici fallita: ",
|
||||
"Stick calibration failed": "Calibrazione analogici fallita",
|
||||
"Stick calibration completed": "Calibrazione analogici completata",
|
||||
"NVS Lock failed: ": "Blocco NVS fallito: ",
|
||||
"NVS Unlock failed: ": "Sblocco NVS fallito: ",
|
||||
"NVS Lock failed": "Blocco NVS fallito",
|
||||
"NVS Unlock failed": "Sblocco NVS fallito",
|
||||
"Please connect only one controller at time.": "Connettere un solo controller alla volta, grazie.",
|
||||
"Sony DualShock 4 V1": "Sony DualShock 4 V1",
|
||||
"Sony DualShock 4 V2": "Sony DualShock 4 V2",
|
||||
@@ -134,12 +134,9 @@
|
||||
"This feature is experimental.": "Questa funzionalità è sperimentale.",
|
||||
"Please let me know if the board model of your controller is not detected correctly.": "Scrivimi se il modello della scheda del tuo controller non viene riconosciuto correttamente.",
|
||||
"Board model detection thanks to": "Rilevamento del modello della scheda grazie a",
|
||||
"Please connect the device using a USB cable.": "Connetti il controller usando un cavo USB.",
|
||||
"This DualSense controller has outdated firmware.": "Questo controller DualSense ha un firmware non aggiornato.",
|
||||
"Please update the firmware and try again.": "Aggiorna il firmware e riprova.",
|
||||
"Joystick Info": "Informazioni sui Joystick",
|
||||
"Err R:": "Err Dx:",
|
||||
"Err L:": "Err Sx:",
|
||||
"Check circularity": "Controlla circolarità",
|
||||
"Can I reset a permanent calibration to previous calibration?": "Posso annullare una calibrazione permanente?",
|
||||
"No.": "No.",
|
||||
@@ -157,7 +154,7 @@
|
||||
"Make sure to touch the edges of the joystick frame and rotate slowly, preferably in each direction - clockwise and anti-clockwise.": "Assicurati di ruotare gli analogici fino a toccare i bordi, preferibilmente in ogni direzione - senso orario e antiorario.",
|
||||
"Only after you have done that, you click on \"Done\".": "Solo dopo che hai fatto questo, clicca \"Fatto\".",
|
||||
"Changes saved successfully": "Modifiche salvate con successo",
|
||||
"Error while saving changes:": "Errore nel salvare le modifiche:",
|
||||
"Error while saving changes": "Errore nel salvare le modifiche:",
|
||||
"Save changes permanently": "Salva i cambiamenti permanentemente",
|
||||
"Reboot controller": "Riavvia il controller",
|
||||
"Controller Info": "Informazioni sul Controller",
|
||||
@@ -197,7 +194,7 @@
|
||||
"I'm actively working on adding compatibility, the primary challenge lies in storing data into the stick modules.": "Sto lavorando attivamente per renderlo compatibile, ma la sfida principale rimane salvare i dati nei moduli degli stick.",
|
||||
"If this tool has been helpful to you or you want to see DualSense Edge support arrive faster, please consider supporting the project with a": "Se questo strumento ti è stato utile o desideri che il supporto per il DualSense Edge arrivi più rapidamente, considera di supportare il progetto con una",
|
||||
"Thank you for your generosity and support!": "Grazie per la tua generosità e per il supporto!",
|
||||
"<b>Externally</b>: by applying +1.8V directly to the visible test point without opening the controller": "<b>Esternamente</b>: applicando +1.8V direttamente al test point visibile senza aprire il controller",
|
||||
"<b>Externally</b>: by applying +1.8V directly to the visible test point without opening the controller.": "<b>Esternamente</b>: applicando +1.8V direttamente al test point visibile senza aprire il controller",
|
||||
"<b>Internally</b>: by soldering a wire from a +1.8V source to the write-protect TP.": "<b>Internamente</b>: saldando un filo da un test point a +1.8V al test point di write-protect.",
|
||||
"Calibration is being stored in the stick modules.": "Sto salvando la calibrazione nei moduli degli stick.",
|
||||
"DualSense Edge Calibration": "Calibrazione del DualSense Edge",
|
||||
@@ -236,5 +233,32 @@
|
||||
"Sterling Silver": "Sterling Silver",
|
||||
"Volcanic Red": "Volcanic Red",
|
||||
"White": "Original White",
|
||||
"Chroma Indigo": "Chroma Indigo",
|
||||
"Chroma Pearl": "Chroma Pearl",
|
||||
"Chroma Teal": "Chroma Teal",
|
||||
"Fortnite": "Fortnite",
|
||||
"Spider-Man 2": "Spider-Man 2",
|
||||
"The Last of Us": "The Last of Us",
|
||||
"10x zoom": "Zoom 10x",
|
||||
"Normal": "Normale",
|
||||
"Calibration": "Calibrazione",
|
||||
"Debug": "Debug",
|
||||
"Error triggering rumble": "Errore nell'avvio della vibrazione",
|
||||
"Info": "Info",
|
||||
"Press L2 to test the strong (left) haptic motor": "Premi L2 per testare il motore forte (sinistro)",
|
||||
"Press R2 to test the weak (right) haptic motor": "Premi R2 per testare il motore debole (destro)",
|
||||
"Test the Haptic Motors": "Testa la vibrazione",
|
||||
"Tests": "Test",
|
||||
"The motor strength will match how hard you press the trigger": "La forza della vibrazione sarà proporzionale alla pressione del trigger",
|
||||
"Center (L1)": "Centro (L1)",
|
||||
"Circularity (R1)": "Circolarità (R1)",
|
||||
"Move the stick to select it for tuning, then without touching the stick use the D-pad buttons to adjust the center point. Flick it and adjust it again if it is off center or flickers.": "Sposta lo stick per selezionarlo per la calibrazione, quindi, senza toccare lo stick, usa i pulsanti del D-pad per regolare il punto centrale. Muovi rapidamente lo stick e regola di nuovo se non è centrato o se sfarfalla.",
|
||||
"Please release the stick to center position before adjusting with D-pad buttons.": "Rilascia lo stick al centro prima di usare i pulsanti del D-pad.",
|
||||
"Press the D-pad or face buttons in the direction you want the stick position to move.": "Premi il D-pad o i pulsanti frontali nella direzione in cui vuoi spostare lo stick.",
|
||||
"Push the stick straight up/down/left/right as far as possible.": "Premi lo stick completamente verso l'alto, il basso, sinistra o destra.",
|
||||
"Show raw numbers": "Mostra i dati raw",
|
||||
"While holding the stick to be adjusted straight up/down/left/right, <em>observe the highlighted value below the circle</em>, then use the D-pad buttons to adjust the value to ±0.99 (just below ±1.00).": "Mentre tieni lo stick da calibrare verso l'alto, il basso, sinistra o destra, <em>osserva il valore evidenziato sotto il cerchio</em>, quindi usa i pulsanti del D-pad per regolare il valore a ±0.99 (appena sotto ±1.00).",
|
||||
"The device is connected via Bluetooth. Disconnect and reconnect using a USB cable instead.": "",
|
||||
"Your device might not be a genuine Sony controller. If it is not a clone then please report this issue.": "",
|
||||
"": ""
|
||||
}
|
||||
}
|
||||
@@ -32,7 +32,7 @@
|
||||
"Please move both sticks to the <b>bottom-right corner</b> and release them.": "両方のスティックを<b>右下の隅</b>に倒して、戻してください。",
|
||||
"Calibration completed successfully!": "キャリブレーションが正常に完了しました!",
|
||||
"Next": "次へ",
|
||||
"Recentering the controller sticks. ": "コントローラのスティックを再センタリングしています。 ",
|
||||
"Recentering the controller sticks.": "コントローラのスティックを再センタリングしています。",
|
||||
"Please do not close this window and do not disconnect your controller. ": "このウインドウを閉じたり、コントローラーを切断したりしないでください。 ",
|
||||
"Range calibration": "範囲キャリブレーション",
|
||||
"<b>The controller is now sampling data!</b>": "<b>コントローラは現在データをサンプリングしています!</b>",
|
||||
@@ -56,16 +56,16 @@
|
||||
"SW Version": "SWバージョン",
|
||||
"Device Type": "デバイスタイプ",
|
||||
"Range calibration completed": "範囲キャリブレーションが完了しました",
|
||||
"Range calibration failed: ": "範囲キャリブレーションに失敗しました:",
|
||||
"Range calibration failed": "範囲キャリブレーションに失敗しました",
|
||||
"Cannot unlock NVS": "NVSをロック解除できません",
|
||||
"Cannot relock NVS": "NVSを再ロックできません",
|
||||
"Error 1": "エラー1",
|
||||
"Error 2": "エラー2",
|
||||
"Error 3": "エラー3",
|
||||
"Stick calibration failed: ": "スティックのキャリブレーションに失敗しました:",
|
||||
"Stick calibration failed": "スティックのキャリブレーションに失敗しました",
|
||||
"Stick calibration completed": "スティックのキャリブレーションが完了しました",
|
||||
"NVS Lock failed: ": "NVSロックに失敗しました:",
|
||||
"NVS Unlock failed: ": "NVSロック解除に失敗しました:",
|
||||
"NVS Lock failed": "NVSロックに失敗しました",
|
||||
"NVS Unlock failed": "NVSロック解除に失敗しました",
|
||||
"Please connect only one controller at time.": "コントローラーは、一度に一つのみ接続してください。",
|
||||
"Sony DualShock 4 V1": "Sony DualShock 4 V1",
|
||||
"Sony DualShock 4 V2": "Sony DualShock 4 V2",
|
||||
@@ -134,12 +134,9 @@
|
||||
"This feature is experimental.": "この機能は実験的です。",
|
||||
"Please let me know if the board model of your controller is not detected correctly.": "コントローラーの基板モデルが正しく検出されない場合はお知らせください。",
|
||||
"Board model detection thanks to": "基板モデルの検出には感謝します",
|
||||
"Please connect the device using a USB cable.": "デバイスをUSBケーブルで接続してください。",
|
||||
"This DualSense controller has outdated firmware.": "このDualSenseコントローラーのファームウェアは古くなっています。",
|
||||
"Please update the firmware and try again.": "ファームウェアを更新してから再試行してください。",
|
||||
"Joystick Info": "ジョイスティック情報",
|
||||
"Err R:": "エラー 右:",
|
||||
"Err L:": "エラー 左:",
|
||||
"Check circularity": "円形を確認",
|
||||
"Finetune stick calibration": "スティックの微調整キャリブレーション",
|
||||
"(beta)": "(ベータ版)",
|
||||
@@ -155,30 +152,39 @@
|
||||
"If this tool has been helpful to you or you want to see DualSense Edge support arrive faster, please consider supporting the project with a": "このツールが役に立った場合、またはDualSense Edgeのサポートを早く実現したい場合は、プロジェクトへの支援をご検討ください。",
|
||||
"Thank you for your generosity and support!": "ご支援とご厚意に感謝します!",
|
||||
"(Dualsense) Will updating the firmware reset calibration?": "",
|
||||
"10x zoom": "",
|
||||
"30th Anniversary": "",
|
||||
"<b>Externally</b>: by applying +1.8V directly to the visible test point without opening the controller": "",
|
||||
"<b>Externally</b>: by applying +1.8V directly to the visible test point without opening the controller.": "",
|
||||
"<b>Internally</b>: by soldering a wire from a +1.8V source to the write-protect TP.": "",
|
||||
"After range calibration, joysticks always go in corners.": "",
|
||||
"Astro Bot": "",
|
||||
"Battery Barcode": "",
|
||||
"Bluetooth Address": "",
|
||||
"Calibration": "",
|
||||
"Calibration is being stored in the stick modules.": "",
|
||||
"Can I reset a permanent calibration to previous calibration?": "",
|
||||
"Can you overwrite a permanent calibration?": "",
|
||||
"Cannot lock": "",
|
||||
"Cannot store data into": "",
|
||||
"Cannot unlock": "",
|
||||
"Center (L1)": "",
|
||||
"Changes saved successfully": "",
|
||||
"Chroma Indigo": "",
|
||||
"Chroma Pearl": "",
|
||||
"Chroma Teal": "",
|
||||
"Circularity (R1)": "",
|
||||
"Cobalt Blue": "",
|
||||
"Color": "",
|
||||
"Color detection thanks to": "",
|
||||
"Controller Info": "",
|
||||
"Cosmic Red": "",
|
||||
"Debug": "",
|
||||
"Debug Info": "",
|
||||
"Debug buttons": "",
|
||||
"Does this software resolve stickdrift?": "",
|
||||
"DualSense Edge Calibration": "",
|
||||
"Error while saving changes:": "",
|
||||
"Error triggering rumble": "",
|
||||
"Error while saving changes": "",
|
||||
"FW Build Date": "",
|
||||
"FW Series": "",
|
||||
"FW Type": "",
|
||||
@@ -186,6 +192,7 @@
|
||||
"FW Update Info": "",
|
||||
"FW Version": "",
|
||||
"For more info or help, feel free to reach out on Discord.": "",
|
||||
"Fortnite": "",
|
||||
"Galactic Purple": "",
|
||||
"God of War Ragnarok": "",
|
||||
"Grey Camouflage": "",
|
||||
@@ -193,30 +200,45 @@
|
||||
"Hardware": "",
|
||||
"I have noticed some controllers out of the box have worse factory calibration than if I would recalibrate them. Especially true for circularity of SCUF controllers with a unique shell.": "",
|
||||
"If the calibration is not stored permanently, please double-check the wirings of the hardware mod.": "",
|
||||
"Info": "",
|
||||
"Left Module Barcode": "",
|
||||
"MCU Unique ID": "",
|
||||
"Make sure to touch the edges of the joystick frame and rotate slowly, preferably in each direction - clockwise and anti-clockwise.": "",
|
||||
"Midnight Black": "",
|
||||
"More details and images": "",
|
||||
"Move the stick to select it for tuning, then without touching the stick use the D-pad buttons to adjust the center point. Flick it and adjust it again if it is off center or flickers.": "",
|
||||
"No.": "",
|
||||
"Normal": "",
|
||||
"Nova Pink": "",
|
||||
"Only after you have done that, you click on \"Done\".": "",
|
||||
"PCBA ID": "",
|
||||
"Please connect a DualShock 4, a DualSense or DualSense Edge controller to your computer and press Connect.": "",
|
||||
"Please note: the stick modules on the DS Edge <b>cannot be calibrated via software alone</b>.To store a custom calibration on the stick's internal memory, a <b>hardware modification</b> is required.": "",
|
||||
"Please read the instructions.": "",
|
||||
"Please release the stick to center position before adjusting with D-pad buttons.": "",
|
||||
"Press L2 to test the strong (left) haptic motor": "",
|
||||
"Press R2 to test the weak (right) haptic motor": "",
|
||||
"Press the D-pad or face buttons in the direction you want the stick position to move.": "",
|
||||
"Push the stick straight up/down/left/right as far as possible.": "",
|
||||
"Reboot controller": "",
|
||||
"Right Module Barcode": "",
|
||||
"SBL FW Version": "",
|
||||
"Save changes permanently": "",
|
||||
"Serial Number": "",
|
||||
"Show all": "",
|
||||
"Show raw numbers": "",
|
||||
"Software": "",
|
||||
"Spider FW Version": "",
|
||||
"Spider-Man 2": "",
|
||||
"Starlight Blue": "",
|
||||
"Sterling Silver": "",
|
||||
"Stickdrift is caused by a physical defect; namely dirt, worn potentiometer or in some cases a worn spring.": "",
|
||||
"Support for calibrating DualSense Edge stick modules is now available as an <b>experimental feature</b>.": "",
|
||||
"Test the Haptic Motors": "",
|
||||
"Tests": "",
|
||||
"The Last of Us": "",
|
||||
"The device is connected via Bluetooth. Disconnect and reconnect using a USB cable instead.": "",
|
||||
"The motor strength will match how hard you press the trigger": "",
|
||||
"This involves temporarily disabling write protection by applying <b>+1.8V</b> to a specific test point on each module.": "",
|
||||
"This is only for advanced users. If you're not sure what you're doing, please do not attempt it.": "",
|
||||
"This issue happens because you have clicked \"Done\" immediately after starting a range calibration.": "",
|
||||
@@ -228,10 +250,12 @@
|
||||
"Venom FW Version": "",
|
||||
"Volcanic Red": "",
|
||||
"We are not responsible for any damage caused by attempting this modification.": "",
|
||||
"While holding the stick to be adjusted straight up/down/left/right, <em>observe the highlighted value below the circle</em>, then use the D-pad buttons to adjust the value to ±0.99 (just below ±1.00).": "",
|
||||
"White": "",
|
||||
"Yes. Simply do another permanent calibration.": "",
|
||||
"You can do this in two ways:": "",
|
||||
"You have to rotate the joysticks before you press \"Done\".": "",
|
||||
"Your device might not be a genuine Sony controller. If it is not a clone then please report this issue.": "",
|
||||
"here": "",
|
||||
"left module": "",
|
||||
"right module": "",
|
||||
|
||||
398
lang/ko_kr.json
398
lang/ko_kr.json
@@ -1,239 +1,263 @@
|
||||
{
|
||||
".authorMsg": "한국어 번역 (제타/NGC224K)",
|
||||
"DualShock Calibration GUI": "듀얼쇼크 보정 GUI",
|
||||
"Unsupported browser. Please use a web browser with WebHID support (e.g. Chrome).": "지원되지 않는 브라우저입니다. WebHID를 지원하는 웹 브라우저(예: Chrome)를 사용하십시오",
|
||||
".authorMsg": "한국어 번역 : 제타",
|
||||
"DualShock Calibration GUI": "DualShock 보정 GUI",
|
||||
"Unsupported browser. Please use a web browser with WebHID support (e.g. Chrome).": "지원하지 않는 브라우저입니다. WebHID를 지원하는 웹 브라우저(예: Chrome)를 사용해주세요.",
|
||||
"Connect": "연결",
|
||||
"Connected to:": "연결 대상:",
|
||||
"Connected to:": "연결된 기기:",
|
||||
"Disconnect": "연결 끊기",
|
||||
"Calibrate stick center": "스틱 중앙 보정",
|
||||
"Calibrate stick range": "스틱 범위 보정",
|
||||
"Sections below are not useful, just some debug infos or manual commands": "다음 섹션은 디버그 정보 및 수동 명령어만 제공하므로 도움이 되지 않습니다",
|
||||
"Sections below are not useful, just some debug infos or manual commands": "아래 항목은 디버그 정보와 수동 명령어로, 일반 사용자에게는 유용하지 않습니다.",
|
||||
"NVS Status": "NVS 상태",
|
||||
"Unknown": "Unknown",
|
||||
"Unknown": "알 수 없음",
|
||||
"Debug buttons": "디버그 버튼",
|
||||
"Query NVS status": "NVS 상태 조회",
|
||||
"NVS unlock": "NVS 잠금 해제",
|
||||
"NVS lock": "NVS 잠금 설정",
|
||||
"Fast calibrate stick center (OLD)": "스틱 중앙 - 빠른 보정 (OLD)",
|
||||
"NVS lock": "NVS 잠금",
|
||||
"Fast calibrate stick center (OLD)": "스틱 중앙 빠른 보정 (구버전)",
|
||||
"Stick center calibration": "스틱 중앙 보정",
|
||||
"Welcome": "환영합니다",
|
||||
"Step 1": "단계1",
|
||||
"Step 2": "단계2",
|
||||
"Step 3": "단계3",
|
||||
"Step 4": "단계4",
|
||||
"Step 1": "1단계",
|
||||
"Step 2": "2단계",
|
||||
"Step 3": "3단계",
|
||||
"Step 4": "4단계",
|
||||
"Completed": "완료",
|
||||
"Welcome to the stick center-calibration wizard!": "스틱 중앙 보정 마법사에 오신 것을 환영합니다!",
|
||||
"This tool will guide you in re-centering the analog sticks of your controller. It consists in four steps: you will be asked to move both sticks in a direction and release them.": "이 도구는 컨트롤러의 아날로그 스틱을 다시 중앙에 위치하도록 안내하며, 4단계로 구성되어 두 스틱을 특정 방향으로 움직인 후 해제하라는 메시지가 표시됩니다.",
|
||||
"Please be aware that, <i>once the calibration is running, it cannot be canceled</i>. Do not close this page or disconnect your controller until is completed.": "보정이 실행되면, <i>취소할 수 없습니다</i>. 완료될 때까지 이 페이지를 닫거나 컨트롤러를 분리하지 마십시오.",
|
||||
"Press <b>Start</b> to begin calibration.": "보정을 시작하려면 <b>시작</b>을 눌러 보정을 시작하십시오.",
|
||||
"Please move both sticks to the <b>top-left corner</b> and release them.": "두 스틱을 <b>왼쪽 상단 모서리</b>로 이동한 후 놓아주세요.",
|
||||
"When the sticks are back in the center, press <b>Continue</b>.": "스틱이 중앙으로 돌아오면 <b>계속하기</b> 버튼을 누릅니다.",
|
||||
"Please move both sticks to the <b>top-right corner</b> and release them.": "두 스틱을 <b>오른쪽 상단 모서리</b>로 이동한 후 놓아주세요.",
|
||||
"Please move both sticks to the <b>bottom-left corner</b> and release them.": "두 스틱을 <b>왼쪽 하단 모서리</b>로 이동한 후 놓아주세요.",
|
||||
"Please move both sticks to the <b>bottom-right corner</b> and release them.": "두 스틱을 <b>오른쪽 하단 모서리</b>로 이동한 후 놓아주세요.",
|
||||
"This tool will guide you in re-centering the analog sticks of your controller. It consists in four steps: you will be asked to move both sticks in a direction and release them.": "이 도구는 컨트롤러 아날로그 스틱의 중앙을 다시 설정하는 과정을 안내합니다. 총 4단계로 구성되며, 각 단계마다 양쪽 스틱을 특정 방향으로 움직였다가 놓으라는 안내가 표시됩니다.",
|
||||
"Please be aware that, <i>once the calibration is running, it cannot be canceled</i>. Do not close this page or disconnect your controller until is completed.": "<i>보정이 시작되면 취소할 수 없습니다</i>. 완료될 때까지 이 페이지를 닫거나 컨트롤러 연결을 해제하지 마십시오.",
|
||||
"Press <b>Start</b> to begin calibration.": "<b>시작</b>을 눌러 보정을 시작하세요.",
|
||||
"Please move both sticks to the <b>top-left corner</b> and release them.": "양쪽 스틱을 <b>왼쪽 위</b> 방향으로 끝까지 민 다음 놓아주세요.",
|
||||
"When the sticks are back in the center, press <b>Continue</b>.": "스틱이 중앙으로 돌아오면 <b>계속</b> 버튼을 누르세요.",
|
||||
"Please move both sticks to the <b>top-right corner</b> and release them.": "양쪽 스틱을 <b>오른쪽 위</b> 방향으로 끝까지 민 다음 놓아주세요.",
|
||||
"Please move both sticks to the <b>bottom-left corner</b> and release them.": "양쪽 스틱을 <b>왼쪽 아래</b> 방향으로 끝까지 민 다음 놓아주세요.",
|
||||
"Please move both sticks to the <b>bottom-right corner</b> and release them.": "양쪽 스틱을 <b>오른쪽 아래</b> 방향으로 끝까지 민 다음 놓아주세요.",
|
||||
"Calibration completed successfully!": "보정이 성공적으로 완료되었습니다!",
|
||||
"Next": "다음",
|
||||
"Recentering the controller sticks. ": "컨트롤러의 스틱을 다시 중심을 잡고 있습니다.",
|
||||
"Please do not close this window and do not disconnect your controller. ": "이 창을 닫지 말고 컨트롤러를 분리하지 마십시오.",
|
||||
"Recentering the controller sticks.": "컨트롤러 스틱 중앙을 다시 설정하는 중입니다.",
|
||||
"Please do not close this window and do not disconnect your controller. ": "이 창을 닫거나 컨트롤러 연결을 해제하지 마십시오.",
|
||||
"Range calibration": "범위 보정",
|
||||
"<b>The controller is now sampling data!</b>": "<b>컨트롤러는 현재 데이터를 샘플링하고 있습니다!</b>",
|
||||
"Rotate the sticks slowly to cover the whole range. Press \"Done\" when completed.": "스틱을 천천히 돌려서 전체 범위를 커버하세요. 끝나면 <b>완료</b>를 누르세요.",
|
||||
"<b>The controller is now sampling data!</b>": "<b>컨트롤러가 데이터 샘플링을 시작했습니다!</b>",
|
||||
"Rotate the sticks slowly to cover the whole range. Press \"Done\" when completed.": "스틱을 천천히 돌려 전체 범위를 인식시키세요. 완료되면 <b>완료</b>를 누르세요.",
|
||||
"Done": "완료",
|
||||
"Hi, thank you for using this software.": "안녕하세요, 이 소프트웨어를 사용해 주셔서 감사합니다.",
|
||||
"If you're finding it helpful and you want to support my efforts, feel free to": "도움을 주시거나 저의 노력을 지원하고 싶으시다면 언제든지 연락주세요.",
|
||||
"buy me a coffee": "커피를 사주세요",
|
||||
"! :)": "! :)",
|
||||
"Do you have any suggestion or issue? Drop me a message via email or discord.": "제안이나 의견이 있으신가요? 이메일이나 디스코드로 알려주세요.",
|
||||
"Cheers!": "건배!",
|
||||
"Support this project": "이 프로젝트 지원",
|
||||
"unknown": "Unknown",
|
||||
"original": "오리지날",
|
||||
"Hi, thank you for using this software.": "안녕하세요, 저희 소프트웨어를 이용해 주셔서 감사합니다.",
|
||||
"If you're finding it helpful and you want to support my efforts, feel free to": "이 프로그램이 도움이 되었고, 개발자를 응원하고 싶으시다면",
|
||||
"buy me a coffee": "커피 한 잔 사주세요",
|
||||
"! :)": "! :)",
|
||||
"Do you have any suggestion or issue? Drop me a message via email or discord.": "제안이나 문제가 있으신가요? 이메일이나 Discord로 메시지를 보내주세요.",
|
||||
"Cheers!": "감사합니다!",
|
||||
"Support this project": "프로젝트 후원하기",
|
||||
"unknown": "알 수 없음",
|
||||
"original": "정품",
|
||||
"clone": "복제품",
|
||||
"locked": "잠김",
|
||||
"unlocked": "잠김 해제",
|
||||
"error": "에러",
|
||||
"unlocked": "잠금 해제",
|
||||
"error": "오류",
|
||||
"Build Date": "빌드 날짜",
|
||||
"HW Version": "HW 버전",
|
||||
"SW Version": "SW 버전",
|
||||
"Device Type": "장치 타입",
|
||||
"HW Version": "하드웨어 버전",
|
||||
"SW Version": "소프트웨어 버전",
|
||||
"Device Type": "기기 종류",
|
||||
"Range calibration completed": "범위 보정이 완료되었습니다.",
|
||||
"Range calibration failed: ": "범위 보정에 실패했습니다:",
|
||||
"Cannot unlock NVS": "NVS를 잠금 해제할 수 없습니다",
|
||||
"Cannot relock NVS": "NVS를 다시 잠글 수 없습니다",
|
||||
"Error 1": "에러 1",
|
||||
"Error 2": "에러 2",
|
||||
"Error 3": "에러 3",
|
||||
"Stick calibration failed: ": "스틱을 보정하지 못했습니다:",
|
||||
"Range calibration failed": "범위 보정에 실패했습니다",
|
||||
"Cannot unlock NVS": "NVS를 잠금 해제할 수 없습니다.",
|
||||
"Cannot relock NVS": "NVS를 다시 잠글 수 없습니다.",
|
||||
"Error 1": "오류 1",
|
||||
"Error 2": "오류 2",
|
||||
"Error 3": "오류 3",
|
||||
"Stick calibration failed": "스틱 보정에 실패했습니다",
|
||||
"Stick calibration completed": "스틱 보정이 완료되었습니다.",
|
||||
"NVS Lock failed: ": "NVS 잠금에 실패했습니다:",
|
||||
"NVS Unlock failed: ": "NVS 잠금 해제에 실패했습니다:",
|
||||
"Please connect only one controller at time.": "한 번에 하나의 컨트롤러만 연결하십시오.",
|
||||
"NVS Lock failed": "NVS 잠금에 실패했습니다",
|
||||
"NVS Unlock failed": "NVS 잠금 해제에 실패했습니다",
|
||||
"Please connect only one controller at time.": "한 번에 하나의 컨트롤러만 연결해주세요.",
|
||||
"Sony DualShock 4 V1": "Sony DualShock 4 V1",
|
||||
"Sony DualShock 4 V2": "Sony DualShock 4 V2",
|
||||
"Sony DualSense": "Sony DualSense",
|
||||
"Sony DualSense Edge": "Sony DualSense Edge",
|
||||
"Connected invalid device: ": "연결된 비활성화 된 장치:",
|
||||
"The device appears to be a DS4 clone. All functionalities are disabled.": "이 장치는 DS4의 복제품인 것 같습니다. 모든 기능이 비활성화되어 있습니다.",
|
||||
"Error: ": "에러:",
|
||||
"My handle on discord is: the_al": "Discord의 내 핸들은 the_al 입니다.",
|
||||
"Initializing...": "초기화...",
|
||||
"Storing calibration...": "보정 저장 중...",
|
||||
"Sampling...": "샘플링...",
|
||||
"Connected invalid device: ": "잘못된 기기가 연결되었습니다:",
|
||||
"The device appears to be a DS4 clone. All functionalities are disabled.": "이 기기는 DS4 복제품으로 보입니다. 모든 기능이 비활성화됩니다.",
|
||||
"Error: ": "오류:",
|
||||
"My handle on discord is: the_al": "제 Discord ID는 the_al 입니다.",
|
||||
"Initializing...": "초기화 중...",
|
||||
"Storing calibration...": "보정 값 저장 중...",
|
||||
"Sampling...": "샘플링 중...",
|
||||
"Calibration in progress": "보정 진행 중",
|
||||
"Start": "시작",
|
||||
"Continue": "진행",
|
||||
"You can check the calibration with the": "보정은 다음에서 확인할 수 있습니다.",
|
||||
"Continue": "계속",
|
||||
"You can check the calibration with the": "다음을 통해 보정 상태를 확인할 수 있습니다:",
|
||||
"Have a nice day :)": "좋은 하루 되세요 :)",
|
||||
"Welcome to the Calibration GUI": "보정 GUI에 오신 것을 환영합니다",
|
||||
"Just few things to know before you can start:": "시작하기 전에 알아야 할 사항:",
|
||||
"This website is not affiliated with Sony, PlayStation & co.": "이 웹사이트는 소니, 플레이스테이션 등과 무관합니다.",
|
||||
"This service is provided without warranty. Use at your own risk.": "이 서비스는 무보증으로 제공됩니다. 자기 책임하에 사용하시기 바랍니다.",
|
||||
"Keep the internal battery of the controller connected and ensure it is well charged. If the battery dies during operations, the controller will be damaged and rendered unusable.": "컨트롤러의 내장 배터리를 연결하고 충분히 충전되었는지 확인하십시오. 작동 중 배터리가 방전되면 컨트롤러가 손상되어 사용할 수 없습니다.",
|
||||
"Before doing the permanent calibration, try the temporary one to ensure that everything is working well.": "영구 보정을 하기 전에 임시 보정을 통해 모든 것이 제대로 작동하는지 확인하십시오.",
|
||||
"Understood": "이해하였습니다.",
|
||||
"Just few things to know before you can start:": "시작하기 전에 몇 가지 알아둘 사항이 있습니다:",
|
||||
"This website is not affiliated with Sony, PlayStation & co.": "이 웹사이트는 Sony, PlayStation 및 관련사와 아무런 관련이 없습니다.",
|
||||
"This service is provided without warranty. Use at your own risk.": "이 서비스는 어떠한 보증도 제공하지 않으며, 사용에 대한 책임은 본인에게 있습니다.",
|
||||
"Keep the internal battery of the controller connected and ensure it is well charged. If the battery dies during operations, the controller will be damaged and rendered unusable.": "컨트롤러의 내장 배터리가 연결되어 있고 충분히 충전되었는지 확인하세요. 작업 중 배터리가 방전되면 컨트롤러가 손상되어 사용할 수 없게 될 수 있습니다.",
|
||||
"Before doing the permanent calibration, try the temporary one to ensure that everything is working well.": "영구 보정을 진행하기 전에, 임시 보정을 먼저 시도하여 모든 것이 정상적으로 작동하는지 확인하세요.",
|
||||
"Understood": "이해했습니다",
|
||||
"Version": "버전",
|
||||
"Frequently Asked Questions": "자주 묻는 질문",
|
||||
"Close": "닫기",
|
||||
"Welcome to the F.A.Q. section! Below, you'll find answers to some of the most commonly asked questions about this website. If you have any other inquiries or need further assistance, feel free to reach out to me directly. Your feedback and questions are always welcome!": "자주 묻는 질문 섹션에 오신 것을 환영합니다! 아래는 이 웹사이트와 관련하여 가장 자주 묻는 질문에 대한 답변입니다. 기타 문의 사항이 있거나 추가 지원이 필요한 경우 직접 문의하시기 바랍니다. 우리는 항상 귀하의 의견과 질문을 환영합니다!",
|
||||
"Welcome to the F.A.Q. section! Below, you'll find answers to some of the most commonly asked questions about this website. If you have any other inquiries or need further assistance, feel free to reach out to me directly. Your feedback and questions are always welcome!": "자주 묻는 질문(F.A.Q.)에 오신 것을 환영합니다! 아래에서 이 웹사이트에 대해 자주 묻는 질문과 답변을 확인하실 수 있습니다. 다른 문의사항이나 추가 지원이 필요하시면 언제든지 직접 연락해주세요. 여러분의 피드백과 질문을 언제나 환영합니다!",
|
||||
"How does it work?": "어떻게 작동하나요?",
|
||||
"Behind the scenes, this website is the culmination of one year of dedicated effort in reverse-engineering DualShock controllers for fun/hobby from a random guy on the internet.": "이 웹사이트는 1년 동안 인터넷에서 무작위 사람들이 재미와 취미를 위해 듀얼쇼크 컨트롤러를 리버스 엔지니어링하는 데 전념한 결과물이다.",
|
||||
"Through": "를 통해",
|
||||
"Behind the scenes, this website is the culmination of one year of dedicated effort in reverse-engineering DualShock controllers for fun/hobby from a random guy on the internet.": "이 웹사이트는 인터넷의 한 유저가 1년 동안 재미와 취미로 DualShock 컨트롤러를 리버스 엔지니어링한 노력의 결실입니다.",
|
||||
"this research": "이 연구",
|
||||
", it was discovered that there exist some undocumented commands on DualShock controllers that can be sent via USB and are used during factory assembly process. If these commands are sent, the controller starts the recalibration of analog sticks.": "DualShock 컨트롤러에는 USB를 통해 전송되고 공장 조립 과정에서 사용되는 몇 가지 문서화되지 않은 명령이 존재한다는 것을 발견했다. 이러한 명령이 전송되면 컨트롤러는 아날로그 스틱의 재보정을 시작합니다.",
|
||||
"While the primary focus of this research wasn't initially centered on recalibration, it became apparent that a service offering this capability could greatly benefit numerous individuals. And thus, here we are.": "이 연구의 주요 초점은 처음에는 재보정에 초점을 맞추지 않았지만, 이 기능을 제공하는 서비스가 많은 사람들에게 큰 혜택을 줄 수 있다는 것이 밝혀졌습니다. 그 결과 여기 있습니다.",
|
||||
"Does the calibration remain effective during gameplay on PS4/PS5?": "PS4/PS5에서 게임 플레이 중에도 보정이 가능한가요?",
|
||||
"Yes, if you tick the checkbox \"Write changes permanently in the controller\". In that case, the calibration is flashed directly in the controller firmware. This ensures that it remains in place regardless of the console it's connected to.": "예, <컨트롤러에 변경 사항을 영구적으로 기록> 확인란을 선택합니다. 이 경우 보정이 컨트롤러 펌웨어에 직접 플래시됩니다. 이렇게 하면 연결된 콘솔에 관계없이 그 자리에 그대로 유지됩니다.",
|
||||
"Is this an officially endorsed service?": "공식적으로 승인된 서비스인가요?",
|
||||
"No, this service is simply a creation by a DualShock enthusiast.": "아니요, 이 서비스는 단순히 DualShock 애호가들이 만든 서비스입니다.",
|
||||
"Does this website detects if a controller is a clone?": "이 웹 사이트는 컨트롤러가 복제되었는지 여부를 감지합니까?",
|
||||
"Yes, only DualShock4 at the moment. This happened because I accidentally purchased some clones, spent time identifying the differences and added this functionality to prevent future deception.": "예, 현재 DualShock4에만 있습니다. 이것은 내가 우연히 몇 개의 복제품 구입하고 차이점을 파악하는 데 시간을 보냈고 향후 오해를 방지하기 위해이 기능을 추가했기 때문입니다.",
|
||||
"Unfortunately, the clones cannot be calibrated anyway, because they only clone the behavior of a DualShock4 during a normal gameplay, not all the undocumented functionalities.": "안타깝게도 복제품은 어느 쪽이든 보정할 수 없습니다. 왜냐하면 그들은 정상적인 게임 플레이 중 DualShock4의 동작만 복제하고, 문서화되지 않은 모든 기능을 복제하지 않기 때문입니다.",
|
||||
"If you want to extend this detection functionality to DualSense, please ship me a fake DualSense and you'll see it in few weeks.": "이 감지 기능을 DualSense로 확장하고 싶다면 가짜 DualSense를 보내주세요. 몇 주 안에 구현됩니다.",
|
||||
"What development is in plan?": "어떤 개발 계획이 있습니까?",
|
||||
"I maintain two separate to-do lists for this project, although the priority has yet to be established.": "이 프로젝트에서는 아직 우선순위가 정해지지 않았지만, 두 개의 별도 ToDo 리스트를 관리하고 있다.",
|
||||
"The first list is about enhancing support for DualShock4 and DualSense controllers:": "첫 번째 목록은 DualShock4 및 DualSense 컨트롤러에 대한 지원 강화에 관한 것이다.",
|
||||
"Implement calibration of L2/R2 triggers.": "L2/R2 트리거의 보정을 구현한다.",
|
||||
"Improve detection of clones, particularly beneficial for those seeking to purchase used controllers with assurance of authenticity.": "복제품 탐지를 개선하고 특히 정품이 보장되는 중고 컨트롤러를 구매하려는 사람들에게 유용합니다.",
|
||||
"Enhance user interface (e.g. provide additional controller information)": "사용자 인터페이스 개선(예: 추가 컨트롤러 정보 제공)",
|
||||
"Add support for recalibrating IMUs.": "IMU 재보정 지원을 추가한다.",
|
||||
"Additionally, explore the possibility of reviving non-functioning DualShock controllers (further discussion available on Discord for interested parties).": "또한, 작동하지 않는 DualShock 컨트롤러의 부활 가능성을 모색합니다(관심 있는 분들은 Discord에서 더 많은 논의가 가능합니다).",
|
||||
"The second list contains new controllers I aim to support:": "두 번째 목록에는 지원되는 새로운 컨트롤러가 포함되어 있습니다:",
|
||||
", it was discovered that there exist some undocumented commands on DualShock controllers that can be sent via USB and are used during factory assembly process. If these commands are sent, the controller starts the recalibration of analog sticks.": "를 통해 DualShock 컨트롤러에 문서화되지 않은 특정 명령어가 존재하며, 이 명령어는 USB를 통해 전송되어 공장 조립 과정에서 사용된다는 사실이 발견되었습니다. 이 명령어를 전송하면 컨트롤러가 아날로그 스틱 재보정을 시작합니다.",
|
||||
"While the primary focus of this research wasn't initially centered on recalibration, it became apparent that a service offering this capability could greatly benefit numerous individuals. And thus, here we are.": "처음에는 재보정이 이 연구의 주된 초점은 아니었지만, 이 기능을 제공하는 서비스가 많은 사람들에게 큰 도움이 될 수 있다는 사실이 명확해졌습니다. 그래서 이 웹사이트를 만들게 되었습니다.",
|
||||
"Does the calibration remain effective during gameplay on PS4/PS5?": "PS4/PS5에서 게임을 할 때도 보정 효과가 유지되나요?",
|
||||
"Yes, if you tick the checkbox \"Write changes permanently in the controller\". In that case, the calibration is flashed directly in the controller firmware. This ensures that it remains in place regardless of the console it's connected to.": "네, \"변경 사항을 컨트롤러에 영구적으로 저장\" 체크박스를 선택하면 됩니다. 이 경우 보정 값이 컨트롤러 펌웨어에 직접 저장되어, 어떤 콘솔에 연결하든 설정이 유지됩니다.",
|
||||
"Is this an officially endorsed service?": "이것은 공식적으로 인증된 서비스인가요?",
|
||||
"No, this service is simply a creation by a DualShock enthusiast.": "아니요, 이 서비스는 한 DualShock 팬이 만든 개인적인 창작물입니다.",
|
||||
"Does this website detects if a controller is a clone?": "이 웹사이트는 컨트롤러가 복제품인지 감지할 수 있나요?",
|
||||
"Yes, only DualShock4 at the moment. This happened because I accidentally purchased some clones, spent time identifying the differences and added this functionality to prevent future deception.": "네, 현재로서는 DualShock 4만 감지할 수 있습니다. 제가 실수로 복제품을 구매하게 되어, 차이점을 파악하는 데 시간을 투자했고, 앞으로 다른 사람들이 속지 않도록 이 기능을 추가했습니다.",
|
||||
"Unfortunately, the clones cannot be calibrated anyway, because they only clone the behavior of a DualShock4 during a normal gameplay, not all the undocumented functionalities.": "안타깝게도 복제품은 보정이 불가능합니다. 일반적인 게임 플레이 동작만 복제할 뿐, 문서화되지 않은 모든 기능까지 복제하지는 않기 때문입니다.",
|
||||
"If you want to extend this detection functionality to DualSense, please ship me a fake DualSense and you'll see it in few weeks.": "DualSense 복제품 감지 기능 추가를 원하신다면, 저에게 가짜 DualSense를 보내주세요. 몇 주 안에 기능을 추가해 드리겠습니다.",
|
||||
"What development is in plan?": "어떤 개발 계획이 있나요?",
|
||||
"I maintain two separate to-do lists for this project, although the priority has yet to be established.": "이 프로젝트에는 두 개의 별도 할 일 목록이 있으며, 아직 우선순위는 정해지지 않았습니다.",
|
||||
"The first list is about enhancing support for DualShock4 and DualSense controllers:": "첫 번째 목록은 DualShock 4 및 DualSense 컨트롤러 지원 강화에 관한 것입니다:",
|
||||
"Implement calibration of L2/R2 triggers.": "L2/R2 트리거 보정 기능 구현",
|
||||
"Improve detection of clones, particularly beneficial for those seeking to purchase used controllers with assurance of authenticity.": "복제품 탐지 기능 개선 (특히 정품 인증이 필요한 중고 컨트롤러 구매자에게 유용)",
|
||||
"Enhance user interface (e.g. provide additional controller information)": "사용자 인터페이스 개선 (예: 추가 컨트롤러 정보 제공)",
|
||||
"Add support for recalibrating IMUs.": "IMU 재보정 지원 추가",
|
||||
"Additionally, explore the possibility of reviving non-functioning DualShock controllers (further discussion available on Discord for interested parties).": "또한, 작동하지 않는 DualShock 컨트롤러를 되살릴 수 있는 가능성 탐색 (관심 있는 분들은 Discord에서 추가 논의 가능)",
|
||||
"The second list contains new controllers I aim to support:": "두 번째 목록은 앞으로 지원할 새로운 컨트롤러들입니다:",
|
||||
"DualSense Edge": "DualSense Edge",
|
||||
"DualShock 3": "DualShock 3",
|
||||
"XBox Controllers": "Xbox 컨트롤러",
|
||||
"Each of these tasks presents both immense interest and significant time investment. To provide context, supporting a new controller typically demands 6-12 months of full-time research, alongside a stroke of good fortune.": "이러한 각 작업은 매우 흥미롭고 많은 시간을 투자해야 합니다. 맥락을 제공하기 위해 새로운 컨트롤러를 지원하려면 일반적으로 6~12개월의 풀타임 연구와 행운이 필요합니다.",
|
||||
"I love this service, it helped me! How can I contribute?": "이 서비스가 마음에 들어요, 도움이 되었어요! 어떻게 기여할 수 있나요?",
|
||||
"I'm glad to hear that you found this helpful! If you're interested in contributing, here are a few ways you can help me:": "이 글이 도움이 되셨다니 다행입니다! 기여하고 싶다면, 다음은 당신이 나를 도울 수있는 몇 가지 방법입니다:",
|
||||
"Consider making a": "다음 사항을 고려하십시오.",
|
||||
"donation": "후원",
|
||||
"to support my late-night caffeine-fueled reverse-engineering efforts.": "밤늦게까지 카페인으로 지탱된 리버스 엔지니어링 작업을 지원하기 위해.",
|
||||
"Ship me a controller you would love to add (send me an email for organization).": "추가하고 싶은 컨트롤러를 보내주세요 (조직을 위해 이메일을 보내주세요).",
|
||||
"Translate this website in your language": "이 웹사이트를 당신의 언어로 번역하세요",
|
||||
", to help more people like you!": "당신과 같은 많은 사람들을 돕기 위해!",
|
||||
"This website uses analytics to improve the service.": "이 웹사이트는 서비스 개선을 위해 분석을 사용하고 있습니다.",
|
||||
"Board Model": "기판 모델",
|
||||
"Each of these tasks presents both immense interest and significant time investment. To provide context, supporting a new controller typically demands 6-12 months of full-time research, alongside a stroke of good fortune.": "각 작업은 매우 흥미롭지만 상당한 시간 투자가 필요합니다. 새로운 컨트롤러를 지원하려면 보통 6~12개월의 전담 연구와 약간의 행운이 필요합니다.",
|
||||
"I love this service, it helped me! How can I contribute?": "이 서비스 정말 마음에 들어요, 큰 도움이 됐습니다! 어떻게 기여할 수 있나요?",
|
||||
"I'm glad to hear that you found this helpful! If you're interested in contributing, here are a few ways you can help me:": "도움이 되셨다니 기쁩니다! 기여하고 싶으시다면 다음과 같은 방법으로 저를 도울 수 있습니다:",
|
||||
"Consider making a": "다음과 같은",
|
||||
"donation": "기부",
|
||||
"to support my late-night caffeine-fueled reverse-engineering efforts.": "를 통해 카페인으로 버티는 저의 밤샘 리버스 엔지니어링 작업을 응원해주세요.",
|
||||
"Ship me a controller you would love to add (send me an email for organization).": "추가하고 싶은 컨트롤러가 있다면 저에게 보내주세요 (자세한 내용은 이메일로 문의).",
|
||||
"Translate this website in your language": "이 웹사이트를 당신의 언어로 번역해주세요",
|
||||
", to help more people like you!": ", 당신과 같은 더 많은 사람들을 돕기 위해!",
|
||||
"This website uses analytics to improve the service.": "이 웹사이트는 서비스 개선을 위해 분석 도구를 사용합니다.",
|
||||
"Board Model": "보드 모델",
|
||||
"This feature is experimental.": "이 기능은 실험적인 기능입니다.",
|
||||
"Please let me know if the board model of your controller is not detected correctly.": "컨트롤러의 기판 모델이 제대로 감지되지 않는 경우 알려주시기 바랍니다.",
|
||||
"Board model detection thanks to": "기판 모델 감지에 감사드립니다",
|
||||
"Please connect the device using a USB cable.": "장치를 USB 케이블로 연결하십시오.",
|
||||
"Please let me know if the board model of your controller is not detected correctly.": "컨트롤러의 보드 모델이 올바르게 감지되지 않으면 알려주세요.",
|
||||
"Board model detection thanks to": "보드 모델 감지 도움:",
|
||||
"This DualSense controller has outdated firmware.": "이 DualSense 컨트롤러의 펌웨어가 오래되었습니다.",
|
||||
"Please update the firmware and try again.": "펌웨어를 업데이트한 후 다시 시도해 보세요.",
|
||||
"Please update the firmware and try again.": "펌웨어를 업데이트한 후 다시 시도해주세요.",
|
||||
"Joystick Info": "조이스틱 정보",
|
||||
"Err R:": "오류 오른쪽:",
|
||||
"Err L:": "오류 왼쪽:",
|
||||
"Check circularity": "원형 확인",
|
||||
"Can I reset a permanent calibration to previous calibration?": "영구 보정을 이전 보정으로 재설정할 수 있나요?",
|
||||
"No.": "아니오.",
|
||||
"Check circularity": "원형성 확인",
|
||||
"Can I reset a permanent calibration to previous calibration?": "영구 보정을 이전 보정 값으로 되돌릴 수 있나요?",
|
||||
"No.": "아니요.",
|
||||
"Can you overwrite a permanent calibration?": "영구 보정을 덮어쓸 수 있나요?",
|
||||
"Yes. Simply do another permanent calibration.": "예. 영구 보정을 한 번 더 수행하기만 하면 됩니다.",
|
||||
"Does this software resolve stickdrift?": "이 소프트웨어로 스틱 쏠림 문제가 해결되나요?",
|
||||
"Stickdrift is caused by a physical defect; namely dirt, worn potentiometer or in some cases a worn spring.": "스틱 쏠림은 먼지, 마모된 포텐셜미터(가변저항) 또는 경우에 따라 마모된 스프링과 같은 물리적 결함으로 인해 발생합니다.",
|
||||
"This software will not fix stick drift on its own if you already experience that. What it will help with, is ensuring the new joystick(s) will function properly after replacing the old one(s) to work well with.": "이미 스틱 쏠림이 발생한 경우 이 소프트웨어로는 저절로 해결되지 않습니다. 이 소프트웨어는 기존 조이스틱을 교체한 후 새 조이스틱이 제대로 작동하는지 확인하는 데 도움이 됩니다.",
|
||||
"I have noticed some controllers out of the box have worse factory calibration than if I would recalibrate them. Especially true for circularity of SCUF controllers with a unique shell.": "일부 컨트롤러는 (생산처)출고 시 보정된 결과보다 보정 상태가 더 나쁘다는 것을 알게 되었습니다. 특히 고유한 셸을 가진 SCUF 컨트롤러의 경우 더욱 그렇습니다.",
|
||||
"(Dualsense) Will updating the firmware reset calibration?": "(듀얼센스) 펌웨어를 업데이트하면 보정이 초기화되나요?",
|
||||
"After range calibration, joysticks always go in corners.": "범위 보정 후 조이스틱은 항상 모서리로 이동합니다.",
|
||||
"This issue happens because you have clicked \"Done\" immediately after starting a range calibration.": "이 문제는 범위 보정을 시작한 직후에 완료를 클릭했기 때문에 발생합니다.",
|
||||
"Please read the instructions.": "지침을 읽어주세요.",
|
||||
"You have to rotate the joysticks before you press \"Done\".": "완료를 누르기 전에 조이스틱을 회전해야 합니다.",
|
||||
"Make sure to touch the edges of the joystick frame and rotate slowly, preferably in each direction - clockwise and anti-clockwise.": "조이스틱 프레임의 가장자리를 터치하고 시계 방향과 시계 반대 방향으로 천천히 회전하는 것이 좋습니다.",
|
||||
"Only after you have done that, you click on \"Done\".": "작업이 마무리된 후에 반드시 완료를 클릭합니다.",
|
||||
"Yes. Simply do another permanent calibration.": "네, 영구 보정을 다시 실행하면 됩니다.",
|
||||
"Does this software resolve stickdrift?": "이 소프트웨어로 스틱 쏠림 현상을 해결할 수 있나요?",
|
||||
"Stickdrift is caused by a physical defect; namely dirt, worn potentiometer or in some cases a worn spring.": "스틱 쏠림은 먼지, 마모된 전위차계(포텐셔미터) 또는 마모된 스프링과 같은 물리적 결함으로 인해 발생합니다.",
|
||||
"This software will not fix stick drift on its own if you already experience that. What it will help with, is ensuring the new joystick(s) will function properly after replacing the old one(s) to work well with.": "이미 스틱 쏠림을 겪고 있다면 이 소프트웨어만으로는 해결되지 않습니다. 하지만 낡은 조이스틱을 교체한 후 새 조이스틱이 제대로 작동하도록 보정하는 데 도움이 될 수 있습니다.",
|
||||
"I have noticed some controllers out of the box have worse factory calibration than if I would recalibrate them. Especially true for circularity of SCUF controllers with a unique shell.": "일부 컨트롤러는 공장 출고 상태보다 재보정했을 때 더 나은 성능을 보였습니다. 특히 독특한 셸을 가진 SCUF 컨트롤러의 원형성에서 더욱 그렇습니다.",
|
||||
"(Dualsense) Will updating the firmware reset calibration?": "(DualSense) 펌웨어를 업데이트하면 보정 값이 초기화되나요?",
|
||||
"After range calibration, joysticks always go in corners.": "범위 보정 후 조이스틱이 항상 가장자리로 쏠려요.",
|
||||
"This issue happens because you have clicked \"Done\" immediately after starting a range calibration.": "이 문제는 범위 보정을 시작하자마자 \"완료\"를 클릭했기 때문에 발생합니다.",
|
||||
"Please read the instructions.": "안내를 제대로 읽어주세요.",
|
||||
"You have to rotate the joysticks before you press \"Done\".": "\"완료\"를 누르기 전에 조이스틱을 돌려야 합니다.",
|
||||
"Make sure to touch the edges of the joystick frame and rotate slowly, preferably in each direction - clockwise and anti-clockwise.": "조이스틱 프레임 가장자리까지 닿도록 천천히, 가급적 시계 방향과 시계 반대 방향으로 모두 돌려주세요.",
|
||||
"Only after you have done that, you click on \"Done\".": "그 과정을 마친 후에 \"완료\"를 클릭해야 합니다.",
|
||||
"Changes saved successfully": "변경 사항이 성공적으로 저장되었습니다.",
|
||||
"Error while saving changes:": "변경 사항을 저장하는 동안 오류가 발생했습니다.",
|
||||
"Save changes permanently": "변경 사항을 영구적으로 저장",
|
||||
"Error while saving changes": "변경 사항 저장 중 오류 발생",
|
||||
"Save changes permanently": "변경 사항 영구 저장",
|
||||
"Reboot controller": "컨트롤러 재부팅",
|
||||
"Controller Info": "컨트롤러 정보",
|
||||
"Debug Info": "디버그 정보",
|
||||
"Software": "소프트웨어",
|
||||
"Hardware": "하드웨어",
|
||||
"FW Build Date": "FW 빌드 날짜",
|
||||
"FW Type": "FW 타입",
|
||||
"FW Series": "FW 시리즈",
|
||||
"FW Version": "FW 버전",
|
||||
"FW Update": "FW 업데이트",
|
||||
"FW Update Info": "FW 업데이트 정보",
|
||||
"SBL FW Version": "SBL FW 버전",
|
||||
"Venom FW Version": "Venom FW 버전",
|
||||
"Spider FW Version": "Spider FW 버전",
|
||||
"Touchpad FW Version": "Touchpad FW 버전",
|
||||
"Serial Number": "Serial Number",
|
||||
"MCU Unique ID": "MCU Unique ID",
|
||||
"FW Build Date": "펌웨어 빌드 날짜",
|
||||
"FW Type": "펌웨어 타입",
|
||||
"FW Series": "펌웨어 시리즈",
|
||||
"FW Version": "펌웨어 버전",
|
||||
"FW Update": "펌웨어 업데이트",
|
||||
"FW Update Info": "펌웨어 업데이트 정보",
|
||||
"SBL FW Version": "SBL 펌웨어 버전",
|
||||
"Venom FW Version": "Venom 펌웨어 버전",
|
||||
"Spider FW Version": "Spider 펌웨어 버전",
|
||||
"Touchpad FW Version": "터치패드 펌웨어 버전",
|
||||
"Serial Number": "시리얼 번호",
|
||||
"MCU Unique ID": "MCU 고유 ID",
|
||||
"PCBA ID": "PCBA ID",
|
||||
"Battery Barcode": "Battery Barcode",
|
||||
"VCM Left Barcode": "VCM Left Barcode",
|
||||
"VCM Right Barcode": "VCM Right Barcode",
|
||||
"HW Model": "HW Model",
|
||||
"Touchpad ID": "Touchpad ID",
|
||||
"Bluetooth Address": "Bluetooth Address",
|
||||
"Battery Barcode": "배터리 바코드",
|
||||
"VCM Left Barcode": "VCM 왼쪽 바코드",
|
||||
"VCM Right Barcode": "VCM 오른쪽 바코드",
|
||||
"HW Model": "하드웨어 모델",
|
||||
"Touchpad ID": "터치패드 ID",
|
||||
"Bluetooth Address": "블루투스 주소",
|
||||
"Show all": "모두 보기",
|
||||
"(beta)": "",
|
||||
"30th Anniversary": "",
|
||||
"<b>Externally</b>: by applying +1.8V directly to the visible test point without opening the controller": "",
|
||||
"<b>Internally</b>: by soldering a wire from a +1.8V source to the write-protect TP.": "",
|
||||
"Astro Bot": "",
|
||||
"Calibration is being stored in the stick modules.": "",
|
||||
"Cancel": "",
|
||||
"Cannot lock": "",
|
||||
"Cannot store data into": "",
|
||||
"Cannot unlock": "",
|
||||
"Center X": "",
|
||||
"Center Y": "",
|
||||
"Cobalt Blue": "",
|
||||
"Color": "",
|
||||
"Color detection thanks to": "",
|
||||
"Cosmic Red": "",
|
||||
"DualSense Edge Calibration": "",
|
||||
"Finetune stick calibration": "",
|
||||
"For more info or help, feel free to reach out on Discord.": "",
|
||||
"Galactic Purple": "",
|
||||
"God of War Ragnarok": "",
|
||||
"Grey Camouflage": "",
|
||||
"I'm actively working on adding compatibility, the primary challenge lies in storing data into the stick modules.": "",
|
||||
"If the calibration is not stored permanently, please double-check the wirings of the hardware mod.": "",
|
||||
"If this tool has been helpful to you or you want to see DualSense Edge support arrive faster, please consider supporting the project with a": "",
|
||||
"Left Module Barcode": "",
|
||||
"Left stick": "",
|
||||
"Midnight Black": "",
|
||||
"More details and images": "",
|
||||
"Nova Pink": "",
|
||||
"Please connect a DualShock 4, a DualSense or DualSense Edge controller to your computer and press Connect.": "",
|
||||
"Please note: the stick modules on the DS Edge <b>cannot be calibrated via software alone</b>.To store a custom calibration on the stick's internal memory, a <b>hardware modification</b> is required.": "",
|
||||
"Right Module Barcode": "",
|
||||
"Right stick": "",
|
||||
"Save": "",
|
||||
"Starlight Blue": "",
|
||||
"Sterling Silver": "",
|
||||
"Support for calibrating DualSense Edge stick modules is now available as an <b>experimental feature</b>.": "",
|
||||
"Thank you for your generosity and support!": "",
|
||||
"The DualShock Calibration GUI does not currently support the DualSense Edge.": "",
|
||||
"This involves temporarily disabling write protection by applying <b>+1.8V</b> to a specific test point on each module.": "",
|
||||
"This is only for advanced users. If you're not sure what you're doing, please do not attempt it.": "",
|
||||
"This screen allows to finetune raw calibration data on your controller": "",
|
||||
"Volcanic Red": "",
|
||||
"We are not responsible for any damage caused by attempting this modification.": "",
|
||||
"White": "",
|
||||
"You can do this in two ways:": "",
|
||||
"here": "",
|
||||
"left module": "",
|
||||
"right module": "",
|
||||
"(beta)": "(베타)",
|
||||
"10x zoom": "10배 줌",
|
||||
"30th Anniversary": "30주년 기념",
|
||||
"<b>Externally</b>: by applying +1.8V directly to the visible test point without opening the controller.": "<b>외부에서</b>: 컨트롤러를 분해하지 않고 보이는 테스트 포인트에 직접 +1.8V를 인가합니다.",
|
||||
"<b>Internally</b>: by soldering a wire from a +1.8V source to the write-protect TP.": "<b>내부에서</b>: +1.8V 소스에서 쓰기 방지 TP까지 와이어를 납땜합니다.",
|
||||
"Astro Bot": "아스트로 봇",
|
||||
"Calibration": "보정",
|
||||
"Calibration is being stored in the stick modules.": "보정 값이 스틱 모듈에 저장되고 있습니다.",
|
||||
"Cancel": "취소",
|
||||
"Cannot lock": "잠글 수 없음",
|
||||
"Cannot store data into": "데이터를 저장할 수 없음:",
|
||||
"Cannot unlock": "잠금 해제할 수 없음",
|
||||
"Center (L1)": "중앙 (L1)",
|
||||
"Center X": "중앙 X",
|
||||
"Center Y": "중앙 Y",
|
||||
"Chroma Indigo": "크로마 인디고",
|
||||
"Chroma Pearl": "크로마 펄",
|
||||
"Chroma Teal": "크로마 틸",
|
||||
"Circularity (R1)": "원형성 (R1)",
|
||||
"Cobalt Blue": "코발트 블루",
|
||||
"Color": "색상",
|
||||
"Color detection thanks to": "색상 감지 도움:",
|
||||
"Cosmic Red": "코스믹 레드",
|
||||
"Debug": "디버그",
|
||||
"DualSense Edge Calibration": "DualSense Edge 보정",
|
||||
"Error triggering rumble": "진동 활성화 오류",
|
||||
"Finetune stick calibration": "스틱 보정 미세 조정",
|
||||
"For more info or help, feel free to reach out on Discord.": "더 많은 정보나 도움이 필요하시면 Discord로 문의해주세요.",
|
||||
"Fortnite": "포트나이트",
|
||||
"Galactic Purple": "갤럭틱 퍼플",
|
||||
"God of War Ragnarok": "갓 오브 워 라그나로크",
|
||||
"Grey Camouflage": "그레이 카무플라주",
|
||||
"I'm actively working on adding compatibility, the primary challenge lies in storing data into the stick modules.": "호환성 추가 작업을 적극적으로 진행 중이며, 주된 과제는 스틱 모듈에 데이터를 저장하는 것입니다.",
|
||||
"If the calibration is not stored permanently, please double-check the wirings of the hardware mod.": "보정 값이 영구적으로 저장되지 않으면 하드웨어 개조 배선을 다시 확인해주세요.",
|
||||
"If this tool has been helpful to you or you want to see DualSense Edge support arrive faster, please consider supporting the project with a": "이 도구가 도움이 되었거나 DualSense Edge 지원이 더 빨리 이루어지기를 바란다면, 다음을 통해 프로젝트를 후원하는 것을 고려해주세요:",
|
||||
"Info": "정보",
|
||||
"Left Module Barcode": "왼쪽 모듈 바코드",
|
||||
"Left stick": "왼쪽 스틱",
|
||||
"Midnight Black": "미드나이트 블랙",
|
||||
"More details and images": "자세한 내용 및 이미지 더보기",
|
||||
"Move the stick to select it for tuning, then without touching the stick use the D-pad buttons to adjust the center point. Flick it and adjust it again if it is off center or flickers.": "스틱을 움직여 조정할 스틱을 선택한 다음, 스틱을 만지지 않은 상태에서 D-패드 버튼을 사용하여 중앙점을 조정하세요. 스틱을 튕겨보고 중앙에서 벗어나거나 흔들리면 다시 조정하세요.",
|
||||
"Normal": "일반",
|
||||
"Nova Pink": "노바 핑크",
|
||||
"Please connect a DualShock 4, a DualSense or DualSense Edge controller to your computer and press Connect.": "DualShock 4, DualSense 또는 DualSense Edge 컨트롤러를 컴퓨터에 연결하고 '연결'을 누르세요.",
|
||||
"Please note: the stick modules on the DS Edge <b>cannot be calibrated via software alone</b>.To store a custom calibration on the stick's internal memory, a <b>hardware modification</b> is required.": "참고: DS Edge의 스틱 모듈은 <b>소프트웨어만으로는 보정할 수 없습니다</b>. 스틱 내부 메모리에 사용자 지정 보정 값을 저장하려면 <b>하드웨어 개조</b>가 필요합니다.",
|
||||
"Please release the stick to center position before adjusting with D-pad buttons.": "D-패드 버튼으로 조정하기 전에 스틱을 중앙 위치에 놓아주세요.",
|
||||
"Press L2 to test the strong (left) haptic motor": "L2를 눌러 강한 (왼쪽) 햅틱 모터를 테스트하세요",
|
||||
"Press R2 to test the weak (right) haptic motor": "R2를 눌러 약한 (오른쪽) 햅틱 모터를 테스트하세요",
|
||||
"Press the D-pad or face buttons in the direction you want the stick position to move.": "스틱 위치를 이동시키고 싶은 방향으로 D-패드나 페이스 버튼을 누르세요.",
|
||||
"Push the stick straight up/down/left/right as far as possible.": "스틱을 위/아래/왼쪽/오른쪽으로 최대한 밀어주세요.",
|
||||
"Right Module Barcode": "오른쪽 모듈 바코드",
|
||||
"Right stick": "오른쪽 스틱",
|
||||
"Save": "저장",
|
||||
"Show raw numbers": "원시 데이터 보기",
|
||||
"Spider-Man 2": "스파이더맨 2",
|
||||
"Starlight Blue": "스타라이트 블루",
|
||||
"Sterling Silver": "스털링 실버",
|
||||
"Support for calibrating DualSense Edge stick modules is now available as an <b>experimental feature</b>.": "DualSense Edge 스틱 모듈 보정 지원이 이제 <b>실험적인 기능</b>으로 제공됩니다.",
|
||||
"Test the Haptic Motors": "햅틱 모터 테스트",
|
||||
"Tests": "테스트",
|
||||
"Thank you for your generosity and support!": "너그러운 후원에 진심으로 감사드립니다!",
|
||||
"The DualShock Calibration GUI does not currently support the DualSense Edge.": "DualShock 보정 GUI는 현재 DualSense Edge를 지원하지 않습니다.",
|
||||
"The Last of Us": "더 라스트 오브 어스",
|
||||
"The motor strength will match how hard you press the trigger": "트리거를 누르는 강도에 따라 모터의 세기가 조절됩니다.",
|
||||
"This involves temporarily disabling write protection by applying <b>+1.8V</b> to a specific test point on each module.": "이를 위해서는 각 모듈의 특정 테스트 포인트에 <b>+1.8V</b>를 인가하여 쓰기 방지를 일시적으로 비활성화해야 합니다.",
|
||||
"This is only for advanced users. If you're not sure what you're doing, please do not attempt it.": "이 기능은 고급 사용자 전용입니다. 잘 모르는 경우 시도하지 마십시오.",
|
||||
"This screen allows to finetune raw calibration data on your controller": "이 화면에서 컨트롤러의 원시 보정 데이터를 미세 조정할 수 있습니다.",
|
||||
"Volcanic Red": "볼캐닉 레드",
|
||||
"We are not responsible for any damage caused by attempting this modification.": "이 개조 시도로 인해 발생하는 어떠한 손상에 대해서도 책임지지 않습니다.",
|
||||
"While holding the stick to be adjusted straight up/down/left/right, <em>observe the highlighted value below the circle</em>, then use the D-pad buttons to adjust the value to ±0.99 (just below ±1.00).": "조정할 스틱을 위/아래/왼쪽/오른쪽으로 똑바로 잡은 상태에서 <em>원 아래에 강조 표시된 값</em>을 확인한 다음 D-패드 버튼을 사용하여 값을 ±0.99(±1.00 바로 아래)로 조정하세요.",
|
||||
"White": "화이트",
|
||||
"You can do this in two ways:": "두 가지 방법으로 할 수 있습니다:",
|
||||
"here": "여기",
|
||||
"left module": "왼쪽 모듈",
|
||||
"right module": "오른쪽 모듈",
|
||||
"The device is connected via Bluetooth. Disconnect and reconnect using a USB cable instead.": "",
|
||||
"Through": "",
|
||||
"Your device might not be a genuine Sony controller. If it is not a clone then please report this issue.": "",
|
||||
"": ""
|
||||
}
|
||||
@@ -32,7 +32,7 @@
|
||||
"Please move both sticks to the <b>bottom-right corner</b> and release them.": "Verplaats alstublieft beide sticks in de <b>rechter onderhoek</b> en laat ze los.",
|
||||
"Calibration completed successfully!": "Kalibratie succesvol voltooid!",
|
||||
"Next": "Next",
|
||||
"Recentering the controller sticks. ": "Her-centreer de controller sticks. ",
|
||||
"Recentering the controller sticks.": "Her-centreer de controller sticks.",
|
||||
"Please do not close this window and do not disconnect your controller. ": "Sluit dit venster niet en koppel uw controller niet los. ",
|
||||
"Range calibration": "Bereik kalibratie",
|
||||
"<b>The controller is now sampling data!</b>": "<b>De controller verzamelt nu gegevens!</b>",
|
||||
@@ -56,16 +56,16 @@
|
||||
"SW Version": "SW-versie",
|
||||
"Device Type": "Apparaat type",
|
||||
"Range calibration completed": "Kalibratie van het bereik is voltooid",
|
||||
"Range calibration failed: ": " Kalibratie van het bereik is mislukt: ",
|
||||
"Range calibration failed": " Kalibratie van het bereik is mislukt",
|
||||
"Cannot unlock NVS": " Kan NVS niet ontgrendelen",
|
||||
"Cannot relock NVS": "Kan NVS niet opnieuw vergrendelen",
|
||||
"Error 1": "Fout 1",
|
||||
"Error 2": "Fout 2",
|
||||
"Error 3": "Fout 3",
|
||||
"Stick calibration failed: ": "Stick kalibratie mislukt: ",
|
||||
"Stick calibration failed": "Stick kalibratie mislukt",
|
||||
"Stick calibration completed": "Stick kalibratie voltooid",
|
||||
"NVS Lock failed: ": "NVS vergrendeling mislukt: ",
|
||||
"NVS Unlock failed: ": "NVS ontgrendeling mislukt: ",
|
||||
"NVS Lock failed": "NVS vergrendeling mislukt",
|
||||
"NVS Unlock failed": "NVS ontgrendeling mislukt",
|
||||
"Please connect only one controller at time.": "Sluit slechts één controller tegelijk aan.",
|
||||
"Sony DualShock 4 V1": "Sony DualShock 4 V1",
|
||||
"Sony DualShock 4 V2": "Sony DualShock 4 V2",
|
||||
@@ -134,22 +134,21 @@
|
||||
"This feature is experimental.": "Deze functie is experimenteel.",
|
||||
"Please let me know if the board model of your controller is not detected correctly.": "Laat het me weten als het model van uw controller niet correct wordt gedetecteerd.",
|
||||
"Board model detection thanks to": "Bordmodel detectie dankzij",
|
||||
"Please connect the device using a USB cable.": "Sluit het apparaat aan met een USB-kabel.",
|
||||
"This DualSense controller has outdated firmware.": "Deze DualSense-controller heeft verouderde firmware.",
|
||||
"Please update the firmware and try again.": "Update de firmware en probeer het opnieuw.",
|
||||
"Joystick Info": "Joystick Info",
|
||||
"Err R:": "Err R:",
|
||||
"Err L:": "Err L:",
|
||||
"Check circularity": "Controleer de circulariteit",
|
||||
"(Dualsense) Will updating the firmware reset calibration?": "",
|
||||
"(beta)": "",
|
||||
"10x zoom": "",
|
||||
"30th Anniversary": "",
|
||||
"<b>Externally</b>: by applying +1.8V directly to the visible test point without opening the controller": "",
|
||||
"<b>Externally</b>: by applying +1.8V directly to the visible test point without opening the controller.": "",
|
||||
"<b>Internally</b>: by soldering a wire from a +1.8V source to the write-protect TP.": "",
|
||||
"After range calibration, joysticks always go in corners.": "",
|
||||
"Astro Bot": "",
|
||||
"Battery Barcode": "",
|
||||
"Bluetooth Address": "",
|
||||
"Calibration": "",
|
||||
"Calibration is being stored in the stick modules.": "",
|
||||
"Can I reset a permanent calibration to previous calibration?": "",
|
||||
"Can you overwrite a permanent calibration?": "",
|
||||
@@ -157,19 +156,26 @@
|
||||
"Cannot lock": "",
|
||||
"Cannot store data into": "",
|
||||
"Cannot unlock": "",
|
||||
"Center (L1)": "",
|
||||
"Center X": "",
|
||||
"Center Y": "",
|
||||
"Changes saved successfully": "",
|
||||
"Chroma Indigo": "",
|
||||
"Chroma Pearl": "",
|
||||
"Chroma Teal": "",
|
||||
"Circularity (R1)": "",
|
||||
"Cobalt Blue": "",
|
||||
"Color": "",
|
||||
"Color detection thanks to": "",
|
||||
"Controller Info": "",
|
||||
"Cosmic Red": "",
|
||||
"Debug": "",
|
||||
"Debug Info": "",
|
||||
"Debug buttons": "",
|
||||
"Does this software resolve stickdrift?": "",
|
||||
"DualSense Edge Calibration": "",
|
||||
"Error while saving changes:": "",
|
||||
"Error triggering rumble": "",
|
||||
"Error while saving changes": "",
|
||||
"FW Build Date": "",
|
||||
"FW Series": "",
|
||||
"FW Type": "",
|
||||
@@ -178,6 +184,7 @@
|
||||
"FW Version": "",
|
||||
"Finetune stick calibration": "",
|
||||
"For more info or help, feel free to reach out on Discord.": "",
|
||||
"Fortnite": "",
|
||||
"Galactic Purple": "",
|
||||
"God of War Ragnarok": "",
|
||||
"Grey Camouflage": "",
|
||||
@@ -187,19 +194,27 @@
|
||||
"I'm actively working on adding compatibility, the primary challenge lies in storing data into the stick modules.": "",
|
||||
"If the calibration is not stored permanently, please double-check the wirings of the hardware mod.": "",
|
||||
"If this tool has been helpful to you or you want to see DualSense Edge support arrive faster, please consider supporting the project with a": "",
|
||||
"Info": "",
|
||||
"Left Module Barcode": "",
|
||||
"Left stick": "",
|
||||
"MCU Unique ID": "",
|
||||
"Make sure to touch the edges of the joystick frame and rotate slowly, preferably in each direction - clockwise and anti-clockwise.": "",
|
||||
"Midnight Black": "",
|
||||
"More details and images": "",
|
||||
"Move the stick to select it for tuning, then without touching the stick use the D-pad buttons to adjust the center point. Flick it and adjust it again if it is off center or flickers.": "",
|
||||
"No.": "",
|
||||
"Normal": "",
|
||||
"Nova Pink": "",
|
||||
"Only after you have done that, you click on \"Done\".": "",
|
||||
"PCBA ID": "",
|
||||
"Please connect a DualShock 4, a DualSense or DualSense Edge controller to your computer and press Connect.": "",
|
||||
"Please note: the stick modules on the DS Edge <b>cannot be calibrated via software alone</b>.To store a custom calibration on the stick's internal memory, a <b>hardware modification</b> is required.": "",
|
||||
"Please read the instructions.": "",
|
||||
"Please release the stick to center position before adjusting with D-pad buttons.": "",
|
||||
"Press L2 to test the strong (left) haptic motor": "",
|
||||
"Press R2 to test the weak (right) haptic motor": "",
|
||||
"Press the D-pad or face buttons in the direction you want the stick position to move.": "",
|
||||
"Push the stick straight up/down/left/right as far as possible.": "",
|
||||
"Reboot controller": "",
|
||||
"Right Module Barcode": "",
|
||||
"Right stick": "",
|
||||
@@ -208,14 +223,21 @@
|
||||
"Save changes permanently": "",
|
||||
"Serial Number": "",
|
||||
"Show all": "",
|
||||
"Show raw numbers": "",
|
||||
"Software": "",
|
||||
"Spider FW Version": "",
|
||||
"Spider-Man 2": "",
|
||||
"Starlight Blue": "",
|
||||
"Sterling Silver": "",
|
||||
"Stickdrift is caused by a physical defect; namely dirt, worn potentiometer or in some cases a worn spring.": "",
|
||||
"Support for calibrating DualSense Edge stick modules is now available as an <b>experimental feature</b>.": "",
|
||||
"Test the Haptic Motors": "",
|
||||
"Tests": "",
|
||||
"Thank you for your generosity and support!": "",
|
||||
"The DualShock Calibration GUI does not currently support the DualSense Edge.": "",
|
||||
"The Last of Us": "",
|
||||
"The device is connected via Bluetooth. Disconnect and reconnect using a USB cable instead.": "",
|
||||
"The motor strength will match how hard you press the trigger": "",
|
||||
"This involves temporarily disabling write protection by applying <b>+1.8V</b> to a specific test point on each module.": "",
|
||||
"This is only for advanced users. If you're not sure what you're doing, please do not attempt it.": "",
|
||||
"This issue happens because you have clicked \"Done\" immediately after starting a range calibration.": "",
|
||||
@@ -228,10 +250,12 @@
|
||||
"Venom FW Version": "",
|
||||
"Volcanic Red": "",
|
||||
"We are not responsible for any damage caused by attempting this modification.": "",
|
||||
"While holding the stick to be adjusted straight up/down/left/right, <em>observe the highlighted value below the circle</em>, then use the D-pad buttons to adjust the value to ±0.99 (just below ±1.00).": "",
|
||||
"White": "",
|
||||
"Yes. Simply do another permanent calibration.": "",
|
||||
"You can do this in two ways:": "",
|
||||
"You have to rotate the joysticks before you press \"Done\".": "",
|
||||
"Your device might not be a genuine Sony controller. If it is not a clone then please report this issue.": "",
|
||||
"here": "",
|
||||
"left module": "",
|
||||
"right module": "",
|
||||
|
||||
129
lang/pl_pl.json
129
lang/pl_pl.json
@@ -1,10 +1,10 @@
|
||||
{
|
||||
".authorMsg": "Tłumaczenie na język polski wykonał - Marekk2k :)",
|
||||
".authorMsg": "Tłumaczenie na język polski wykonał <a href='https://github.com/Marekk2k'>Marekk</a> update zrobiony przez <a href='https://github.com/GoomisPL'>GoomisPL</a>",
|
||||
"DualShock Calibration GUI": "DualShock Calibration GUI",
|
||||
"Unsupported browser. Please use a web browser with WebHID support (e.g. Chrome).": "Nie wspierana przeglądarka! Proszę użyć przeglądarki internetowej wpierającą WebHID (np. Chrome).",
|
||||
"Connect": "Połącz",
|
||||
"Connected to:": "Połączono z:",
|
||||
"Disconnect": "Rozłącz",
|
||||
"Disconnect": "Rozłącz kontroler",
|
||||
"Calibrate stick center": "Skalibruj centralny punkt drążków",
|
||||
"Calibrate stick range": "Skalibruj maksymalny zakres drążków",
|
||||
"Reset controller": "Zresetuj kontroler",
|
||||
@@ -34,7 +34,7 @@
|
||||
"Please move both sticks to the <b>bottom-right corner</b> and release them.": "Proszę przesuń oba drążki maksymalnie do <b>prawy-dolny-róg</b> a następnie je puść.",
|
||||
"Calibration completed successfully!": "Kalibracja została wykonana pomyślnie!",
|
||||
"Next": "Dalej",
|
||||
"Recentering the controller sticks. ": "Ponowne centrowanie drążków kontrolera. ",
|
||||
"Recentering the controller sticks.": "Ponowne centrowanie drążków kontrolera.",
|
||||
"Please do not close this window and do not disconnect your controller. ": "Proszę nie zamykaj tego okna, ani nie odłączaj swojego kontrolera. ",
|
||||
"Range calibration": "Kalibracja maksymalnego zakresu drążków",
|
||||
"<b>The controller is now sampling data!</b>": "<b>Kontroler zbiera teraz dane!</b>",
|
||||
@@ -58,16 +58,16 @@
|
||||
"SW Version": "Wersja SW",
|
||||
"Device Type": "Rodzaj urządzenia",
|
||||
"Range calibration completed": "Kalibracja maksymalnego zakresu drążków została zakończona pomyślnie",
|
||||
"Range calibration failed: ": "Kalibracja maksymalnego zakresu drążków została nieuadana: ",
|
||||
"Range calibration failed": "Kalibracja maksymalnego zakresu drążków została nieuadana",
|
||||
"Cannot unlock NVS": "Nie można odblokować NVS",
|
||||
"Cannot relock NVS": "Nie można ponownie zablokować NVS",
|
||||
"Error 1": "Błąd 1",
|
||||
"Error 2": "Błąd 2",
|
||||
"Error 3": "Błąd 3",
|
||||
"Stick calibration failed: ": "Kalibracja drążków nie powiodła się: ",
|
||||
"Stick calibration failed": "Kalibracja drążków nie powiodła się",
|
||||
"Stick calibration completed": "Kalibracja drążków powiodła się",
|
||||
"NVS Lock failed: ": "Blokada NVS nie powiodła się: ",
|
||||
"NVS Unlock failed: ": "Odblokowanie NVS nie powiodło się: ",
|
||||
"NVS Lock failed": "Blokada NVS nie powiodła się",
|
||||
"NVS Unlock failed": "Odblokowanie NVS nie powiodło się",
|
||||
"Please connect only one controller at time.": "Proszę podłączyć tylko jeden kontoler.",
|
||||
"Sony DualShock 4 V1": "Sony DualShock 4 V1",
|
||||
"Sony DualShock 4 V2": "Sony DualShock 4 V2",
|
||||
@@ -100,7 +100,7 @@
|
||||
"Behind the scenes, this website is the culmination of one year of dedicated effort in reverse-engineering DualShock controllers for fun/hobby from a random guy on the internet.": "Za kulisami ta witryna internetowa jest wynikiem całorocznych wysiłków związanych z inżynierią wsteczną kontrolerów DualShock dla zabawy/hobby jakiegoś przypadkowego faceta w Internecie.",
|
||||
"Through": "Poprzez",
|
||||
"this research": "badania",
|
||||
", it was discovered that there exist some undocumented commands on DualShock controllers that can be sent via USB and are used during factory assembly process. If these commands are sent, the controller starts the recalibration of analog sticks.": "odkryto, że w kontrolerach DualShock znajdują się pewne nieudokumentowane polecenia, które można wysyłać przez USB i wykorzystywać w procesie produkcyjnym. Po wysłaniu tych poleceń sterownik rozpoczyna ponowną kalibrację drążków.",
|
||||
", it was discovered that there exist some undocumented commands on DualShock controllers that can be sent via USB and are used during factory assembly process. If these commands are sent, the controller starts the recalibration of analog sticks.": "odkryto, że w kontrolerach DualShock, oraz Dualsense znajdują się pewne nieudokumentowane polecenia, które można wysyłać poprzez USB i wykorzystywać je w procesie produkcyjnym. Po wysłaniu tych poleceń sterownik rozpoczyna ponowną kalibrację drążków.",
|
||||
"While the primary focus of this research wasn't initially centered on recalibration, it became apparent that a service offering this capability could greatly benefit numerous individuals. And thus, here we are.": "Chociaż początkowo główny nacisk w tych badaniach nie skupiał się na ponownej kalibracji, stało się jasne, że usługa oferująca taką możliwość może przynieść ogromne korzyści wielu osobom. I tak oto jesteśmy.",
|
||||
"Does the calibration remain effective during gameplay on PS4/PS5?": "Czy kalibracja pozostaje skuteczna podczas gry na PS4/PS5?",
|
||||
"Yes, if you tick the checkbox \"Write changes permanently in the controller\". In that case, the calibration is flashed directly in the controller firmware. This ensures that it remains in place regardless of the console it's connected to.": "Tak, jeśli zaznaczysz w checkbox \"Zapisz zmiany na stałe w kontrolerze\" W takim przypadku kalibracja zostanie wczytana bezpośrednio w oprogramowaniu sterownika. Dzięki temu pozostanie na swoim miejscu niezależnie od konsoli, do której jest podłączony.",
|
||||
@@ -134,14 +134,11 @@
|
||||
"This website uses analytics to improve the service.": "Ta strona korzysta z analiz w celu ulepszenia usług.",
|
||||
"Board Model": "Model płytki",
|
||||
"This feature is experimental.": "Ta funkcja jest eksperymentalna.",
|
||||
"Please let me know if the board model of your controller is not detected correctly.": "Proszę daj mi znać jaki model płytki kontrolera nie został wykryty poprawnie",
|
||||
"Board model detection thanks to": "Podziękowania dla osoby która wykryła model płytki",
|
||||
"Please connect the device using a USB cable.": "Proszę podłącz urządzenie przy pomocy kabla USB.",
|
||||
"Please let me know if the board model of your controller is not detected correctly.": "Jeżeli model płytki został wykryty błędnie prosimy o kontakt",
|
||||
"Board model detection thanks to": "Podziękowania dla osoby za funkcję wykrywania modelu płytki",
|
||||
"This DualSense controller has outdated firmware.": "Ten kontroler Dualsense posiada przestarzały firmware.",
|
||||
"Please update the firmware and try again.": "Proszę zaktualizuj firmware i spróbuj ponownie.",
|
||||
"Joystick Info": "Informacje o drążkach",
|
||||
"Err R:": "Błędność R",
|
||||
"Err L:": "Błędność L",
|
||||
"Check circularity": "Sprawdź okrężność",
|
||||
"Can I reset a permanent calibration to previous calibration?": "Czy mogę przywrócić stałą kalibrację do poprzedniej kalibracji?",
|
||||
"No.": "Nie.",
|
||||
@@ -159,7 +156,7 @@
|
||||
"Make sure to touch the edges of the joystick frame and rotate slowly, preferably in each direction - clockwise and anti-clockwise.": "Pamiętaj o dotykaniu krawędzi ramki drążka i jego powolnym obracaniu, najlepiej w każdym kierunku – zgodnie z ruchem wskazówek zegara, i na odwrót.",
|
||||
"Only after you have done that, you click on \"Done\".": "Dopiero po wykonaniu tej czynności, kliknij \"Gotowe\".",
|
||||
"Changes saved successfully": "Zmiany zostały zapisane pomyślnie",
|
||||
"Error while saving changes:": "Wystąpił błąd podczas zapisywania zmian",
|
||||
"Error while saving changes": "Wystąpił błąd podczas zapisywania zmian",
|
||||
"Save changes permanently": "Zapisz zmiany permanentnie",
|
||||
"Reboot controller": "Uruchom ponownie kontroler",
|
||||
"Controller Info": "Informacje o kontrolerze",
|
||||
@@ -188,7 +185,7 @@
|
||||
"Show all": "Pokaż wszystko",
|
||||
"Finetune stick calibration": "Dokładna kalibracja drążków",
|
||||
"(beta)": "(beta)",
|
||||
"This screen allows to finetune raw calibration data on your controller": "Te okienko pozwala na dokładniejszą zmianę w danych o kalibracji w twoim kontrolerze",
|
||||
"This screen allows to finetune raw calibration data on your controller": "Te okienko pozwala na ustawianie dokładniejszych danych o kalibracji w twoim kontrolerze",
|
||||
"Left stick": "Lewy drążęk",
|
||||
"Right stick": "Prawy drążęk",
|
||||
"Center X": "Punkt X",
|
||||
@@ -199,42 +196,70 @@
|
||||
"I'm actively working on adding compatibility, the primary challenge lies in storing data into the stick modules.": "Aktywnie pracuję nad dodaniem kompatybilności, ale głównym wyzwaniem jest przechowywanie danych w modułach drążków.",
|
||||
"If this tool has been helpful to you or you want to see DualSense Edge support arrive faster, please consider supporting the project with a": "Jeśli uważasz że to narzędzie było dla ciebie pomocne, lub chcesz aby wsparcie DualSense Edge pojawiło się szybciej, rozważ wsparcie projektu poprzez",
|
||||
"Thank you for your generosity and support!": "Dziękujemy za hojność i wsparcie!",
|
||||
"30th Anniversary": "",
|
||||
"<b>Externally</b>: by applying +1.8V directly to the visible test point without opening the controller": "",
|
||||
"<b>Internally</b>: by soldering a wire from a +1.8V source to the write-protect TP.": "",
|
||||
"Astro Bot": "",
|
||||
"Calibration is being stored in the stick modules.": "",
|
||||
"Cannot lock": "",
|
||||
"Cannot store data into": "",
|
||||
"Cannot unlock": "",
|
||||
"Cobalt Blue": "",
|
||||
"Color": "",
|
||||
"Color detection thanks to": "",
|
||||
"Cosmic Red": "",
|
||||
"DualSense Edge Calibration": "",
|
||||
"For more info or help, feel free to reach out on Discord.": "",
|
||||
"Galactic Purple": "",
|
||||
"God of War Ragnarok": "",
|
||||
"Grey Camouflage": "",
|
||||
"If the calibration is not stored permanently, please double-check the wirings of the hardware mod.": "",
|
||||
"Left Module Barcode": "",
|
||||
"Midnight Black": "",
|
||||
"More details and images": "",
|
||||
"Nova Pink": "",
|
||||
"Please connect a DualShock 4, a DualSense or DualSense Edge controller to your computer and press Connect.": "",
|
||||
"Please note: the stick modules on the DS Edge <b>cannot be calibrated via software alone</b>.To store a custom calibration on the stick's internal memory, a <b>hardware modification</b> is required.": "",
|
||||
"Right Module Barcode": "",
|
||||
"Starlight Blue": "",
|
||||
"Sterling Silver": "",
|
||||
"Support for calibrating DualSense Edge stick modules is now available as an <b>experimental feature</b>.": "",
|
||||
"This involves temporarily disabling write protection by applying <b>+1.8V</b> to a specific test point on each module.": "",
|
||||
"This is only for advanced users. If you're not sure what you're doing, please do not attempt it.": "",
|
||||
"Volcanic Red": "",
|
||||
"We are not responsible for any damage caused by attempting this modification.": "",
|
||||
"White": "",
|
||||
"You can do this in two ways:": "",
|
||||
"here": "",
|
||||
"left module": "",
|
||||
"right module": "",
|
||||
"30th Anniversary": "30th Anniversary",
|
||||
"<b>Externally</b>: by applying +1.8V directly to the visible test point without opening the controller.": "<b>Zewnętrznie</b>: poprzez podanie +1.8V bezpośrednio do widocznego punktu testowego bez otwierania kontrolera.",
|
||||
"<b>Internally</b>: by soldering a wire from a +1.8V source to the write-protect TP.": "<b>Wewnętrznie</b>: przez przylutowanie przewodu z źródła +1.8V do punktu testowego ochrony przed zapisem.",
|
||||
"Astro Bot": "Astro Bot",
|
||||
"Calibration is being stored in the stick modules.": "Kalibracja jest zapisywana w modułach drążków.",
|
||||
"Cannot lock": "Nie można zablokować",
|
||||
"Cannot store data into": "Nie można zachować informacji w",
|
||||
"Cannot unlock": "Nie można odblokować",
|
||||
"Cobalt Blue": "Cobalt Blue",
|
||||
"Color": "Kolor",
|
||||
"Color detection thanks to": "Podziękowania dla osoby za funkcję wykrywania kolorów",
|
||||
"Cosmic Red": "Cosmic Red",
|
||||
"DualSense Edge Calibration": "Kalibracja Dualsense Edge",
|
||||
"For more info or help, feel free to reach out on Discord.": "Aby uzyskać więcej informacji lub pomoc, skontaktuj się do nas na Discordzie",
|
||||
"Galactic Purple": "Galactic Purple",
|
||||
"God of War Ragnarok": "God of War Ragnarok",
|
||||
"Grey Camouflage": "Grey Camouflage",
|
||||
"If the calibration is not stored permanently, please double-check the wirings of the hardware mod.": "Jeżeli kalibracja nie została zachowana na stałe, prosimy o dwukrotnym sprawdzeniu ręcznie wykonanej modyfikacji",
|
||||
"Left Module Barcode": "Barcode lewego modułu",
|
||||
"Midnight Black": "Midnight Black",
|
||||
"More details and images": "Więcej szczegółów i zdjęć",
|
||||
"Nova Pink": "Nova Pink",
|
||||
"Please connect a DualShock 4, a DualSense or DualSense Edge controller to your computer and press Connect.": "Podłącz kontroler Dualshock 4, Dualsense, lub Dualsense Edge do komputera, i naciśnij opcję Połącz",
|
||||
"Please note: the stick modules on the DS Edge <b>cannot be calibrated via software alone</b>.": "Uwaga: moduły drążków w DS Edge <b>nie mogą być kalibrowane wyłącznie za pomocą oprogramowania!</b>.",
|
||||
"To store a custom calibration on the stick's internal memory, a <b>hardware modification</b> is required.": "Aby zapisać niestandardową kalibrację w wewnętrznej pamięci drążka, wymagana jest ręczna <b>modyfikacja sprzętowa</b>.",
|
||||
"Right Module Barcode": "Barcode prawego modułu",
|
||||
"Starlight Blue": "Starlight Blue",
|
||||
"Sterling Silver": "Sterling Silver",
|
||||
"Support for calibrating DualSense Edge stick modules is now available as an <b>experimental feature</b>.": "Wsparcie dla obsługi kalibrowania modułów drążków DualSense Edge jest teraz dostępna jako <b>funkcja eksperymentalna</b>.",
|
||||
"This involves temporarily disabling write protection by applying <b>+1.8V</b> to a specific test point on each module.": "Obejmuje to na tymczasowym wyłączeniu ochrony przed zapisem poprzez podanie <b>+1.8V</b> do określonego punktu testowego na każdym module.",
|
||||
"This is only for advanced users. If you're not sure what you're doing, please do not attempt it.": "Tylko dla zaawansowanych użytkowników. Jeśli nie jesteś pewien co robisz, proszę nie próbuj tego!",
|
||||
"Volcanic Red": "Volcanic Red",
|
||||
"We are not responsible for any damage caused by attempting this modification.": "Nie ponosimy odpowiedzialności za jakiekolwiek szkody spowodowane próbą tej modyfikacji.",
|
||||
"White": "White",
|
||||
"You can do this in two ways:": "Możesz to zrobić na 2 sposoby",
|
||||
"here": "tutaj",
|
||||
"left module": "lewy moduł",
|
||||
"right module": "prawy moduł",
|
||||
"Chroma Indigo": "Chroma Indigo",
|
||||
"Chroma Pearl": "Chroma Pearl",
|
||||
"Chroma Teal": "Chroma Teal",
|
||||
"Fortnite": "Fortnite",
|
||||
"Spider-Man 2": "Spider-Man 2",
|
||||
"The Last of Us": "The Last of US",
|
||||
"10x zoom": "10-krotne przybliżenie",
|
||||
"Calibration": "Kalibracja",
|
||||
"Debug": "Wyszukiwanie błędów",
|
||||
"Error triggering rumble": "Błąd wyzwalania wibracji",
|
||||
"Info": "Informacje",
|
||||
"Normal": "Normalne",
|
||||
"Press L2 to test the strong (left) haptic motor": "Naciśnij L2 by sprawdzić silniejszy (lewy) silnik haptyczny",
|
||||
"Press R2 to test the weak (right) haptic motor": "Naciśnij R2 by sprawdzić delikatniejszy (prawy) silnik haptyczny",
|
||||
"Test the Haptic Motors": "Test Silników Haptycznych",
|
||||
"Tests": "Testy",
|
||||
"The motor strength will match how hard you press the trigger": "Siła wibracji będzie odpowiadała sile z jaką naciskasz na przyciski",
|
||||
"Center (L1)": "Centrowanie (L1)",
|
||||
"Circularity (R1)": "Kolistość (R1)",
|
||||
"Move the stick to select it for tuning, then without touching the stick use the D-pad buttons to adjust the center point. Flick it and adjust it again if it is off center or flickers.": "Porusz drążek który chcesz wyregulować, następnie bez dotykania go użyj pada kierunkowego (d-pad/krzyżak) by wybrać punkt środkowy. Wyreguluj i wyśrodkuj ponownie jeśli nie jest na środku lub skacze.",
|
||||
"Please release the stick to center position before adjusting with D-pad buttons.": "Pozostaw drążek na pozycji środkowej zanim zaczniesz centrować przy pomocy pada kierunkowego (d-pad/krzyżak).",
|
||||
"Press the D-pad or face buttons in the direction you want the stick position to move.": "Naciśnij pad kierunkowy (d-pad/krzyżak) lub przyciski funkcyjne w kierynku którym chcesz ustawić pozycję drążka.",
|
||||
"Push the stick straight up/down/left/right as far as possible.": "Przesuń drążek prosto w górę/dół/lewo/prawo najdalej jak to możliwe.",
|
||||
"Show raw numbers": "Pokaż surowe liczby",
|
||||
"The device is connected via Bluetooth. Disconnect and reconnect using a USB cable instead.": "",
|
||||
"While holding the stick to be adjusted straight up/down/left/right, <em>observe the highlighted value below the circle</em>, then use the D-pad buttons to adjust the value to ±0.99 (just below ±1.00).": "Trzymajac drążek w pozycji do wyregulowania (góra/dół/lewo/prawo), <em>obserwuj pogrubioną wartość pod okręgiem</em>, nastęnie użyj pada kierunkowego (d-pada/krzyżaka) by ustawić wartość na ±0.99 (zaraz poniżej ±1.00).",
|
||||
"Your device might not be a genuine Sony controller. If it is not a clone then please report this issue.": "",
|
||||
"": ""
|
||||
}
|
||||
@@ -32,7 +32,7 @@
|
||||
"Please move both sticks to the <b>bottom-right corner</b> and release them.": "Mova ambos os analógicos para o <b>canto inferior direito</b> e solte-os.",
|
||||
"Calibration completed successfully!": "Calibração concluída com sucesso!",
|
||||
"Next": "Próximo",
|
||||
"Recentering the controller sticks. ": "Recentrando os analógicos do controle. ",
|
||||
"Recentering the controller sticks.": "Recentrando os analógicos do controle.",
|
||||
"Please do not close this window and do not disconnect your controller. ": "Por favor, não feche esta janela e não desconecte seu controle. ",
|
||||
"Range calibration": "Calibração do intervalo",
|
||||
"<b>The controller is now sampling data!</b>": "<b>O controlador está agora a amostrar dados!</b>",
|
||||
@@ -56,16 +56,16 @@
|
||||
"SW Version": "Versão SW",
|
||||
"Device Type": "Tipo de Dispositivo",
|
||||
"Range calibration completed": "Calibração de alcance completa",
|
||||
"Range calibration failed: ": "Calibração de alcance falhou: ",
|
||||
"Range calibration failed": "Calibração de alcance falhou",
|
||||
"Cannot unlock NVS": "Não é possível desbloquear NVS",
|
||||
"Cannot relock NVS": "Não é possível bloquear NVS",
|
||||
"Error 1": "Erro 1",
|
||||
"Error 2": "Erro 2",
|
||||
"Error 3": "Erro 3",
|
||||
"Stick calibration failed: ": "Calibração de analógico falhou: ",
|
||||
"Stick calibration failed": "Calibração de analógico falhou",
|
||||
"Stick calibration completed": "Calibração de analógico completa",
|
||||
"NVS Lock failed: ": "Bloqueio de NVS falhou: ",
|
||||
"NVS Unlock failed: ": "Desbloqueio de NVS falhou: ",
|
||||
"NVS Lock failed": "Bloqueio de NVS falhou",
|
||||
"NVS Unlock failed": "Desbloqueio de NVS falhou",
|
||||
"Please connect only one controller at time.": "Por favor, conecte somente um controle por vez.",
|
||||
"Sony DualShock 4 V1": "Sony DualShock 4 V1",
|
||||
"Sony DualShock 4 V2": "Sony DualShock 4 V2",
|
||||
@@ -134,12 +134,9 @@
|
||||
"This feature is experimental.": "Esta funcionalidade é experimental.",
|
||||
"Please let me know if the board model of your controller is not detected correctly.": "Por favor, avise-me se o modelo da placa do seu controle não for detectado corretamente.",
|
||||
"Board model detection thanks to": "Detecção do modelo da placa graças a",
|
||||
"Please connect the device using a USB cable.": "Por favor, conecte o dispositivo usando um cabo USB.",
|
||||
"This DualSense controller has outdated firmware.": "Este controle DualSense possui um firmware desatualizado.",
|
||||
"Please update the firmware and try again.": "Por favor, atualize o firmware e tente novamente.",
|
||||
"Joystick Info": "Informações do Joystick",
|
||||
"Err R:": "Erro D:",
|
||||
"Err L:": "Erro E:",
|
||||
"Check circularity": "Verificar circularidade",
|
||||
"Can I reset a permanent calibration to previous calibration?": "Posso resetar uma calibração permanente para a calibração anterior?",
|
||||
"No.": "Não.",
|
||||
@@ -157,31 +154,40 @@
|
||||
"Make sure to touch the edges of the joystick frame and rotate slowly, preferably in each direction - clockwise and anti-clockwise.": "Certifique-se de encostar nos limites do analógico e rotacione lentamente, prefrerencialmente em cada direção.",
|
||||
"Only after you have done that, you click on \"Done\".": "Somente após você fazer isso, você clica em \"Concluído\"",
|
||||
"Changes saved successfully": "Alterações salvas com sucesso",
|
||||
"Error while saving changes:": "Erro ao salvar as alterações.",
|
||||
"Error while saving changes": "Erro ao salvar as alterações.",
|
||||
"Save changes permanently": "Salvar alterações permanentemente.",
|
||||
"Reboot controller": "Reiniciar controle",
|
||||
"(beta)": "(beta)",
|
||||
"10x zoom": "",
|
||||
"30th Anniversary": "",
|
||||
"<b>Externally</b>: by applying +1.8V directly to the visible test point without opening the controller": "",
|
||||
"<b>Externally</b>: by applying +1.8V directly to the visible test point without opening the controller.": "",
|
||||
"<b>Internally</b>: by soldering a wire from a +1.8V source to the write-protect TP.": "",
|
||||
"Astro Bot": "",
|
||||
"Battery Barcode": "",
|
||||
"Bluetooth Address": "",
|
||||
"Calibration": "",
|
||||
"Calibration is being stored in the stick modules.": "",
|
||||
"Cancel": "",
|
||||
"Cannot lock": "",
|
||||
"Cannot store data into": "",
|
||||
"Cannot unlock": "",
|
||||
"Center (L1)": "",
|
||||
"Center X": "",
|
||||
"Center Y": "",
|
||||
"Chroma Indigo": "",
|
||||
"Chroma Pearl": "",
|
||||
"Chroma Teal": "",
|
||||
"Circularity (R1)": "",
|
||||
"Cobalt Blue": "",
|
||||
"Color": "",
|
||||
"Color detection thanks to": "",
|
||||
"Controller Info": "",
|
||||
"Cosmic Red": "",
|
||||
"Debug": "",
|
||||
"Debug Info": "",
|
||||
"Debug buttons": "",
|
||||
"DualSense Edge Calibration": "",
|
||||
"Error triggering rumble": "",
|
||||
"FW Build Date": "",
|
||||
"FW Series": "",
|
||||
"FW Type": "",
|
||||
@@ -190,6 +196,7 @@
|
||||
"FW Version": "",
|
||||
"Finetune stick calibration": "",
|
||||
"For more info or help, feel free to reach out on Discord.": "",
|
||||
"Fortnite": "",
|
||||
"Galactic Purple": "",
|
||||
"God of War Ragnarok": "",
|
||||
"Grey Camouflage": "",
|
||||
@@ -198,28 +205,43 @@
|
||||
"I'm actively working on adding compatibility, the primary challenge lies in storing data into the stick modules.": "",
|
||||
"If the calibration is not stored permanently, please double-check the wirings of the hardware mod.": "",
|
||||
"If this tool has been helpful to you or you want to see DualSense Edge support arrive faster, please consider supporting the project with a": "",
|
||||
"Info": "",
|
||||
"Left Module Barcode": "",
|
||||
"Left stick": "",
|
||||
"MCU Unique ID": "",
|
||||
"Midnight Black": "",
|
||||
"More details and images": "",
|
||||
"Move the stick to select it for tuning, then without touching the stick use the D-pad buttons to adjust the center point. Flick it and adjust it again if it is off center or flickers.": "",
|
||||
"Normal": "",
|
||||
"Nova Pink": "",
|
||||
"PCBA ID": "",
|
||||
"Please connect a DualShock 4, a DualSense or DualSense Edge controller to your computer and press Connect.": "",
|
||||
"Please note: the stick modules on the DS Edge <b>cannot be calibrated via software alone</b>.To store a custom calibration on the stick's internal memory, a <b>hardware modification</b> is required.": "",
|
||||
"Please release the stick to center position before adjusting with D-pad buttons.": "",
|
||||
"Press L2 to test the strong (left) haptic motor": "",
|
||||
"Press R2 to test the weak (right) haptic motor": "",
|
||||
"Press the D-pad or face buttons in the direction you want the stick position to move.": "",
|
||||
"Push the stick straight up/down/left/right as far as possible.": "",
|
||||
"Right Module Barcode": "",
|
||||
"Right stick": "",
|
||||
"SBL FW Version": "",
|
||||
"Save": "",
|
||||
"Serial Number": "",
|
||||
"Show all": "",
|
||||
"Show raw numbers": "",
|
||||
"Software": "",
|
||||
"Spider FW Version": "",
|
||||
"Spider-Man 2": "",
|
||||
"Starlight Blue": "",
|
||||
"Sterling Silver": "",
|
||||
"Support for calibrating DualSense Edge stick modules is now available as an <b>experimental feature</b>.": "",
|
||||
"Test the Haptic Motors": "",
|
||||
"Tests": "",
|
||||
"Thank you for your generosity and support!": "",
|
||||
"The DualShock Calibration GUI does not currently support the DualSense Edge.": "",
|
||||
"The Last of Us": "",
|
||||
"The device is connected via Bluetooth. Disconnect and reconnect using a USB cable instead.": "",
|
||||
"The motor strength will match how hard you press the trigger": "",
|
||||
"This involves temporarily disabling write protection by applying <b>+1.8V</b> to a specific test point on each module.": "",
|
||||
"This is only for advanced users. If you're not sure what you're doing, please do not attempt it.": "",
|
||||
"This screen allows to finetune raw calibration data on your controller": "",
|
||||
@@ -230,8 +252,10 @@
|
||||
"Venom FW Version": "",
|
||||
"Volcanic Red": "",
|
||||
"We are not responsible for any damage caused by attempting this modification.": "",
|
||||
"While holding the stick to be adjusted straight up/down/left/right, <em>observe the highlighted value below the circle</em>, then use the D-pad buttons to adjust the value to ±0.99 (just below ±1.00).": "",
|
||||
"White": "",
|
||||
"You can do this in two ways:": "",
|
||||
"Your device might not be a genuine Sony controller. If it is not a clone then please report this issue.": "",
|
||||
"here": "",
|
||||
"left module": "",
|
||||
"right module": "",
|
||||
|
||||
@@ -32,7 +32,7 @@
|
||||
"Please move both sticks to the <b>bottom-right corner</b> and release them.": "Mova ambos os joysticks para o <b>canto inferior direito</b> e solte-os.",
|
||||
"Calibration completed successfully!": "Calibração concluída com sucesso!",
|
||||
"Next": "Próximo",
|
||||
"Recentering the controller sticks. ": "A recentrar os manípulos do controlador",
|
||||
"Recentering the controller sticks.": "A recentrar os manípulos do controlador.",
|
||||
"Please do not close this window and do not disconnect your controller. ": "Por favor, não feche esta janela e não desconecte o seu controlador. ",
|
||||
"Range calibration": "Calibração de alcançe",
|
||||
"<b>The controller is now sampling data!</b>": "<b>O controlador está agora a recolher dados!</b>",
|
||||
@@ -56,16 +56,16 @@
|
||||
"SW Version": "Versão SW",
|
||||
"Device Type": "Tipo de Dispositivo",
|
||||
"Range calibration completed": "Calibração de alcance completa",
|
||||
"Range calibration failed: ": "Calibração de alcance falhou: ",
|
||||
"Range calibration failed": "Calibração de alcance falhou",
|
||||
"Cannot unlock NVS": "Não é possível desbloquear NVS",
|
||||
"Cannot relock NVS": "Não é possível bloquear NVS",
|
||||
"Error 1": "Erro 1",
|
||||
"Error 2": "Erro 2",
|
||||
"Error 3": "Erro 3",
|
||||
"Stick calibration failed: ": "Calibração do joystick falhou: ",
|
||||
"Stick calibration failed": "Calibração do joystick falhou",
|
||||
"Stick calibration completed": "Calibração do joystick completa",
|
||||
"NVS Lock failed: ": "Bloqueio de NVS falhou: ",
|
||||
"NVS Unlock failed: ": "Desbloqueio de NVS falhou: ",
|
||||
"NVS Lock failed": "Bloqueio de NVS falhou",
|
||||
"NVS Unlock failed": "Desbloqueio de NVS falhou",
|
||||
"Please connect only one controller at time.": "Por favor, ligue apenas um controlador de cada vez.",
|
||||
"Sony DualShock 4 V1": "Sony DualShock 4 V1",
|
||||
"Sony DualShock 4 V2": "Sony DualShock 4 V2",
|
||||
@@ -134,12 +134,9 @@
|
||||
"This feature is experimental.": "Esta funcionalidade é experimental.",
|
||||
"Please let me know if the board model of your controller is not detected correctly.": "Por favor, avise-me se o modelo da placa do seu controlador não for detectado corretamente.",
|
||||
"Board model detection thanks to": "Detecção do modelo da placa graças a",
|
||||
"Please connect the device using a USB cable.": "Por favor, conecte o dispositivo usando um cabo USB.",
|
||||
"This DualSense controller has outdated firmware.": "Este controlador DualSense possui um firmware desatualizado.",
|
||||
"Please update the firmware and try again.": "Por favor, atualize o firmware e tente novamente.",
|
||||
"Joystick Info": "Informações do Joystick",
|
||||
"Err R:": "Erro D:",
|
||||
"Err L:": "Erro E:",
|
||||
"Check circularity": "Verificar circularidade",
|
||||
"Can I reset a permanent calibration to previous calibration?": "Posso repor uma calibração permanente para uma calibração anterior?",
|
||||
"No.": "Não.",
|
||||
@@ -157,11 +154,11 @@
|
||||
"Make sure to touch the edges of the joystick frame and rotate slowly, preferably in each direction - clockwise and anti-clockwise.": "Certifique-se que toca nas extremidades da estrutura do Joystick e gire lentamente, de prefrerencia em ambas as direções - no sentido dos ponteiros do relógio e no sentido contrário.",
|
||||
"Only after you have done that, you click on \"Done\".": "So depois de o fazer, clique em \"Concluído\".",
|
||||
"Changes saved successfully": "Alterações salvas com sucesso",
|
||||
"Error while saving changes:": "Erro ao salvar as alterações.",
|
||||
"Error while saving changes": "Erro ao salvar as alterações.",
|
||||
"Save changes permanently": "Salvar alterações permanentemente.",
|
||||
"Reboot controller": "Reiniciar controlador",
|
||||
"(beta)": "(beta)",
|
||||
"<b>Externally</b>: by applying +1.8V directly to the visible test point without opening the controller": "<b>Externamente</b>: aplicando +1,8 V diretamente ao ponto de teste visível sem abrir o controlador",
|
||||
"<b>Externally</b>: by applying +1.8V directly to the visible test point without opening the controller.": "<b>Externamente</b>: aplicando +1,8 V diretamente ao ponto de teste visível sem abrir o controlador",
|
||||
"<b>Internally</b>: by soldering a wire from a +1.8V source to the write-protect TP.": "<b>Internamente</b>: soldadura de um fio de uma fonte de +1,8 V ao TP de proteção contra a escrita.",
|
||||
"Battery Barcode": "Código de barras da bateria",
|
||||
"Bluetooth Address": "Endereço Bluetooth",
|
||||
@@ -223,18 +220,45 @@
|
||||
"Right Module Barcode": "Código de barras do módulo direito",
|
||||
"left module": "módulo esquerdo",
|
||||
"right module": "módulo direito",
|
||||
"10x zoom": "",
|
||||
"30th Anniversary": "",
|
||||
"Astro Bot": "",
|
||||
"Calibration": "",
|
||||
"Center (L1)": "",
|
||||
"Chroma Indigo": "",
|
||||
"Chroma Pearl": "",
|
||||
"Chroma Teal": "",
|
||||
"Circularity (R1)": "",
|
||||
"Cobalt Blue": "",
|
||||
"Cosmic Red": "",
|
||||
"Debug": "",
|
||||
"Error triggering rumble": "",
|
||||
"Fortnite": "",
|
||||
"Galactic Purple": "",
|
||||
"God of War Ragnarok": "",
|
||||
"Grey Camouflage": "",
|
||||
"Info": "",
|
||||
"Midnight Black": "",
|
||||
"Move the stick to select it for tuning, then without touching the stick use the D-pad buttons to adjust the center point. Flick it and adjust it again if it is off center or flickers.": "",
|
||||
"Normal": "",
|
||||
"Nova Pink": "",
|
||||
"Please release the stick to center position before adjusting with D-pad buttons.": "",
|
||||
"Press L2 to test the strong (left) haptic motor": "",
|
||||
"Press R2 to test the weak (right) haptic motor": "",
|
||||
"Press the D-pad or face buttons in the direction you want the stick position to move.": "",
|
||||
"Push the stick straight up/down/left/right as far as possible.": "",
|
||||
"Show raw numbers": "",
|
||||
"Spider-Man 2": "",
|
||||
"Starlight Blue": "",
|
||||
"Sterling Silver": "",
|
||||
"Test the Haptic Motors": "",
|
||||
"Tests": "",
|
||||
"The Last of Us": "",
|
||||
"The device is connected via Bluetooth. Disconnect and reconnect using a USB cable instead.": "",
|
||||
"The motor strength will match how hard you press the trigger": "",
|
||||
"Volcanic Red": "",
|
||||
"While holding the stick to be adjusted straight up/down/left/right, <em>observe the highlighted value below the circle</em>, then use the D-pad buttons to adjust the value to ±0.99 (just below ±1.00).": "",
|
||||
"White": "",
|
||||
"Your device might not be a genuine Sony controller. If it is not a clone then please report this issue.": "",
|
||||
"": ""
|
||||
}
|
||||
@@ -33,7 +33,7 @@
|
||||
"Please move both sticks to the <b>bottom-right corner</b> and release them.": "Molimo vas da pomerite oba džojstika u <b>donji desni ugao</b> i zatim ih otpustite.",
|
||||
"Calibration completed successfully!": "Kalibracija je uspešno završena!",
|
||||
"Next": "Sledeće",
|
||||
"Recentering the controller sticks. ": "Ponovno centriranje džojstika kontrolera. ",
|
||||
"Recentering the controller sticks.": "Ponovno centriranje džojstika kontrolera.",
|
||||
"Please do not close this window and do not disconnect your controller. ": "Molimo vas da ne zatvarate ovaj prozor i da ne prekidate vezu sa kontrolerom. ",
|
||||
"Range calibration": "Kalibracija opsega džojstika",
|
||||
"<b>The controller is now sampling data!</b>": "<b>Kontroler sada prikuplja podatke!</b>",
|
||||
@@ -57,16 +57,16 @@
|
||||
"SW Version": "Verzija softvera",
|
||||
"Device Type": "Tip uređaja",
|
||||
"Range calibration completed": "Kalibracija opsega završena",
|
||||
"Range calibration failed: ": "Kalibracija opsega nije uspela: ",
|
||||
"Range calibration failed": "Kalibracija opsega nije uspela",
|
||||
"Cannot unlock NVS": "Nije moguće otključati NVS",
|
||||
"Cannot relock NVS": "Nije moguće zaključati NVS",
|
||||
"Error 1": "Greška 1",
|
||||
"Error 2": "Greška 2",
|
||||
"Error 3": "Greška 3",
|
||||
"Stick calibration failed: ": "Kalibracija džojstika nije uspela: ",
|
||||
"Stick calibration failed": "Kalibracija džojstika nije uspela",
|
||||
"Stick calibration completed": "Kalibracija džojstika završena",
|
||||
"NVS Lock failed: ": "Zaključavanje NVS nije uspelo: ",
|
||||
"NVS Unlock failed: ": "Otključavanje NVS nije uspelo: ",
|
||||
"NVS Lock failed": "Zaključavanje NVS nije uspelo",
|
||||
"NVS Unlock failed": "Otključavanje NVS nije uspelo",
|
||||
"Please connect only one controller at time.": "Molimo vas da povežete samo jedan kontroler istovremeno.",
|
||||
"Sony DualShock 4 V1": "Sony DualShock 4 V1",
|
||||
"Sony DualShock 4 V2": "Sony DualShock 4 V2",
|
||||
@@ -135,12 +135,9 @@
|
||||
"This feature is experimental.": "Ova funkcionalnost je eksperimentalna.",
|
||||
"Please let me know if the board model of your controller is not detected correctly.": "Molimo vas da mi javite ako model ploče vašeg kontrolera nije tačno detektovan.",
|
||||
"Board model detection thanks to": "Detekcija modela ploče zahvaljujući",
|
||||
"Please connect the device using a USB cable.": "Molimo vas da povežete uređaj koristeći USB kabl.",
|
||||
"This DualSense controller has outdated firmware.": "Ovaj DualSense kontroler ima zastareli firmware.",
|
||||
"Please update the firmware and try again.": "Molimo vas da ažurirate firmware i pokušate ponovo.",
|
||||
"Joystick Info": "Informacije o džojstiku",
|
||||
"Err R:": "Greška D:",
|
||||
"Err L:": "Greška L:",
|
||||
"Check circularity": "Proveri kružnost",
|
||||
"Can I reset a permanent calibration to previous calibration?": "Mogu li da resetujem trajnu kalibraciju na prethodnu kalibraciju?",
|
||||
"No.": "Ne.",
|
||||
@@ -158,7 +155,7 @@
|
||||
"Make sure to touch the edges of the joystick frame and rotate slowly, preferably in each direction - clockwise and anti-clockwise.": "Obavezno dodirnite ivice okvira džojstika i rotirajte polako, po mogućstvu u oba pravca - u smeru kazaljke na satu i suprotno.",
|
||||
"Only after you have done that, you click on \"Done\".": "Tek nakon što to uradite, kliknite na \"Završeno\".",
|
||||
"Changes saved successfully": "Promene uspešno sačuvane",
|
||||
"Error while saving changes:": "Greška prilikom čuvanja promena:",
|
||||
"Error while saving changes": "Greška prilikom čuvanja promena:",
|
||||
"Save changes permanently": "Sačuvaj promene trajno",
|
||||
"Reboot controller": "Ponovo pokreni kontroler",
|
||||
"Controller Info": "Informacije o kontroleru",
|
||||
@@ -198,40 +195,67 @@
|
||||
"I'm actively working on adding compatibility, the primary challenge lies in storing data into the stick modules.": "Aktivno radim na dodavanju kompatibilnosti, glavni izazov je u čuvanju podataka u modulima džojstika.",
|
||||
"If this tool has been helpful to you or you want to see DualSense Edge support arrive faster, please consider supporting the project with a": "Ako vam je ovaj alat bio koristan ili želite da podrška za DualSense Edge stigne brže, razmislite o podršci projekta sa",
|
||||
"Thank you for your generosity and support!": "Hvala vam na velikodušnosti i podršci!",
|
||||
"10x zoom": "",
|
||||
"30th Anniversary": "",
|
||||
"<b>Externally</b>: by applying +1.8V directly to the visible test point without opening the controller": "",
|
||||
"<b>Externally</b>: by applying +1.8V directly to the visible test point without opening the controller.": "",
|
||||
"<b>Internally</b>: by soldering a wire from a +1.8V source to the write-protect TP.": "",
|
||||
"Astro Bot": "",
|
||||
"Calibration": "",
|
||||
"Calibration is being stored in the stick modules.": "",
|
||||
"Cannot lock": "",
|
||||
"Cannot store data into": "",
|
||||
"Cannot unlock": "",
|
||||
"Center (L1)": "",
|
||||
"Chroma Indigo": "",
|
||||
"Chroma Pearl": "",
|
||||
"Chroma Teal": "",
|
||||
"Circularity (R1)": "",
|
||||
"Cobalt Blue": "",
|
||||
"Color": "",
|
||||
"Color detection thanks to": "",
|
||||
"Cosmic Red": "",
|
||||
"Debug": "",
|
||||
"DualSense Edge Calibration": "",
|
||||
"Error triggering rumble": "",
|
||||
"For more info or help, feel free to reach out on Discord.": "",
|
||||
"Fortnite": "",
|
||||
"Galactic Purple": "",
|
||||
"God of War Ragnarok": "",
|
||||
"Grey Camouflage": "",
|
||||
"If the calibration is not stored permanently, please double-check the wirings of the hardware mod.": "",
|
||||
"Info": "",
|
||||
"Left Module Barcode": "",
|
||||
"Midnight Black": "",
|
||||
"More details and images": "",
|
||||
"Move the stick to select it for tuning, then without touching the stick use the D-pad buttons to adjust the center point. Flick it and adjust it again if it is off center or flickers.": "",
|
||||
"Normal": "",
|
||||
"Nova Pink": "",
|
||||
"Please connect a DualShock 4, a DualSense or DualSense Edge controller to your computer and press Connect.": "",
|
||||
"Please note: the stick modules on the DS Edge <b>cannot be calibrated via software alone</b>.To store a custom calibration on the stick's internal memory, a <b>hardware modification</b> is required.": "",
|
||||
"Please release the stick to center position before adjusting with D-pad buttons.": "",
|
||||
"Press L2 to test the strong (left) haptic motor": "",
|
||||
"Press R2 to test the weak (right) haptic motor": "",
|
||||
"Press the D-pad or face buttons in the direction you want the stick position to move.": "",
|
||||
"Push the stick straight up/down/left/right as far as possible.": "",
|
||||
"Right Module Barcode": "",
|
||||
"Show raw numbers": "",
|
||||
"Spider-Man 2": "",
|
||||
"Starlight Blue": "",
|
||||
"Sterling Silver": "",
|
||||
"Support for calibrating DualSense Edge stick modules is now available as an <b>experimental feature</b>.": "",
|
||||
"Test the Haptic Motors": "",
|
||||
"Tests": "",
|
||||
"The Last of Us": "",
|
||||
"The device is connected via Bluetooth. Disconnect and reconnect using a USB cable instead.": "",
|
||||
"The motor strength will match how hard you press the trigger": "",
|
||||
"This involves temporarily disabling write protection by applying <b>+1.8V</b> to a specific test point on each module.": "",
|
||||
"This is only for advanced users. If you're not sure what you're doing, please do not attempt it.": "",
|
||||
"Volcanic Red": "",
|
||||
"We are not responsible for any damage caused by attempting this modification.": "",
|
||||
"While holding the stick to be adjusted straight up/down/left/right, <em>observe the highlighted value below the circle</em>, then use the D-pad buttons to adjust the value to ±0.99 (just below ±1.00).": "",
|
||||
"White": "",
|
||||
"You can do this in two ways:": "",
|
||||
"Your device might not be a genuine Sony controller. If it is not a clone then please report this issue.": "",
|
||||
"here": "",
|
||||
"left module": "",
|
||||
"right module": "",
|
||||
|
||||
169
lang/ru_ru.json
169
lang/ru_ru.json
@@ -1,5 +1,5 @@
|
||||
{
|
||||
".authorMsg": "- Перевод на Русский язык выполнен: <a href='https://www.youtube.com/channel/UC8pzDCIt_CUj8sa7cYgPzHQ'>Tamir-Teknik</a>",
|
||||
".authorMsg": "- Перевод на Русский язык выполнен: <a href='https://www.youtube.com/channel/UC8pzDCIt_CUj8sa7cYgPzHQ'>Tamir-Teknik. Дополнил Amnesia44</a>",
|
||||
"DualShock Calibration GUI": "Интерфейс калибровки DualShock",
|
||||
"Unsupported browser. Please use a web browser with WebHID support (e.g. Chrome).": "Неподдерживаемый браузер. Используйте браузер с поддержкой WebHID (например, Chrome).",
|
||||
"Connect": "Подключить",
|
||||
@@ -32,7 +32,7 @@
|
||||
"Please move both sticks to the <b>bottom-right corner</b> and release them.": "Пожалуйста, переместите оба джойстика в <b>нижний правый угол</b> и отпустите их.",
|
||||
"Calibration completed successfully!": "Калибровка успешно завершена!",
|
||||
"Next": "Далее",
|
||||
"Recentering the controller sticks. ": "Центрирование стиков контроллера. ",
|
||||
"Recentering the controller sticks.": "Центрирование стиков контроллера.",
|
||||
"Please do not close this window and do not disconnect your controller. ": "Пожалуйста, не закрывайте это окно и не отключайте контроллер. ",
|
||||
"Range calibration": "Калибровка диапазона",
|
||||
"<b>The controller is now sampling data!</b>": "<b>Контроллер в настоящее время собирает данные!</b>",
|
||||
@@ -56,16 +56,16 @@
|
||||
"SW Version": "Версия программного обеспечения",
|
||||
"Device Type": "Тип устройства",
|
||||
"Range calibration completed": "Калибровка диапазона завершена",
|
||||
"Range calibration failed: ": "Калибровка диапазона не удалась: ",
|
||||
"Range calibration failed": "Калибровка диапазона не удалась",
|
||||
"Cannot unlock NVS": "Не удается разблокировать NVS",
|
||||
"Cannot relock NVS": "Не удается заблокировать NVS повторно",
|
||||
"Error 1": "Ошибка 1",
|
||||
"Error 2": "Ошибка 2",
|
||||
"Error 3": "Ошибка 3",
|
||||
"Stick calibration failed: ": "Калибровка джойстика не удалась: ",
|
||||
"Stick calibration failed": "Калибровка джойстика не удалась",
|
||||
"Stick calibration completed": "Калибровка джойстика завершена",
|
||||
"NVS Lock failed: ": "Блокировка NVS не удалась: ",
|
||||
"NVS Unlock failed: ": "Разблокировка NVS не удалась: ",
|
||||
"NVS Lock failed": "Блокировка NVS не удалась",
|
||||
"NVS Unlock failed": "Разблокировка NVS не удалась",
|
||||
"Please connect only one controller at time.": "Пожалуйста, подключайте только один контроллер за раз.",
|
||||
"Sony DualShock 4 V1": "Sony DualShock 4 V1",
|
||||
"Sony DualShock 4 V2": "Sony DualShock 4 V2",
|
||||
@@ -134,12 +134,9 @@
|
||||
"This feature is experimental.": "Эта функция экспериментальная.",
|
||||
"Please let me know if the board model of your controller is not detected correctly.": "Пожалуйста, дайте знать, если модель платы вашего контроллера определена неправильно.",
|
||||
"Board model detection thanks to": "Определение модели платы благодаря",
|
||||
"Please connect the device using a USB cable.": "Пожалуйста, подключите устройство с помощью USB-кабеля.",
|
||||
"This DualSense controller has outdated firmware.": "Прошивка этого контроллера DualSense устарела.",
|
||||
"Please update the firmware and try again.": "Пожалуйста, обновите прошивку и попробуйте снова.",
|
||||
"Joystick Info": "Информация о джойстике",
|
||||
"Err R:": "Ошибка П:",
|
||||
"Err L:": "Ошибка Л:",
|
||||
"Check circularity": "Проверить округлость",
|
||||
"Can I reset a permanent calibration to previous calibration?": "Можно ли сбросить постоянную калибровку на предыдущую?",
|
||||
"No.": "Нет.",
|
||||
@@ -157,83 +154,111 @@
|
||||
"Make sure to touch the edges of the joystick frame and rotate slowly, preferably in each direction - clockwise and anti-clockwise.": "Убедитесь, что касаетесь краев рамы джойстика и вращайте медленно, предпочтительно в обоих направлениях — по часовой стрелке и против часовой стрелки.",
|
||||
"Only after you have done that, you click on \"Done\".": "Только после того, как вы это сделали, нажмите \"Готово\".",
|
||||
"Changes saved successfully": "Изменения успешно сохранены",
|
||||
"Error while saving changes:": "Ошибка при сохранении изменений:",
|
||||
"Error while saving changes": "Ошибка при сохранении изменений:",
|
||||
"Save changes permanently": "Сохранить изменения навсегда",
|
||||
"Reboot controller": "Перезагрузить контроллер",
|
||||
"(beta)": "",
|
||||
"(beta)": "Бета",
|
||||
"<b>Externally</b>: by applying +1.8V directly to the visible test point without opening the controller.": "<b>Снаружи</b>: подачей напряжения +1,8 В непосредственно на видимую тестовую точку (TP) без вскрытия корпуса контроллера.",
|
||||
"<b>Internally</b>: by soldering a wire from a +1.8V source to the write-protect TP.": "<b>Внутри</b>: припаяйте провод от +1,8 В к точке защиты от записи.",
|
||||
"Battery Barcode": "Штрих-код батареи",
|
||||
"Bluetooth Address": "Адрес Bluetooth",
|
||||
"Calibration is being stored in the stick modules.": "Калибровка сохраняется в модулях стиков",
|
||||
"Cancel": "Отмена",
|
||||
"Cannot lock": "Не удалось заблокировать",
|
||||
"Cannot store data into": "Не удалось сохранить данные",
|
||||
"Cannot unlock": "Не удалось разблокировать",
|
||||
"Center X": "Центр оси X",
|
||||
"Center Y": "Центр оси Y",
|
||||
"Color": "Цвет",
|
||||
"Color detection thanks to": "За определение цвета спасибо",
|
||||
"Controller Info": "Инфо контроллера",
|
||||
"Debug Info": "Дебаг-информация",
|
||||
"Debug buttons": "Отладка кнопок",
|
||||
"DualSense Edge Calibration": "Калибровка DualSense Edge",
|
||||
"FW Build Date": "Дата сборки ПО",
|
||||
"FW Series": "Серия ПО",
|
||||
"FW Type": "Тип ПО",
|
||||
"FW Update": "Обновление ПО",
|
||||
"FW Update Info": "Информация об обновлении ПО",
|
||||
"FW Version": "Версия ПО",
|
||||
"Finetune stick calibration": "Точная калибровка стиков",
|
||||
"For more info or help, feel free to reach out on Discord.": "Для получения помощи не стесняйтесь обращаться в Discord",
|
||||
"HW Model": "Модель устройства",
|
||||
"Hardware": "Аппаратная часть",
|
||||
"I'm actively working on adding compatibility, the primary challenge lies in storing data into the stick modules.": "Я активно работаю над добавлением совместимости, но основная проблема заключается в хранении данных в модулях стиков.",
|
||||
"If the calibration is not stored permanently, please double-check the wirings of the hardware mod.": "Если калибровка не сохраняется после перезагрузки, тщательно проверьте правильность подключения.",
|
||||
"If this tool has been helpful to you or you want to see DualSense Edge support arrive faster, please consider supporting the project with a": "Если этот инструмент был вам полезен или вы хотите, чтобы поддержка DualSense Edge появилась быстрее, пожалуйста, рассмотрите возможность поддержать проект —",
|
||||
"Left Module Barcode": "Штрих-код левого модуля",
|
||||
"Left stick": "Левый стик",
|
||||
"MCU Unique ID": "Уникальный MCU ID",
|
||||
"More details and images": "Больше деталей и изображения",
|
||||
"PCBA ID": "ID платы",
|
||||
"Please connect a DualShock 4, a DualSense or DualSense Edge controller to your computer and press Connect.": "Подключите контроллер DualShock 4, DualSense или DualSense Edge к компьютеру и нажмите кнопку Подключить",
|
||||
"Please note: the stick modules on the DS Edge <b>cannot be calibrated via software alone</b>.": "Обратите внимание: модули стиков на контроллере Dualsense Edge <b>нельзя откалибровать только с помощью программного обеспечения</b>.",
|
||||
"To store a custom calibration on the stick's internal memory, a <b>hardware modification</b> is required.": "Для сохранения пользовательской калибровки во внутренней памяти джойстика требуется <b>аппаратная модификация</b>.",
|
||||
"Right Module Barcode": "Штрих-код правого модуля",
|
||||
"Right stick": "Правый стик",
|
||||
"SBL FW Version": "Версия прошивки SBL",
|
||||
"Save": "Сохранить",
|
||||
"Serial Number": "Серийный номер",
|
||||
"Show all": "Показать все",
|
||||
"Software": "Программное обеспечение",
|
||||
"Spider FW Version": "Версия прошивки Spider",
|
||||
"Support for calibrating DualSense Edge stick modules is now available as an <b>experimental feature</b>.": "Поддержка калибровки модулей DualSense Edge теперь доступна в качестве <b>экспериментальной функции</b>",
|
||||
"Thank you for your generosity and support!": "Спасибо за вашу щедрость и поддержку",
|
||||
"The DualShock Calibration GUI does not currently support the DualSense Edge.": "В настоящее время графический интерфейс калибровки DualShock не поддерживает DualSense Edge.",
|
||||
"This involves temporarily disabling write protection by applying <b>+1.8V</b> to a specific test point on each module.": "Для этого необходимо временно отключить защиту от записи, подав напряжение <b>+1,8 В</b> на определенную контрольную точку на каждом модуле.",
|
||||
"This is only for advanced users. If you're not sure what you're doing, please do not attempt it.": "Только для продвинутых пользователей! Если вы не уверены ",
|
||||
"This screen allows to finetune raw calibration data on your controller": "На этом экране можно более точно откалибровать ваш контроллер",
|
||||
"Touchpad FW Version": "Версия прошивки тачпада",
|
||||
"Touchpad ID": "ID тачпада",
|
||||
"VCM Left Barcode": "Штрих-код левого VCM",
|
||||
"VCM Right Barcode": "Штрих-код правого VCM",
|
||||
"Venom FW Version": "Версия прошивки Venom",
|
||||
"We are not responsible for any damage caused by attempting this modification.": "Мы не несем ответсвенности за какой-либо причиненный ущерб данной модификацией",
|
||||
"You can do this in two ways:": "Это можно сделать двумя способами",
|
||||
"here": "здесь",
|
||||
"left module": "Левый модуль",
|
||||
"right module": "Правый модуль",
|
||||
"10x zoom": "",
|
||||
"30th Anniversary": "",
|
||||
"<b>Externally</b>: by applying +1.8V directly to the visible test point without opening the controller": "",
|
||||
"<b>Internally</b>: by soldering a wire from a +1.8V source to the write-protect TP.": "",
|
||||
"Astro Bot": "",
|
||||
"Battery Barcode": "",
|
||||
"Bluetooth Address": "",
|
||||
"Calibration is being stored in the stick modules.": "",
|
||||
"Cancel": "",
|
||||
"Cannot lock": "",
|
||||
"Cannot store data into": "",
|
||||
"Cannot unlock": "",
|
||||
"Center X": "",
|
||||
"Center Y": "",
|
||||
"Calibration": "",
|
||||
"Center (L1)": "",
|
||||
"Chroma Indigo": "",
|
||||
"Chroma Pearl": "",
|
||||
"Chroma Teal": "",
|
||||
"Circularity (R1)": "",
|
||||
"Cobalt Blue": "",
|
||||
"Color": "",
|
||||
"Color detection thanks to": "",
|
||||
"Controller Info": "",
|
||||
"Cosmic Red": "",
|
||||
"Debug Info": "",
|
||||
"Debug buttons": "",
|
||||
"DualSense Edge Calibration": "",
|
||||
"FW Build Date": "",
|
||||
"FW Series": "",
|
||||
"FW Type": "",
|
||||
"FW Update": "",
|
||||
"FW Update Info": "",
|
||||
"FW Version": "",
|
||||
"Finetune stick calibration": "",
|
||||
"For more info or help, feel free to reach out on Discord.": "",
|
||||
"Debug": "",
|
||||
"Error triggering rumble": "",
|
||||
"Fortnite": "",
|
||||
"Galactic Purple": "",
|
||||
"God of War Ragnarok": "",
|
||||
"Grey Camouflage": "",
|
||||
"HW Model": "",
|
||||
"Hardware": "",
|
||||
"I'm actively working on adding compatibility, the primary challenge lies in storing data into the stick modules.": "",
|
||||
"If the calibration is not stored permanently, please double-check the wirings of the hardware mod.": "",
|
||||
"If this tool has been helpful to you or you want to see DualSense Edge support arrive faster, please consider supporting the project with a": "",
|
||||
"Left Module Barcode": "",
|
||||
"Left stick": "",
|
||||
"MCU Unique ID": "",
|
||||
"Info": "",
|
||||
"Midnight Black": "",
|
||||
"More details and images": "",
|
||||
"Move the stick to select it for tuning, then without touching the stick use the D-pad buttons to adjust the center point. Flick it and adjust it again if it is off center or flickers.": "",
|
||||
"Normal": "",
|
||||
"Nova Pink": "",
|
||||
"PCBA ID": "",
|
||||
"Please connect a DualShock 4, a DualSense or DualSense Edge controller to your computer and press Connect.": "",
|
||||
"Please note: the stick modules on the DS Edge <b>cannot be calibrated via software alone</b>.To store a custom calibration on the stick's internal memory, a <b>hardware modification</b> is required.": "",
|
||||
"Right Module Barcode": "",
|
||||
"Right stick": "",
|
||||
"SBL FW Version": "",
|
||||
"Save": "",
|
||||
"Serial Number": "",
|
||||
"Show all": "",
|
||||
"Software": "",
|
||||
"Spider FW Version": "",
|
||||
"Please release the stick to center position before adjusting with D-pad buttons.": "",
|
||||
"Press L2 to test the strong (left) haptic motor": "",
|
||||
"Press R2 to test the weak (right) haptic motor": "",
|
||||
"Press the D-pad or face buttons in the direction you want the stick position to move.": "",
|
||||
"Push the stick straight up/down/left/right as far as possible.": "",
|
||||
"Show raw numbers": "",
|
||||
"Spider-Man 2": "",
|
||||
"Starlight Blue": "",
|
||||
"Sterling Silver": "",
|
||||
"Support for calibrating DualSense Edge stick modules is now available as an <b>experimental feature</b>.": "",
|
||||
"Thank you for your generosity and support!": "",
|
||||
"The DualShock Calibration GUI does not currently support the DualSense Edge.": "",
|
||||
"This involves temporarily disabling write protection by applying <b>+1.8V</b> to a specific test point on each module.": "",
|
||||
"This is only for advanced users. If you're not sure what you're doing, please do not attempt it.": "",
|
||||
"This screen allows to finetune raw calibration data on your controller": "",
|
||||
"Touchpad FW Version": "",
|
||||
"Touchpad ID": "",
|
||||
"VCM Left Barcode": "",
|
||||
"VCM Right Barcode": "",
|
||||
"Venom FW Version": "",
|
||||
"Test the Haptic Motors": "",
|
||||
"Tests": "",
|
||||
"The Last of Us": "",
|
||||
"The device is connected via Bluetooth. Disconnect and reconnect using a USB cable instead.": "",
|
||||
"The motor strength will match how hard you press the trigger": "",
|
||||
"Volcanic Red": "",
|
||||
"We are not responsible for any damage caused by attempting this modification.": "",
|
||||
"While holding the stick to be adjusted straight up/down/left/right, <em>observe the highlighted value below the circle</em>, then use the D-pad buttons to adjust the value to ±0.99 (just below ±1.00).": "",
|
||||
"White": "",
|
||||
"You can do this in two ways:": "",
|
||||
"here": "",
|
||||
"left module": "",
|
||||
"right module": "",
|
||||
"Your device might not be a genuine Sony controller. If it is not a clone then please report this issue.": "",
|
||||
"": ""
|
||||
}
|
||||
237
lang/tr_tr.json
237
lang/tr_tr.json
@@ -1,27 +1,27 @@
|
||||
{
|
||||
".authorMsg": "- Çeviri: <a href='https://www.youtube.com/channel/UC8pzDCIt_CUj8sa7cYgPzHQ'>Tamir-Teknik</a> tarafından yapılmıştır.",
|
||||
".authorMsg": "- Çeviri: <a href='https://www.youtube.com/channel/UC8pzDCIt_CUj8sa7cYgPzHQ'>Tamir-Teknik</a> ve <a href='https://share.google/hCBJV5fFMbd5gJxxZ'>CzR PlayStation&Bilgisayar Teknik Servis</a> tarafından yapılmıştır.",
|
||||
"DualShock Calibration GUI": "DualShock Kalibrasyon Arayüzü",
|
||||
"Unsupported browser. Please use a web browser with WebHID support (e.g. Chrome).": "Desteklenmeyen tarayıcı. Lütfen WebHID desteği olan bir web tarayıcısı kullanın (örneğin, Chrome).",
|
||||
"Connect": "Bağlan",
|
||||
"Connected to:": "Bağlanılan cihaz:",
|
||||
"Connected to:": "Bağlanılan Cihaz:",
|
||||
"Disconnect": "Bağlantıyı Kes",
|
||||
"Calibrate stick center": "Analog merkezini kalibre et",
|
||||
"Calibrate stick range": "Analog ara mesafeyi kalibre et",
|
||||
"Calibrate stick center": "Analog Merkezini Kalibre Et",
|
||||
"Calibrate stick range": "Analog Ara Mesafeyi Kalibre Et",
|
||||
"Sections below are not useful, just some debug infos or manual commands": "Aşağıdaki bölümler kullanışlı değildir, sadece bazı hata ayıklama bilgileri veya manuel komutlar içerir",
|
||||
"NVS Status": "NVS Durumu",
|
||||
"Unknown": "Bilinmiyor",
|
||||
"Query NVS status": "NVS durumunu sorgula",
|
||||
"NVS unlock": "NVS kilidini aç",
|
||||
"NVS lock": "NVS kilitle",
|
||||
"Fast calibrate stick center (OLD)": "Analog merkezini hızlı kalibre et (ESKİ)",
|
||||
"Stick center calibration": "Analog merkezi kalibrasyonu",
|
||||
"Fast calibrate stick center (OLD)": "Analog Merkezini Hızlı Kalibre Et (ESKİ)",
|
||||
"Stick center calibration": "Analog Merkezi Kalibrasyonu",
|
||||
"Welcome": "Hoş geldiniz",
|
||||
"Step 1": "Adım 1",
|
||||
"Step 2": "Adım 2",
|
||||
"Step 3": "Adım 3",
|
||||
"Step 4": "Adım 4",
|
||||
"Step 1": "1.Adım",
|
||||
"Step 2": "2.Adım",
|
||||
"Step 3": "3.Adım",
|
||||
"Step 4": "4.Adım",
|
||||
"Completed": "Tamamlandı",
|
||||
"Welcome to the stick center-calibration wizard!": "Analog merkesi kalibrasyon sihirbazına hoş geldiniz!",
|
||||
"Welcome to the stick center-calibration wizard!": "Analog Merkezi Kalibrasyon Sihirbazına Hoş Geldiniz!",
|
||||
"This tool will guide you in re-centering the analog sticks of your controller. It consists in four steps: you will be asked to move both sticks in a direction and release them.": "Bu araç, denetleyicinizin analog çubuklarını yeniden merkezlemekte size rehberlik edecektir. Dört adımdan oluşur: Her iki çubuğu da bir yönde hareket ettirmeniz ve ardından bırakmanız istenecektir.",
|
||||
"Please be aware that, <i>once the calibration is running, it cannot be canceled</i>. Do not close this page or disconnect your controller until is completed.": "Lütfen bilin ki, <i>kalibrasyon başladığında, iptal edilemez</i>. Tamamlanana kadar bu sayfayı kapatmayın veya denetleyici bağlantısını kesmeyin.",
|
||||
"Press <b>Start</b> to begin calibration.": "Kalibrasyonu başlatmak için <b>Başlat</b> düğmesine basın.",
|
||||
@@ -32,9 +32,9 @@
|
||||
"Please move both sticks to the <b>bottom-right corner</b> and release them.": "Lütfen her iki analogu <b>sağ alt köşeye</b> taşıyın ve bırakın.",
|
||||
"Calibration completed successfully!": "Kalibrasyon başarıyla tamamlandı!",
|
||||
"Next": "İleri",
|
||||
"Recentering the controller sticks. ": "Denetleyici analoglarını yeniden merkezleme. ",
|
||||
"Recentering the controller sticks.": "Denetleyici analoglarını yeniden merkezleme.",
|
||||
"Please do not close this window and do not disconnect your controller. ": "Lütfen bu pencereyi kapatmayın ve denetleyici bağlantısını kesmeyin. ",
|
||||
"Range calibration": "Ara mesafe kalibrasyonu",
|
||||
"Range calibration": "Ara Mesafe Kalibrasyonu",
|
||||
"<b>The controller is now sampling data!</b>": "<b>Denetleyici şu anda veri örnekleme yapıyor!</b>",
|
||||
"Rotate the sticks slowly to cover the whole range. Press \"Done\" when completed.": "Tüm aralığı kapsamak için analogları yavaşça döndürün. Tamamlandığında \"Tamam\" düğmesine basın.",
|
||||
"Done": "Tamamlandı",
|
||||
@@ -45,27 +45,27 @@
|
||||
"Do you have any suggestion or issue? Drop me a message via email or discord.": "Herhangi bir öneriniz veya sorunuz var mı? Bana e-posta veya discord üzerinden mesaj atabilirsiniz.",
|
||||
"Cheers!": "Teşekkürler!",
|
||||
"Support this project": "Bu projeyi destekle",
|
||||
"unknown": "bilinmeyen",
|
||||
"original": "orijinal",
|
||||
"clone": "klon",
|
||||
"locked": "kilitli",
|
||||
"unlocked": "kilidi açık",
|
||||
"error": "hata",
|
||||
"unknown": "Bilinmeyen",
|
||||
"original": "Orijinal",
|
||||
"clone": "Yan Sanayi",
|
||||
"locked": "Kilitli",
|
||||
"unlocked": "Kilidi açık",
|
||||
"error": "Hata",
|
||||
"Build Date": "Derleme Tarihi",
|
||||
"HW Version": "Donanım Sürümü",
|
||||
"SW Version": "Yazılım Sürümü",
|
||||
"Device Type": "Cihaz Türü",
|
||||
"Range calibration completed": "Ara mesafe kalibrasyonu tamamlandı",
|
||||
"Range calibration failed: ": "Ara mesafe kalibrasyonu başarısız oldu: ",
|
||||
"Range calibration failed": "Ara mesafe kalibrasyonu başarısız oldu",
|
||||
"Cannot unlock NVS": "NVS kilidi açılamıyor",
|
||||
"Cannot relock NVS": "NVS kilidi tekrar kilitlenemiyor",
|
||||
"Error 1": "Hata 1",
|
||||
"Error 2": "Hata 2",
|
||||
"Error 3": "Hata 3",
|
||||
"Stick calibration failed: ": "Analog kalibrasyonu başarısız oldu: ",
|
||||
"Error 1": "1.Hata",
|
||||
"Error 2": "2.Hata",
|
||||
"Error 3": "3.Hata",
|
||||
"Stick calibration failed": "Analog kalibrasyonu başarısız oldu",
|
||||
"Stick calibration completed": "Analog kalibrasyonu tamamlandı",
|
||||
"NVS Lock failed: ": "NVS kilidi kilitlenemedi: ",
|
||||
"NVS Unlock failed: ": "NVS kilidi açılamadı: ",
|
||||
"NVS Lock failed": "NVS kilidi kilitlenemedi",
|
||||
"NVS Unlock failed": "NVS kilidi açılamadı",
|
||||
"Please connect only one controller at time.": "Lütfen sadece bir denetleyici bağlayın.",
|
||||
"Sony DualShock 4 V1": "Sony DualShock 4 V1",
|
||||
"Sony DualShock 4 V2": "Sony DualShock 4 V2",
|
||||
@@ -134,16 +134,13 @@
|
||||
"This feature is experimental.": "Bu özellik deneysel.",
|
||||
"Please let me know if the board model of your controller is not detected correctly.": "Denetleyicinizin kart modeli doğru tespit edilmezse lütfen bana bildirin.",
|
||||
"Board model detection thanks to": "Kart modeli tespiti sayesinde",
|
||||
"Please connect the device using a USB cable.": "Lütfen cihazı bir USB kablosu kullanarak bağlayın.",
|
||||
"This DualSense controller has outdated firmware.": "Bu DualSense denetleyicisinin yazılımı güncel değil.",
|
||||
"Please update the firmware and try again.": "Lütfen yazılımı güncelleyin ve tekrar deneyin.",
|
||||
"Joystick Info": "Joystick Bilgisi",
|
||||
"Err R:": "Hata D:",
|
||||
"Err L:": "Hata S:",
|
||||
"Check circularity": "Daireselliği kontrol et",
|
||||
"Can I reset a permanent calibration to previous calibration?": "Kalıcı bir kalibrasyonu önceki kalibrasyona sıfırlayabilir miyim?",
|
||||
"No.": "Hayır.",
|
||||
"Can you overwrite a permanent calibration?": "Kalıcı bir kalibrasyonun üzerine yeniden yazabilirmiyiz",
|
||||
"Can you overwrite a permanent calibration?": "Kalıcı bir kalibrasyonun üzerine yeniden yazabilir miyiz?",
|
||||
"Yes. Simply do another permanent calibration.": "Evet. Sadece yeni bir kalıcı kalibrasyon yapın.",
|
||||
"Does this software resolve stickdrift?": "Bu yazılım analog kaydırma sorununu çözer mi?",
|
||||
"Stickdrift is caused by a physical defect; namely dirt, worn potentiometer or in some cases a worn spring.": "Analog kaydırması fiziksel bir arızadan kaynaklanır; kir, aşınmış potansiyometre veya bazı durumlarda aşınmış bir yaydan.",
|
||||
@@ -157,83 +154,111 @@
|
||||
"Make sure to touch the edges of the joystick frame and rotate slowly, preferably in each direction - clockwise and anti-clockwise.": "Analog çerçevesinin kenarlarına dokunduğunuzdan emin olun ve yavaşça döndürün; tercihen her iki yönde - hem saat yönünde, hem saat yönünün tersine.",
|
||||
"Only after you have done that, you click on \"Done\".": "Ancak bunu yaptıktan sonra \"Tamam\" butonuna basmalısınız.",
|
||||
"Changes saved successfully": "Değişiklikler başarıyla kaydedildi.",
|
||||
"Error while saving changes:": "Değişiklikleri kaydederken hata:",
|
||||
"Error while saving changes": "Değişiklikleri kaydederken hata:",
|
||||
"Save changes permanently": "Değişiklikleri kalıcı olarak kaydet",
|
||||
"Reboot controller": "Denetleyiciyi yeniden başlat",
|
||||
"(beta)": "",
|
||||
"30th Anniversary": "",
|
||||
"<b>Externally</b>: by applying +1.8V directly to the visible test point without opening the controller": "",
|
||||
"<b>Internally</b>: by soldering a wire from a +1.8V source to the write-protect TP.": "",
|
||||
"Astro Bot": "",
|
||||
"Battery Barcode": "",
|
||||
"Bluetooth Address": "",
|
||||
"Calibration is being stored in the stick modules.": "",
|
||||
"Cancel": "",
|
||||
"Cannot lock": "",
|
||||
"Cannot store data into": "",
|
||||
"Cannot unlock": "",
|
||||
"Center X": "",
|
||||
"Center Y": "",
|
||||
"Cobalt Blue": "",
|
||||
"Color": "",
|
||||
"Color detection thanks to": "",
|
||||
"Controller Info": "",
|
||||
"Cosmic Red": "",
|
||||
"Debug Info": "",
|
||||
"Debug buttons": "",
|
||||
"DualSense Edge Calibration": "",
|
||||
"FW Build Date": "",
|
||||
"FW Series": "",
|
||||
"FW Type": "",
|
||||
"FW Update": "",
|
||||
"FW Update Info": "",
|
||||
"FW Version": "",
|
||||
"Finetune stick calibration": "",
|
||||
"For more info or help, feel free to reach out on Discord.": "",
|
||||
"Galactic Purple": "",
|
||||
"God of War Ragnarok": "",
|
||||
"Grey Camouflage": "",
|
||||
"HW Model": "",
|
||||
"Hardware": "",
|
||||
"I'm actively working on adding compatibility, the primary challenge lies in storing data into the stick modules.": "",
|
||||
"If the calibration is not stored permanently, please double-check the wirings of the hardware mod.": "",
|
||||
"If this tool has been helpful to you or you want to see DualSense Edge support arrive faster, please consider supporting the project with a": "",
|
||||
"Left Module Barcode": "",
|
||||
"Left stick": "",
|
||||
"MCU Unique ID": "",
|
||||
"Midnight Black": "",
|
||||
"More details and images": "",
|
||||
"Nova Pink": "",
|
||||
"PCBA ID": "",
|
||||
"Please connect a DualShock 4, a DualSense or DualSense Edge controller to your computer and press Connect.": "",
|
||||
"Please note: the stick modules on the DS Edge <b>cannot be calibrated via software alone</b>.To store a custom calibration on the stick's internal memory, a <b>hardware modification</b> is required.": "",
|
||||
"Right Module Barcode": "",
|
||||
"Right stick": "",
|
||||
"SBL FW Version": "",
|
||||
"Save": "",
|
||||
"Serial Number": "",
|
||||
"Show all": "",
|
||||
"Software": "",
|
||||
"Spider FW Version": "",
|
||||
"Starlight Blue": "",
|
||||
"Sterling Silver": "",
|
||||
"Support for calibrating DualSense Edge stick modules is now available as an <b>experimental feature</b>.": "",
|
||||
"Thank you for your generosity and support!": "",
|
||||
"The DualShock Calibration GUI does not currently support the DualSense Edge.": "",
|
||||
"This involves temporarily disabling write protection by applying <b>+1.8V</b> to a specific test point on each module.": "",
|
||||
"This is only for advanced users. If you're not sure what you're doing, please do not attempt it.": "",
|
||||
"This screen allows to finetune raw calibration data on your controller": "",
|
||||
"Touchpad FW Version": "",
|
||||
"Touchpad ID": "",
|
||||
"VCM Left Barcode": "",
|
||||
"VCM Right Barcode": "",
|
||||
"Venom FW Version": "",
|
||||
"Volcanic Red": "",
|
||||
"We are not responsible for any damage caused by attempting this modification.": "",
|
||||
"White": "",
|
||||
"You can do this in two ways:": "",
|
||||
"here": "",
|
||||
"left module": "",
|
||||
"right module": "",
|
||||
"(beta)": "(beta)",
|
||||
"30th Anniversary": "30. Yıl Dönümü",
|
||||
"<b>Externally</b>: by applying +1.8V directly to the visible test point without opening the controller.": "<b>Harici olarak</b>: Denetleyiciyi açmadan görünür test noktasına doğrudan +1.8V uygulayarak",
|
||||
"<b>Internally</b>: by soldering a wire from a +1.8V source to the write-protect TP.": "<b>Dahili olarak</b>: +1.8V bir kaynaktan yazma koruma TP'sine bir kablo lehimleyerek.",
|
||||
"Astro Bot": "Astro Bot",
|
||||
"Battery Barcode": "Batarya Barkodu",
|
||||
"Bluetooth Address": "Bluetooth Adresi",
|
||||
"Calibration is being stored in the stick modules.": "Kalibrasyon, analog modüllerine kaydediliyor.",
|
||||
"Cancel": "İptal",
|
||||
"Cannot lock": "Kilitlenemiyor",
|
||||
"Cannot store data into": "Veri kaydedilemiyor",
|
||||
"Cannot unlock": "Kilit açılamıyor",
|
||||
"Center X": "Merkez X",
|
||||
"Center Y": "Merkez Y",
|
||||
"Chroma Indigo": "Kroma İndigo",
|
||||
"Chroma Pearl": "Kroma İnci",
|
||||
"Chroma Teal": "Kroma Turkuaz",
|
||||
"Cobalt Blue": "Kobalt Mavisi",
|
||||
"Color": "Renk",
|
||||
"Color detection thanks to": "Renk tespiti sayesinde",
|
||||
"Controller Info": "Denetleyici Bilgisi",
|
||||
"Cosmic Red": "Kozmik Kırmızı",
|
||||
"Debug Info": "Hata Ayıklama Bilgisi",
|
||||
"Debug buttons": "Hata ayıklama düğmeleri",
|
||||
"DualSense Edge Calibration": "DualSense Edge Kalibrasyonu",
|
||||
"FW Build Date": "FW Derleme Tarihi",
|
||||
"FW Series": "FW Serisi",
|
||||
"FW Type": "FW Türü",
|
||||
"FW Update": "FW Güncellemesi",
|
||||
"FW Update Info": "FW Güncelleme Bilgisi",
|
||||
"FW Version": "FW Sürümü",
|
||||
"Finetune stick calibration": "Analog Kalibrasyonunu İnce Ayarla",
|
||||
"For more info or help, feel free to reach out on Discord.": "Daha fazla bilgi veya yardım için Discord üzerinden ulaşabilirsiniz.",
|
||||
"Fortnite": "Fortnite",
|
||||
"Galactic Purple": "Galaktik Mor",
|
||||
"God of War Ragnarok": "God of War Ragnarok",
|
||||
"Grey Camouflage": "Gri Kamuflaj",
|
||||
"HW Model": "HW Modeli",
|
||||
"Hardware": "Donanım",
|
||||
"I'm actively working on adding compatibility, the primary challenge lies in storing data into the stick modules.": "Uyumluluk ekleme üzerinde aktif olarak çalışıyorum, asıl zorluk verilerin analog modüllere kaydedilmesinde yatıyor.",
|
||||
"If the calibration is not stored permanently, please double-check the wirings of the hardware mod.": "Kalibrasyon kalıcı olarak kaydedilmezse, lütfen donanım modunun kablolamasını iki kez kontrol edin.",
|
||||
"If this tool has been helpful to you or you want to see DualSense Edge support arrive faster, please consider supporting the project with a": "Eğer bu araç size yardımcı olduysa veya DualSense Edge desteğinin daha hızlı gelmesini istiyorsanız, lütfen projeyi bir",
|
||||
"Left Module Barcode": "Sol Modül Barkodu",
|
||||
"Left stick": "Sol analog",
|
||||
"MCU Unique ID": "MCU Benzersiz Kimliği",
|
||||
"Midnight Black": "Gece Yarısı Siyahı",
|
||||
"More details and images": "Daha fazla detay ve görsel",
|
||||
"Nova Pink": "Nova Pembe",
|
||||
"PCBA ID": "PCBA Kimliği",
|
||||
"Please connect a DualShock 4, a DualSense or DualSense Edge controller to your computer and press Connect.": "Lütfen bilgisayarınıza bir DualShock 4, bir DualSense veya DualSense Edge denetleyici bağlayın ve Bağlan'a basın.",
|
||||
"Please note: the stick modules on the DS Edge <b>cannot be calibrated via software alone</b>.": "Lütfen dikkat: DS Edge üzerindeki analog modülleri <b>yalnızca yazılım aracılığıyla kalibre edilemez</b>.",
|
||||
"To store a custom calibration on the stick's internal memory, a <b>hardware modification</b> is required.": "Özelleştirilmiş bir kalibrasyonu analogun dahili belleğine kaydetmek için bir <b>donanım değişikliği</b> gereklidir.",
|
||||
"Right Module Barcode": "Sağ Modül Barkodu",
|
||||
"Right stick": "Sağ analog",
|
||||
"SBL FW Version": "SBL FW Sürümü",
|
||||
"Save": "Kaydet",
|
||||
"Serial Number": "Seri Numarası",
|
||||
"Show all": "Tümünü göster",
|
||||
"Software": "Yazılım",
|
||||
"Spider FW Version": "Örümcek FW Sürümü",
|
||||
"Spider-Man 2": "Örümcek-Adam 2",
|
||||
"Starlight Blue": "Yıldız Işığı Mavisi",
|
||||
"Sterling Silver": "Gümüş",
|
||||
"Support for calibrating DualSense Edge stick modules is now available as an <b>experimental feature</b>.": "DualSense Edge analog modüllerinin kalibrasyonuna destek, artık <b>deneysel bir özellik</b> olarak mevcuttur.",
|
||||
"Thank you for your generosity and support!": "Cömertliğiniz ve desteğiniz için teşekkür ederiz!",
|
||||
"The DualShock Calibration GUI does not currently support the DualSense Edge.": "DualShock Kalibrasyon Arayüzü şu anda DualSense Edge'i desteklemiyor.",
|
||||
"The Last of Us": "The Last of Us",
|
||||
"This involves temporarily disabling write protection by applying <b>+1.8V</b> to a specific test point on each module.": "Bu, her modül üzerindeki belirli bir test noktasına <b>+1.8V</b> uygulayarak yazma korumasını geçici olarak devre dışı bırakmayı içerir.",
|
||||
"This is only for advanced users. If you're not sure what you're doing, please do not attempt it.": "Bu sadece ileri düzey kullanıcılar içindir. Ne yaptığınızdan emin değilseniz, lütfen denemeyin.",
|
||||
"This screen allows to finetune raw calibration data on your controller": "Bu ekran, denetleyicinizdeki ham kalibrasyon verilerini ince ayarlamaya olanak tanır",
|
||||
"Touchpad FW Version": "Dokunmatik Yüzey FW Sürümü",
|
||||
"Touchpad ID": "Dokunmatik Yüzey Kimliği",
|
||||
"VCM Left Barcode": "VCM Sol Barkodu",
|
||||
"VCM Right Barcode": "VCM Sağ Barkodu",
|
||||
"Venom FW Version": "Venom FW Sürümü",
|
||||
"Volcanic Red": "Volkanik Kırmızı",
|
||||
"We are not responsible for any damage caused by attempting this modification.": "Bu modifikasyonu denemenin neden olduğu herhangi bir hasardan sorumlu değiliz.",
|
||||
"White": "Beyaz",
|
||||
"You can do this in two ways:": "Bunu iki şekilde yapabilirsiniz:",
|
||||
"here": "burada",
|
||||
"left module": "Sol Modül",
|
||||
"right module": "Sağ Modül",
|
||||
"10x zoom": "10x Yakınlaştırma",
|
||||
"Calibration": "KALİBRASYON",
|
||||
"Debug": "HATA AYIKLAMA",
|
||||
"Error triggering rumble": "Titreşim tetiklenirken hata oluştu",
|
||||
"Info": "BİLGİ",
|
||||
"Normal": "Normal",
|
||||
"Press L2 to test the strong (left) haptic motor": "Güçlü (sol) dokunsal motoru test etmek için L2'ye basın",
|
||||
"Press R2 to test the weak (right) haptic motor": "Zayıf (sağ) dokunsal motoru test etmek için R2'ye basın",
|
||||
"Test the Haptic Motors": "Dokunsal Motorları Test Et",
|
||||
"Tests": "Testler",
|
||||
"The motor strength will match how hard you press the trigger": "Motor gücü, tetiğe ne kadar sert bastığınızla orantılı olacaktır",
|
||||
"Center (L1)": "Merkez (L1)",
|
||||
"Circularity (R1)": "Dairesellik (R1)",
|
||||
"Move the stick to select it for tuning, then without touching the stick use the D-pad buttons to adjust the center point. Flick it and adjust it again if it is off center or flickers.": "Analoğu ayar için seçin, ardından analoğa dokunmadan yön tuşlarını kullanarak merkez noktasını ayarlayın. Analoğu hafifçe oynatın, merkezden kaymışsa veya titreme oluyorsa tekrar ayarlayın.",
|
||||
"Please release the stick to center position before adjusting with D-pad buttons.": "Lütfen yön tuşlarıyla ayarlamadan önce analoğu merkez konumuna bırakın.",
|
||||
"Press the D-pad or face buttons in the direction you want the stick position to move.": "Analoğun konumunu hareket ettirmek istediğiniz yöne yön tuşlarına veya yüz tuşlarına(△, ☐, O, ✕) basın.",
|
||||
"Push the stick straight up/down/left/right as far as possible.": "Analoğu mümkün olduğunca yukarı/aşağı/sola/sağa itin.",
|
||||
"Show raw numbers": "Ham değerleri göster",
|
||||
"While holding the stick to be adjusted straight up/down/left/right, <em>observe the highlighted value below the circle</em>, then use the D-pad buttons to adjust the value to ±0.99 (just below ±1.00).": "Ayarlanacak analoğu yukarı/aşağı/sola/sağa doğru basılı tutarken, <em>dairenin altındaki vurgulanan değeri gözlemleyin</em> ve ardından değeri ±0,99’a (±1,00’ın hemen altına) ayarlamak için yön tuşlarını kullanın.",
|
||||
"The device is connected via Bluetooth. Disconnect and reconnect using a USB cable instead.": "",
|
||||
"Your device might not be a genuine Sony controller. If it is not a clone then please report this issue.": "",
|
||||
"": ""
|
||||
}
|
||||
119
lang/ua_ua.json
119
lang/ua_ua.json
@@ -33,7 +33,7 @@
|
||||
"Please move both sticks to the <b>bottom-right corner</b> and release them.": "Будь ласка, перемістіть обидва стіки в <b>нижній правий кут</b> і відпустіть їх.",
|
||||
"Calibration completed successfully!": "Калібрування успішно завершено!",
|
||||
"Next": "Далі",
|
||||
"Recentering the controller sticks. ": "Центрування стіків контролера. ",
|
||||
"Recentering the controller sticks.": "Центрування стіків контролера.",
|
||||
"Please do not close this window and do not disconnect your controller. ": "Будь ласка, не закривайте це вікно і не відключайте ваш контролер. ",
|
||||
"Range calibration": "Калібрування діапазону.",
|
||||
"<b>The controller is now sampling data!</b>": "<b>Контролер зараз збирає дані!</b>",
|
||||
@@ -57,16 +57,16 @@
|
||||
"SW Version": "Версія програмного забезпечення",
|
||||
"Device Type": "Тип пристрою",
|
||||
"Range calibration completed": "Калібрування діапазону завершено",
|
||||
"Range calibration failed: ": "Калібрування діапазону не вдалося: ",
|
||||
"Range calibration failed": "Калібрування діапазону не вдалося",
|
||||
"Cannot unlock NVS": "Не вдається розблокувати NVS",
|
||||
"Cannot relock NVS": "Не вдається заблокувати NVS повторно",
|
||||
"Error 1": "Помилка 1",
|
||||
"Error 2": "Помилка 2",
|
||||
"Error 3": "Помилка 3",
|
||||
"Stick calibration failed: ": "Калібрування джойстика не вдалося: ",
|
||||
"Stick calibration failed": "Калібрування джойстика не вдалося",
|
||||
"Stick calibration completed": "Калібрування джойстика завершено",
|
||||
"NVS Lock failed: ": "Блокування NVS не вдалося: ",
|
||||
"NVS Unlock failed: ": "Розблокування NVS не вдалося: ",
|
||||
"NVS Lock failed": "Блокування NVS не вдалося",
|
||||
"NVS Unlock failed": "Розблокування NVS не вдалося",
|
||||
"Please connect only one controller at time.": "Будь ласка, підключайте лише один контролер одночасно.",
|
||||
"Sony DualShock 4 V1": "Sony DualShock 4 V1",
|
||||
"Sony DualShock 4 V2": "Sony DualShock 4 V2",
|
||||
@@ -85,11 +85,11 @@
|
||||
"You can check the calibration with the": "Ви можете перевірити калібрування за допомогою",
|
||||
"Have a nice day :)": "Гарного дня! :)",
|
||||
"Welcome to the Calibration GUI": "Ласкаво просимо до інтерфейсу калібрування",
|
||||
"Just few things to know before you can start:": "Кілька речей, які потрібно знати перед початком:",
|
||||
"This website is not affiliated with Sony, PlayStation & co.": "Цей сайт не має відношення до Sony, PlayStation та інших компаній.",
|
||||
"This service is provided without warranty. Use at your own risk.": "Цей сервіс надається без гарантії. Використовувати на власний ризик.",
|
||||
"Keep the internal battery of the controller connected and ensure it is well charged. If the battery dies during operations, the controller will be damaged and rendered unusable.": "Тримайте внутрішню батарею контролера підключеною та переконайтеся, що вона добре заряджена. Якщо батарея розрядиться під час операцій, контролер буде пошкоджено і стане непридатним для використання.",
|
||||
"Before doing the permanent calibration, try the temporary one to ensure that everything is working well.": "Перед постійним калібруванням спробуйте тимчасове, щоб переконатися, що все працює добре.",
|
||||
"Just few things to know before you can start:": "Кілька моментів, які слід врахувати перед початком:",
|
||||
"This website is not affiliated with Sony, PlayStation & co.": "Цей сайт не має стосунку до Sony, PlayStation чи будь-яких інших компаній.",
|
||||
"This service is provided without warranty. Use at your own risk.": "Сервіс надається без гарантій. Користуйтеся на власний ризик.",
|
||||
"Keep the internal battery of the controller connected and ensure it is well charged. If the battery dies during operations, the controller will be damaged and rendered unusable.": "Тримайте внутрішню батарею контролера під’єднаною та впевніться, що вона достатньо заряджена. Якщо акумулятор розрядиться під час процесу, пристрій може пошкодитися або почати працювати некоректно.",
|
||||
"Before doing the permanent calibration, try the temporary one to ensure that everything is working well.": "Перед основним калібруванням зробіть коротку перевірку, щоб пересвідчитися, що все функціонує належним чином.",
|
||||
"Understood": "Зрозуміло",
|
||||
"Version": "Версія",
|
||||
"Frequently Asked Questions": "Часто задавані питання",
|
||||
@@ -130,17 +130,14 @@
|
||||
"Ship me a controller you would love to add (send me an email for organization).": "Надішліть мені контролер, який ви хочете додати (відправте мені електронний лист для організації).",
|
||||
"Translate this website in your language": "Перекладіть цей сайт на вашу мову",
|
||||
", to help more people like you!": ", щоб допомогти більшій кількості людей, подібних до вас!",
|
||||
"This website uses analytics to improve the service.": "Цей сайт використовує аналітику для покращення сервісу.",
|
||||
"This website uses analytics to improve the service.": "Платформа застосовує аналітику для вдосконалення роботи.",
|
||||
"Board Model": "Модель плати",
|
||||
"This feature is experimental.": "Ця функція є експериментальною.",
|
||||
"Please let me know if the board model of your controller is not detected correctly.": "Будь ласка, повідомте, якщо модель плати вашого контролера визначена неправильно.",
|
||||
"Board model detection thanks to": "Визначення моделі плати завдяки",
|
||||
"Please connect the device using a USB cable.": "Будь ласка, підключіть пристрій за допомогою USB-кабелю.",
|
||||
"This DualSense controller has outdated firmware.": "Прошивка цього контролера DualSense застаріла.",
|
||||
"Please update the firmware and try again.": "Будь ласка, оновіть прошивку та спробуйте знову.",
|
||||
"Joystick Info": "Інформація про джойстик",
|
||||
"Err R:": "Помилка П:",
|
||||
"Err L:": "Помилка Л:",
|
||||
"Check circularity": "Перевірити округлість",
|
||||
"Can I reset a permanent calibration to previous calibration?": "Чи можу я скинути постійну калибровку до попередньої?",
|
||||
"No.": "Ні.",
|
||||
@@ -149,7 +146,7 @@
|
||||
"Does this software resolve stickdrift?": "Чи вирішує це програмне забезпечення проблему дріфту стиків?",
|
||||
"Stickdrift is caused by a physical defect; namely dirt, worn potentiometer or in some cases a worn spring.": "Дріфт стиків викликається фізичним дефектом; а саме брудом, зношеним потенціометром або, в деяких випадках, зношеною пружиною.",
|
||||
"This software will not fix stick drift on its own if you already experience that. What it will help with, is ensuring the new joystick(s) will function properly after replacing the old one(s) to work well with.": "Це програмне забезпечення не виправить дріфт стиків, якщо ви вже стикаєтеся з цією проблемою. Однак воно допоможе переконатися, що новий джойстик(и) будуть правильно працювати після заміни старого(их).",
|
||||
"I have noticed some controllers out of the box have worse factory calibration than if I would recalibrate them. Especially true for circularity of SCUF controllers with a unique shell.": "Я помітив, що деякі контролери з коробки мають гіршу заводську калібровку, ніж якби я їх перекалібрував. Це особливо стосується кругової точності контролерів SCUF з унікальною оболонкою.",
|
||||
"I have noticed some controllers out of the box have worse factory calibration than if I would recalibrate them. Especially true for circularity of SCUF controllers with a unique shell.": "Я помітив, що деякі контролери з коробки мають гіршу заводську калібровку, ніж якби я їх перекалібрував. Це особливо стосується точності округлості контролерів SCUF з унікальною оболонкою.",
|
||||
"(Dualsense) Will updating the firmware reset calibration?": "Чи скине оновлення прошивки (Dualsense) калібровку?",
|
||||
"After range calibration, joysticks always go in corners.": "Після калібровки діапазону джойстики завжди йдуть у кути.",
|
||||
"This issue happens because you have clicked \"Done\" immediately after starting a range calibration.": "Ця проблема виникає через те, що ви натиснули \"Готово\" одразу після початку калібровки діапазону.",
|
||||
@@ -158,31 +155,31 @@
|
||||
"Make sure to touch the edges of the joystick frame and rotate slowly, preferably in each direction - clockwise and anti-clockwise.": "Переконайтеся, що ви торкаєтесь країв рами джойстика та обертаєте його повільно, бажано в обох напрямках — за годинниковою стрілкою та проти годинникової.",
|
||||
"Only after you have done that, you click on \"Done\".": "Тільки після того, як ви це зробите, натискайте \"Готово\".",
|
||||
"Changes saved successfully": "Зміни успішно збережено",
|
||||
"Error while saving changes:": "Помилка при збереженні змін:",
|
||||
"Error while saving changes": "Помилка при збереженні змін:",
|
||||
"Save changes permanently": "Зберегти зміни назавжди",
|
||||
"Reboot controller": "Перезавантажити контролер",
|
||||
"Controller Info": "Інформація про контролер",
|
||||
"Debug Info": "Інформація для налагодження",
|
||||
"Software": "ПЗ",
|
||||
"Hardware": "Апаратура",
|
||||
"FW Build Date": "Дата складання прошивки",
|
||||
"Software": "Програмне забезпечення",
|
||||
"Hardware": "Апаратне забезпечення",
|
||||
"FW Build Date": "Дата збірки прошивки",
|
||||
"FW Type": "Тип прошивки",
|
||||
"FW Series": "Серія прошивки",
|
||||
"FW Version": "Версія прошивки",
|
||||
"FW Update": "Оновлення прошивки",
|
||||
"FW Update Info": "Інформація про оновлення прошивки",
|
||||
"FW Update Info": "Інфо про оновлення прошивки",
|
||||
"SBL FW Version": "Версія прошивки SBL",
|
||||
"Venom FW Version": "Версія прошивки Venom",
|
||||
"Spider FW Version": "Версія прошивки Spider",
|
||||
"Touchpad FW Version": "Версія прошивки сенсорної панелі",
|
||||
"Touchpad FW Version": "Версія прошивки тачпаду",
|
||||
"Serial Number": "Серійний номер",
|
||||
"MCU Unique ID": "Унікальний ID MCU",
|
||||
"PCBA ID": "ID PCBA",
|
||||
"Battery Barcode": "Штрих-код батареї",
|
||||
"VCM Left Barcode": "Штрих-код VCM лівий",
|
||||
"VCM Right Barcode": "Штрих-код VCM правий",
|
||||
"HW Model": "Модель апаратного забезпечення",
|
||||
"Touchpad ID": "ID сенсорної панелі",
|
||||
"HW Model": "Апаратна модель",
|
||||
"Touchpad ID": "ID тачпаду",
|
||||
"Bluetooth Address": "Bluetooth адреса",
|
||||
"Show all": "Показати все",
|
||||
"(beta)": "(бета)",
|
||||
@@ -200,7 +197,8 @@
|
||||
"Left stick": "Лівий стік",
|
||||
"More details and images": "Більше деталей та зображень",
|
||||
"Please connect a DualShock 4, a DualSense or DualSense Edge controller to your computer and press Connect.": "Будь ласка, підключіть контролер DualShock 4, DualSense або DualSense Edge до комп’ютера та натисніть «Підключити».",
|
||||
"Please note: the stick modules on the DS Edge <b>cannot be calibrated via software alone</b>.To store a custom calibration on the stick's internal memory, a <b>hardware modification</b> is required.": "Зверніть увагу: модулі стіків на DS Edge <b>неможливо відкалібрувати лише програмним шляхом</b>. Щоб зберегти власне калібрування у внутрішній памʼяті стіка, потрібна <b>апаратна модифікація</b>.",
|
||||
"Please note: the stick modules on the DS Edge <b>cannot be calibrated via software alone</b>.": "Зверніть увагу: модулі стіків на DS Edge <b>неможливо відкалібрувати лише програмним шляхом</b>.",
|
||||
"To store a custom calibration on the stick's internal memory, a <b>hardware modification</b> is required.": "Щоб зберегти власне калібрування у внутрішній памʼяті стіка, потрібна <b>апаратна модифікація</b>.",
|
||||
"Right stick": "Правий стік",
|
||||
"Save": "Зберегти",
|
||||
"Support for calibrating DualSense Edge stick modules is now available as an <b>experimental feature</b>.": "Підтримка калібрування модулів стіків DualSense Edge тепер доступна як <b>експериментальна функція</b>.",
|
||||
@@ -212,28 +210,55 @@
|
||||
"We are not responsible for any damage caused by attempting this modification.": "Ми не несемо відповідальності за будь-які пошкодження, спричинені спробами цієї модифікації.",
|
||||
"You can do this in two ways:": "Ви можете зробити це двома способами:",
|
||||
"here": "тут",
|
||||
"30th Anniversary": "",
|
||||
"Astro Bot": "",
|
||||
"Cannot lock": "",
|
||||
"Cannot store data into": "",
|
||||
"Cannot unlock": "",
|
||||
"Cobalt Blue": "",
|
||||
"Color": "",
|
||||
"Color detection thanks to": "",
|
||||
"Cosmic Red": "",
|
||||
"Galactic Purple": "",
|
||||
"God of War Ragnarok": "",
|
||||
"Grey Camouflage": "",
|
||||
"If the calibration is not stored permanently, please double-check the wirings of the hardware mod.": "",
|
||||
"Left Module Barcode": "",
|
||||
"Midnight Black": "",
|
||||
"Nova Pink": "",
|
||||
"Right Module Barcode": "",
|
||||
"Starlight Blue": "",
|
||||
"Sterling Silver": "",
|
||||
"Volcanic Red": "",
|
||||
"White": "",
|
||||
"left module": "",
|
||||
"right module": "",
|
||||
"30th Anniversary": "Обмежена серія до 30-тої річниці",
|
||||
"Astro Bot": "Обмежена серія Astro Bot",
|
||||
"Cannot lock": "Не вдалося заблокувати",
|
||||
"Cannot store data into": "Не вдалося зберегти дані в",
|
||||
"Cannot unlock": "Не вдалося розблокувати",
|
||||
"Cobalt Blue": "Кобальтово-синій",
|
||||
"Color": "Колір",
|
||||
"Color detection thanks to": "Розпізнавання кольору завдяки",
|
||||
"Cosmic Red": "Космічний червоний",
|
||||
"Galactic Purple": "Галактичний пурпуровий",
|
||||
"God of War Ragnarok": "Обмежена серія God of War: Ragnarok",
|
||||
"Grey Camouflage": "Сірий камуфляж",
|
||||
"If the calibration is not stored permanently, please double-check the wirings of the hardware mod.": "Якщо калібрування не зберігається постійно, будь ласка, перевірте підключення апаратної модифікації.",
|
||||
"Left Module Barcode": "Штрих-код лівого модуля",
|
||||
"Midnight Black": "Чорна ніч",
|
||||
"Nova Pink": "Рожевий «Нова зірка»",
|
||||
"Right Module Barcode": "Штрих-код правого модуля",
|
||||
"Starlight Blue": "Зоряний синій",
|
||||
"Sterling Silver": "Монетний срібний",
|
||||
"Volcanic Red": "Вулканічний червоний",
|
||||
"White": "Білий",
|
||||
"left module": "лівий модуль",
|
||||
"right module": "правий модуль",
|
||||
"Chroma Indigo": "Насичений індиго",
|
||||
"Chroma Pearl": "Насичений перлистий",
|
||||
"Chroma Teal": "Насичений синьо-зелений",
|
||||
"Fortnite": "Обмежена серія Fortnite",
|
||||
"Spider-Man 2": "Обмежена серія Spider-Man 2",
|
||||
"The Last of Us": "Обмежена серія The Last of Us",
|
||||
"10x zoom": "Наближення в 10x",
|
||||
"Normal": "Нормальний маштаб",
|
||||
"Calibration": "Калібрування",
|
||||
"Debug": "Налагодження",
|
||||
"Error triggering rumble": "Помилка під час запуску вібрації",
|
||||
"Info": "Інформація",
|
||||
"Press L2 to test the strong (left) haptic motor": "Натисніть L2, щоб протестувати потужний (лівий) вібромотор",
|
||||
"Press R2 to test the weak (right) haptic motor": "Натисніть R2, щоб протестувати слабкий (правий) вібромотор",
|
||||
"Test the Haptic Motors": "Перевірити вібромотори",
|
||||
"Tests": "Тести",
|
||||
"The motor strength will match how hard you press the trigger": "Потужність вібрації залежатиме від сили натискання на тригер",
|
||||
"Center (L1)": "Центр (L1)",
|
||||
"Circularity (R1)": "Округовість (R1)",
|
||||
"Move the stick to select it for tuning, then without touching the stick use the D-pad buttons to adjust the center point. Flick it and adjust it again if it is off center or flickers.": "Перемістіть стік, щоб вибрати його для налаштування, потім, не торкаючись стіка, використовуйте кнопки D-pad для регулювання центральної точки. Різко відпустіть і налаштуйте знову, якщо стік зміщений від центру або тремтить.",
|
||||
"Please release the stick to center position before adjusting with D-pad buttons.": "Будь ласка, відпустіть стік у центральне положення перед регулюванням за допомогою кнопок D-pad.",
|
||||
"Press the D-pad or face buttons in the direction you want the stick position to move.": "Натисніть D-pad або передні кнопки в напрямку, куди потрібно змістити положення стіка.",
|
||||
"Push the stick straight up/down/left/right as far as possible.": "Відхиліть стік максимально вгору/вниз/вліво/вправо.",
|
||||
"Show raw numbers": "Показати необроблені значення",
|
||||
"While holding the stick to be adjusted straight up/down/left/right, <em>observe the highlighted value below the circle</em>, then use the D-pad buttons to adjust the value to ±0.99 (just below ±1.00).": "Утримуючи стік, який потрібно налаштувати, максимально вгору/вниз/вліво/вправо, <em>стежте за виділеним значенням під колом</em>, потім використовуйте кнопки D-pad, щоб відрегулювати значення до ±0.99 (трохи нижче за ±1.00).",
|
||||
"The device is connected via Bluetooth. Disconnect and reconnect using a USB cable instead.": "",
|
||||
"Your device might not be a genuine Sony controller. If it is not a clone then please report this issue.": "",
|
||||
"": ""
|
||||
}
|
||||
@@ -33,7 +33,7 @@
|
||||
"Please move both sticks to the <b>bottom-right corner</b> and release them.": "请将两个摇杆移动到 <b>右下角</b> 并松开摇杆。",
|
||||
"Calibration completed successfully!": "校准成功完成!",
|
||||
"Next": "下一步",
|
||||
"Recentering the controller sticks. ": "重新定位摇杆中心。 ",
|
||||
"Recentering the controller sticks.": "重新定位摇杆中心。",
|
||||
"Please do not close this window and do not disconnect your controller. ": "请不要关闭此窗口,也不要断开手柄的连接。 ",
|
||||
"Range calibration": "摇杆外圈校准",
|
||||
"<b>The controller is now sampling data!</b>": "<b>手柄现在正在采样数据!</b>",
|
||||
@@ -57,16 +57,16 @@
|
||||
"SW Version": "软件版本",
|
||||
"Device Type": "设备类型",
|
||||
"Range calibration completed": "摇杆外圈校准已完成",
|
||||
"Range calibration failed: ": "摇杆外圈校准失败: ",
|
||||
"Range calibration failed": "摇杆外圈校准失败",
|
||||
"Cannot unlock NVS": "无法解锁 NVS",
|
||||
"Cannot relock NVS": "无法重新锁定 NVS",
|
||||
"Error 1": "错误 1",
|
||||
"Error 2": "错误 2",
|
||||
"Error 3": "错误 3",
|
||||
"Stick calibration failed: ": "摇杆校准失败: ",
|
||||
"Stick calibration failed": "摇杆校准失败",
|
||||
"Stick calibration completed": "摇杆校准完成",
|
||||
"NVS Lock failed: ": "NVS 锁定失败: ",
|
||||
"NVS Unlock failed: ": "NVS 解锁失败: ",
|
||||
"NVS Lock failed": "NVS 锁定失败",
|
||||
"NVS Unlock failed": "NVS 解锁失败",
|
||||
"Please connect only one controller at time.": "一次只能连接一个手柄。",
|
||||
"Sony DualShock 4 V1": "PS4手柄一代(Sony DualShock 4 V1)",
|
||||
"Sony DualShock 4 V2": "PS4手柄二代(Sony DualShock 4 V2)",
|
||||
@@ -135,13 +135,10 @@
|
||||
"This feature is experimental.": "此功能为实验性质。",
|
||||
"Please let me know if the board model of your controller is not detected correctly.": "如果没有正确检测您手柄的主板型号,请告诉我。",
|
||||
"Board model detection thanks to": "主板型号检测功能需要感谢",
|
||||
"Please connect the device using a USB cable.": "请使用USB线连接设备。",
|
||||
"This DualSense controller has outdated firmware.": "该DualSense手柄的固件已过时。",
|
||||
"Please update the firmware and try again.": "请更新固件后重试。",
|
||||
"Joystick Info": "摇杆信息",
|
||||
"Err R:": "右摇杆错误率",
|
||||
"Err L:": "左摇杆错误率",
|
||||
"Check circularity": "检查摇杆外圈圆度。",
|
||||
"Check circularity": "测试摇杆外圈",
|
||||
"Can I reset a permanent calibration to previous calibration?": "我可以回退到之前的校准吗?",
|
||||
"No.": "不可以。",
|
||||
"Can you overwrite a permanent calibration?": "可以覆盖永久校准吗?",
|
||||
@@ -158,7 +155,7 @@
|
||||
"Make sure to touch the edges of the joystick frame and rotate slowly, preferably in each direction - clockwise and anti-clockwise.": "确保摇杆接触摇杆圈,并慢慢旋转,最好顺时针和逆时针方向各旋转一次。",
|
||||
"Only after you have done that, you click on \"Done\".": "完成上述操作后,才能点击“完成”按钮。",
|
||||
"Changes saved successfully": "更改已成功保存。",
|
||||
"Error while saving changes:": "保存更改时出错:",
|
||||
"Error while saving changes": "保存更改时出错:",
|
||||
"Save changes permanently": "永久保存更改",
|
||||
"Reboot controller": "重启手柄",
|
||||
"Controller Info": "手柄信息",
|
||||
@@ -223,18 +220,45 @@
|
||||
"Right Module Barcode": "右侧模块条形码",
|
||||
"left module": "左侧模块",
|
||||
"right module": "右侧模块",
|
||||
"30th Anniversary": "",
|
||||
"Astro Bot": "",
|
||||
"Cobalt Blue": "",
|
||||
"Cosmic Red": "",
|
||||
"Galactic Purple": "",
|
||||
"God of War Ragnarok": "",
|
||||
"Grey Camouflage": "",
|
||||
"Midnight Black": "",
|
||||
"Nova Pink": "",
|
||||
"Starlight Blue": "",
|
||||
"Sterling Silver": "",
|
||||
"Volcanic Red": "",
|
||||
"White": "",
|
||||
"30th Anniversary": "30周年纪念版",
|
||||
"Astro Bot": "宇宙机器人",
|
||||
"Cobalt Blue": "钴晶蓝",
|
||||
"Cosmic Red": "星辰红",
|
||||
"Galactic Purple": "银河紫",
|
||||
"God of War Ragnarok": "战神:诸神黄昏",
|
||||
"Grey Camouflage": "深灰迷彩",
|
||||
"Midnight Black": "午夜黑",
|
||||
"Nova Pink": "新星粉",
|
||||
"Starlight Blue": "星光蓝",
|
||||
"Sterling Silver": "亮灰银",
|
||||
"Volcanic Red": "火山红",
|
||||
"White": "白色",
|
||||
"Chroma Indigo": "净彩靛青",
|
||||
"Chroma Pearl": "净彩珠白",
|
||||
"Chroma Teal": "净彩凫绿",
|
||||
"Fortnite": "堡垒之夜",
|
||||
"Spider-Man 2": "漫威蜘蛛侠2",
|
||||
"The Last of Us": "最后生还者",
|
||||
"10x zoom": "10倍速测试",
|
||||
"Calibration": "校准",
|
||||
"Debug": "调试",
|
||||
"Error triggering rumble": "触发震动时出错",
|
||||
"Info": "信息",
|
||||
"Normal": "正常",
|
||||
"Press L2 to test the strong (left) haptic motor": "按下L2键测试强(左)震动",
|
||||
"Press R2 to test the weak (right) haptic motor": "按下R2键测试弱(右)震动",
|
||||
"Test the Haptic Motors": "测试震动",
|
||||
"Tests": "测试",
|
||||
"The motor strength will match how hard you press the trigger": "震动马达的力度与你扣动扳机的力度相匹配",
|
||||
"Center (L1)": "",
|
||||
"Circularity (R1)": "",
|
||||
"Move the stick to select it for tuning, then without touching the stick use the D-pad buttons to adjust the center point. Flick it and adjust it again if it is off center or flickers.": "",
|
||||
"Please release the stick to center position before adjusting with D-pad buttons.": "",
|
||||
"Press the D-pad or face buttons in the direction you want the stick position to move.": "",
|
||||
"Push the stick straight up/down/left/right as far as possible.": "",
|
||||
"Show raw numbers": "",
|
||||
"The device is connected via Bluetooth. Disconnect and reconnect using a USB cable instead.": "",
|
||||
"While holding the stick to be adjusted straight up/down/left/right, <em>observe the highlighted value below the circle</em>, then use the D-pad buttons to adjust the value to ±0.99 (just below ±1.00).": "",
|
||||
"Your device might not be a genuine Sony controller. If it is not a clone then please report this issue.": "",
|
||||
"": ""
|
||||
}
|
||||
@@ -32,7 +32,7 @@
|
||||
"Please move both sticks to the <b>bottom-right corner</b> and release them.": "請將兩個搖桿移到 <b>右下角</b> 並釋放它們。",
|
||||
"Calibration completed successfully!": "校準成功完成!",
|
||||
"Next": "下一步",
|
||||
"Recentering the controller sticks. ": "重新定位手把摇杆。 ",
|
||||
"Recentering the controller sticks.": "重新定位手把摇杆。",
|
||||
"Please do not close this window and do not disconnect your controller. ": "請不要關閉此窗口,也不要斷開手把的連接。 ",
|
||||
"Range calibration": "摇杆外圈校準",
|
||||
"<b>The controller is now sampling data!</b>": "<b>手把現在正在採樣數據!</b>",
|
||||
@@ -56,16 +56,16 @@
|
||||
"SW Version": "軟體版本",
|
||||
"Device Type": "設備類型",
|
||||
"Range calibration completed": "搖桿外圈校準已完成",
|
||||
"Range calibration failed: ": "搖桿外圈校準失敗: ",
|
||||
"Range calibration failed": "搖桿外圈校準失敗",
|
||||
"Cannot unlock NVS": "無法解鎖 NVS",
|
||||
"Cannot relock NVS": "無法重新鎖定 NVS",
|
||||
"Error 1": "錯誤 1",
|
||||
"Error 2": "錯誤 2",
|
||||
"Error 3": "錯誤 3",
|
||||
"Stick calibration failed: ": "摇杆校準失敗: ",
|
||||
"Stick calibration failed": "摇杆校準失敗",
|
||||
"Stick calibration completed": "摇杆校準完成",
|
||||
"NVS Lock failed: ": "NVS 鎖定失敗: ",
|
||||
"NVS Unlock failed: ": "NVS 解鎖失敗: ",
|
||||
"NVS Lock failed": "NVS 鎖定失敗",
|
||||
"NVS Unlock failed": "NVS 解鎖失敗",
|
||||
"Please connect only one controller at time.": "請一次只連接一個手把。",
|
||||
"Sony DualShock 4 V1": "Sony DualShock 4 V1",
|
||||
"Sony DualShock 4 V2": "Sony DualShock 4 V2",
|
||||
@@ -134,12 +134,9 @@
|
||||
"This feature is experimental.": "此功能為實驗性質。",
|
||||
"Please let me know if the board model of your controller is not detected correctly.": "如果您的手把的主機板型號沒有被正確檢測,請告訴我。",
|
||||
"Board model detection thanks to": "主機板型號檢測功能需要感謝",
|
||||
"Please connect the device using a USB cable.": "請使用USB線連接設備。",
|
||||
"This DualSense controller has outdated firmware.": "該DualSense手把的韌體已過時。",
|
||||
"Please update the firmware and try again.": "請更新韌體後重試。",
|
||||
"Joystick Info": "搖桿資訊",
|
||||
"Err R:": "右搖桿錯誤率",
|
||||
"Err L:": "左搖桿錯誤率",
|
||||
"Check circularity": "檢查搖桿外圈圓度。",
|
||||
"Can I reset a permanent calibration to previous calibration?": "我可以將永久校準重置為之前的校準嗎?",
|
||||
"No.": "不可以。",
|
||||
@@ -157,7 +154,7 @@
|
||||
"Make sure to touch the edges of the joystick frame and rotate slowly, preferably in each direction - clockwise and anti-clockwise.": "確保觸摸搖桿框架的邊緣,並慢慢旋轉,最好是每個方向 - 順時針和逆時針。",
|
||||
"Only after you have done that, you click on \"Done\".": "只有在這樣做之後,你才可以點擊\"完成\"。",
|
||||
"Changes saved successfully": "更改已成功保存",
|
||||
"Error while saving changes:": "保存更改時出錯:",
|
||||
"Error while saving changes": "保存更改時出錯:",
|
||||
"Save changes permanently": "永久保存更改",
|
||||
"Reboot controller": "重啟手把",
|
||||
"(beta)": "測試版本",
|
||||
@@ -223,18 +220,45 @@
|
||||
"Venom FW Version": "Venom固件版本",
|
||||
"left module": "左側模塊",
|
||||
"right module": "右側模塊",
|
||||
"30th Anniversary": "",
|
||||
"Astro Bot": "",
|
||||
"Cobalt Blue": "",
|
||||
"Cosmic Red": "",
|
||||
"Galactic Purple": "",
|
||||
"God of War Ragnarok": "",
|
||||
"Grey Camouflage": "",
|
||||
"Midnight Black": "",
|
||||
"Nova Pink": "",
|
||||
"Starlight Blue": "",
|
||||
"Sterling Silver": "",
|
||||
"Volcanic Red": "",
|
||||
"White": "",
|
||||
"30th Anniversary": "30週年紀念版",
|
||||
"Astro Bot": "宇宙機器人",
|
||||
"Cobalt Blue": "鈷藍色",
|
||||
"Cosmic Red": "星塵紅",
|
||||
"Galactic Purple": "銀河紫",
|
||||
"God of War Ragnarok": "戰神:諸神黃昏",
|
||||
"Grey Camouflage": "深灰迷彩",
|
||||
"Midnight Black": "午夜黑",
|
||||
"Nova Pink": "星幻粉",
|
||||
"Starlight Blue": "星光藍",
|
||||
"Sterling Silver": "亮灰銀",
|
||||
"Volcanic Red": "火山紅",
|
||||
"White": "白色",
|
||||
"Chroma Indigo": "閃耀靛紫",
|
||||
"Chroma Pearl": "閃耀珍珠白",
|
||||
"Chroma Teal": "閃耀青",
|
||||
"Fortnite": "要塞英雄",
|
||||
"Spider-Man 2": "蜘蛛人2",
|
||||
"The Last of Us": "最後生還者",
|
||||
"10x zoom": "10倍速測試",
|
||||
"Calibration": "校準",
|
||||
"Debug": "調試",
|
||||
"Error triggering rumble": "觸發震動時出錯",
|
||||
"Info": "信息",
|
||||
"Normal": "正常",
|
||||
"Press L2 to test the strong (left) haptic motor": "按下L2鍵測試強(左)震動",
|
||||
"Press R2 to test the weak (right) haptic motor": "按下R2鍵測試弱(右)震動",
|
||||
"Test the Haptic Motors": "測試震動",
|
||||
"Tests": "測試",
|
||||
"The motor strength will match how hard you press the trigger": "震動馬達的力度與妳扣動扳機的力度相匹配",
|
||||
"Center (L1)": "",
|
||||
"Circularity (R1)": "",
|
||||
"Move the stick to select it for tuning, then without touching the stick use the D-pad buttons to adjust the center point. Flick it and adjust it again if it is off center or flickers.": "",
|
||||
"Please release the stick to center position before adjusting with D-pad buttons.": "",
|
||||
"Press the D-pad or face buttons in the direction you want the stick position to move.": "",
|
||||
"Push the stick straight up/down/left/right as far as possible.": "",
|
||||
"Show raw numbers": "",
|
||||
"The device is connected via Bluetooth. Disconnect and reconnect using a USB cable instead.": "",
|
||||
"While holding the stick to be adjusted straight up/down/left/right, <em>observe the highlighted value below the circle</em>, then use the D-pad buttons to adjust the value to ±0.99 (just below ±1.00).": "",
|
||||
"Your device might not be a genuine Sony controller. If it is not a clone then please report this issue.": "",
|
||||
"": ""
|
||||
}
|
||||
5653
package-lock.json
generated
Normal file
5653
package-lock.json
generated
Normal file
File diff suppressed because it is too large
Load Diff
56
package.json
Normal file
56
package.json
Normal file
@@ -0,0 +1,56 @@
|
||||
{
|
||||
"name": "dualshock-calibration-gui",
|
||||
"version": "1.0.0",
|
||||
"description": "A web-based calibration tool for PlayStation DualShock 4, DualSense, and DualSense Edge controllers",
|
||||
"main": "index.html",
|
||||
"type": "module",
|
||||
"scripts": {
|
||||
"build": "gulp build",
|
||||
"build:prod": "gulp build --production",
|
||||
"clean": "gulp clean",
|
||||
"dev": "gulp dev",
|
||||
"watch": "gulp watch",
|
||||
"serve": "node dev-server.js",
|
||||
"serve:https": "HTTPS=true node dev-server.js",
|
||||
"start": "npm run build && npm run serve",
|
||||
"dev:serve": "npm run build && concurrently \"npm run dev\" \"npm run serve\"",
|
||||
"dev:full": "npm run build && concurrently --kill-others \"npm run watch\" \"npm run serve\""
|
||||
},
|
||||
"devDependencies": {
|
||||
"rollup": "^4.9.0",
|
||||
"@rollup/plugin-node-resolve": "^15.2.3",
|
||||
"@rollup/plugin-terser": "^0.4.4",
|
||||
"gulp": "^5.0.1",
|
||||
"gulp-cli": "^3.1.0",
|
||||
"gulp-terser": "^2.1.0",
|
||||
"gulp-clean-css": "^4.3.0",
|
||||
"gulp-htmlmin": "^5.0.1",
|
||||
"gulp-rev": "^11.0.0",
|
||||
"gulp-rev-replace": "^0.4.4",
|
||||
"gulp-concat": "^2.6.1",
|
||||
"gulp-sourcemaps": "^3.0.0",
|
||||
"gulp-if": "^3.0.0",
|
||||
"gulp-rename": "^2.1.0",
|
||||
"rollup-stream": "^1.24.1",
|
||||
"vinyl-source-stream": "^2.0.0",
|
||||
"vinyl-buffer": "^1.0.1",
|
||||
"del": "^8.0.0",
|
||||
"yargs": "^18.0.0",
|
||||
"gulp-svgmin": "^4.1.0",
|
||||
"gulp-replace": "^1.1.4",
|
||||
"gulp-json-minify": "^1.2.3",
|
||||
"glob": "^10.3.10",
|
||||
"html-minifier-terser": "^7.2.0",
|
||||
"concurrently": "^8.2.2",
|
||||
"http-server": "^14.1.1"
|
||||
},
|
||||
"keywords": [
|
||||
"dualshock",
|
||||
"dualsense",
|
||||
"controller",
|
||||
"calibration",
|
||||
"webHID"
|
||||
],
|
||||
"author": "",
|
||||
"license": "MIT"
|
||||
}
|
||||
73
scripts/process_lang.py
Executable file
73
scripts/process_lang.py
Executable file
@@ -0,0 +1,73 @@
|
||||
#!/usr/bin/env python3
|
||||
|
||||
# (C) 2025 dualshock-tools
|
||||
#
|
||||
# This script can be used to add or remove a sentence from all the language
|
||||
# files. It's really simple and hacking: just edit this files adding lines
|
||||
# In the corresponsing fields (add, remove) and run it.
|
||||
#
|
||||
# Quick note: run it from the "root" directory of the project: it searches for
|
||||
# ./lang/ so the correct command should be `python3 scripts/process_lang.py`.
|
||||
|
||||
data = {
|
||||
"remove": [
|
||||
# Add here lines to remove from each language file
|
||||
],
|
||||
"add": [
|
||||
# Add here lines to add to each language file
|
||||
],
|
||||
}
|
||||
|
||||
## ---
|
||||
|
||||
import os, json
|
||||
|
||||
def process_file(filename):
|
||||
x = json.loads(open(filename, "r").read())
|
||||
|
||||
modified = False
|
||||
for i in data["remove"]:
|
||||
if i in x:
|
||||
del x[i]
|
||||
modified = True
|
||||
else:
|
||||
print("[REMOVE] %s: Cannot find '%s'" % (filename, i))
|
||||
for i in data["add"]:
|
||||
if i in x:
|
||||
print("[ADD] %s: '%s' already present" % (filename, i))
|
||||
else:
|
||||
x[i] = ""
|
||||
modified = True
|
||||
|
||||
del x[""]
|
||||
empties = []
|
||||
for i in x:
|
||||
if len(x[i].strip()) == 0:
|
||||
empties += [i]
|
||||
|
||||
empties = sorted(empties)
|
||||
|
||||
for i in empties:
|
||||
del x[i]
|
||||
|
||||
for i in empties:
|
||||
x[i] = ""
|
||||
|
||||
x[""] = ""
|
||||
|
||||
return (modified, json.dumps(x, indent=4, ensure_ascii=False))
|
||||
|
||||
|
||||
files = list(os.listdir("lang"))
|
||||
|
||||
for i in files:
|
||||
modified, new_file = process_file("lang/" + i)
|
||||
if not modified:
|
||||
print("%s: not modified" % (i, ))
|
||||
continue
|
||||
if len(new_file) < 100:
|
||||
print("%s: invalid content" % (i, ))
|
||||
continue
|
||||
print("%s: writing changes" % (i, ))
|
||||
|
||||
open("lang/" + i, "w").write(new_file)
|
||||
72
setup-dev.sh
Executable file
72
setup-dev.sh
Executable file
@@ -0,0 +1,72 @@
|
||||
#!/bin/bash
|
||||
|
||||
# DualShock Calibration GUI - Development Setup Script
|
||||
|
||||
echo "🎮 DualShock Calibration GUI - Development Setup"
|
||||
echo "================================================"
|
||||
echo ""
|
||||
|
||||
# Check if Node.js is installed
|
||||
if ! command -v node &> /dev/null; then
|
||||
echo "❌ Node.js is not installed"
|
||||
echo "💡 Please install Node.js (v16 or higher) from https://nodejs.org/"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# Check Node.js version
|
||||
NODE_VERSION=$(node -v | cut -d'v' -f2)
|
||||
MAJOR_VERSION=$(echo $NODE_VERSION | cut -d'.' -f1)
|
||||
|
||||
if [ "$MAJOR_VERSION" -lt 16 ]; then
|
||||
echo "❌ Node.js version $NODE_VERSION is too old"
|
||||
echo "💡 Please upgrade to Node.js v16 or higher"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
echo "✅ Node.js version: $NODE_VERSION"
|
||||
|
||||
# Check if npm is installed
|
||||
if ! command -v npm &> /dev/null; then
|
||||
echo "❌ npm is not installed"
|
||||
echo "💡 npm should come with Node.js installation"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
echo "✅ npm version: $(npm -v)"
|
||||
echo ""
|
||||
|
||||
# Install dependencies
|
||||
echo "📦 Installing dependencies..."
|
||||
if npm install; then
|
||||
echo "✅ Dependencies installed successfully"
|
||||
else
|
||||
echo "❌ Failed to install dependencies"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
echo ""
|
||||
|
||||
# Build the application
|
||||
echo "🔨 Building application..."
|
||||
if npm run build; then
|
||||
echo "✅ Application built successfully"
|
||||
else
|
||||
echo "❌ Failed to build application"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
echo ""
|
||||
echo "🎉 Setup complete!"
|
||||
echo ""
|
||||
echo "🚀 To start development:"
|
||||
echo " npm run dev:full"
|
||||
echo ""
|
||||
echo "📱 The app will be available at:"
|
||||
echo " https://localhost:8443"
|
||||
echo ""
|
||||
echo "💡 You may need to accept the SSL certificate warning in your browser"
|
||||
echo "💡 Use Chrome or Edge for full WebHID support"
|
||||
echo ""
|
||||
echo "📚 For more information, see:"
|
||||
echo " - README.md"
|
||||
echo " - DEVELOPMENT.md"
|
||||
65
templates/calib-center-modal.html
Normal file
65
templates/calib-center-modal.html
Normal file
@@ -0,0 +1,65 @@
|
||||
<!-- New calibrate modal -->
|
||||
<div class="modal fade" id="calibCenterModal" data-bs-backdrop="static" data-bs-keyboard="false" tabindex="-1" aria-labelledby="calibTitle" aria-hidden="true">
|
||||
<div class="modal-dialog modal-lg">
|
||||
<div class="modal-content">
|
||||
<div class="modal-header">
|
||||
<h1 class="modal-title fs-5 ds-i18n" id="calibTitle">Stick center calibration</h1>
|
||||
<button type="button" id="calibCross" class="btn-close" data-bs-dismiss="modal" aria-label="Close"></button>
|
||||
</div>
|
||||
<div class="modal-body">
|
||||
|
||||
<div class="row">
|
||||
<div class="col-4">
|
||||
<div class="list-group" id="list-tab">
|
||||
<a class="ds-i18n list-group-item list-group-item-action active" id="list-1-calib">Welcome</a>
|
||||
<a class="ds-i18n list-group-item list-group-item-action" id="list-2-calib">Step 1</a>
|
||||
<a class="ds-i18n list-group-item list-group-item-action" id="list-3-calib">Step 2</a>
|
||||
<a class="ds-i18n list-group-item list-group-item-action" id="list-4-calib">Step 3</a>
|
||||
<a class="ds-i18n list-group-item list-group-item-action" id="list-5-calib">Step 4</a>
|
||||
<a class="ds-i18n list-group-item list-group-item-action" id="list-6-calib">Completed</a>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-8">
|
||||
<div class="container" id="list-1">
|
||||
<h4 class="ds-i18n">Welcome to the stick center-calibration wizard!</h4>
|
||||
|
||||
<p class="ds-i18n">This tool will guide you in re-centering the analog sticks of your controller. It consists in four steps: you will be asked to move both sticks in a direction and release them.</p>
|
||||
|
||||
<p class="ds-i18n">Please be aware that, <i>once the calibration is running, it cannot be canceled</i>. Do not close this page or disconnect your controller until is completed.</p>
|
||||
|
||||
<p class="ds-i18n">Press <b>Start</b> to begin calibration.</p>
|
||||
</div>
|
||||
<div class="container" style="display: none;" id="list-2">
|
||||
<p class="ds-i18n">Please move both sticks to the <b>top-left corner</b> and release them.</p>
|
||||
<p class="ds-i18n">When the sticks are back in the center, press <b>Continue</b>.</p>
|
||||
</div>
|
||||
<div class="container" style="display: none;" id="list-3">
|
||||
<p class="ds-i18n">Please move both sticks to the <b>top-right corner</b> and release them.</p>
|
||||
<p class="ds-i18n">When the sticks are back in the center, press <b>Continue</b>.</p>
|
||||
</div>
|
||||
<div class="container" style="display: none;" id="list-4">
|
||||
<p class="ds-i18n">Please move both sticks to the <b>bottom-left corner</b> and release them.</p>
|
||||
<p class="ds-i18n">When the sticks are back in the center, press <b>Continue</b>.</p>
|
||||
</div>
|
||||
<div class="container" style="display: none;" id="list-5">
|
||||
<p class="ds-i18n">Please move both sticks to the <b>bottom-right corner</b> and release them.</p>
|
||||
<p class="ds-i18n">When the sticks are back in the center, press <b>Continue</b>.</p>
|
||||
</div>
|
||||
<div class="container" style="display: none;" id="list-6">
|
||||
<p class="ds-i18n">Calibration completed successfully!</p>
|
||||
<p><span class="ds-i18n">You can check the calibration with the</span> <a href="https://hardwaretester.com/gamepad" target="_blank">gamepad tester</a>.</p>
|
||||
<p class="ds-i18n">Have a nice day :)</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
<div class="modal-footer">
|
||||
<button type="button" class="btn btn-primary" id="calibNext" onclick="calib_next()">
|
||||
<span class="spinner-border spinner-border-sm" role="status" aria-hidden="true" id="btnSpinner" style="display: none;"></span>
|
||||
<span id="calibNextText" class="ds-i18n">Next</span>
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
19
templates/calibrate-modal.html
Normal file
19
templates/calibrate-modal.html
Normal file
@@ -0,0 +1,19 @@
|
||||
<!-- Modal -->
|
||||
<div class="modal fade" id="calibrateModal" data-bs-backdrop="static" data-bs-keyboard="false" tabindex="-1" aria-labelledby="staticBackdropLabel" aria-hidden="true">
|
||||
<div class="modal-dialog">
|
||||
<div class="modal-content">
|
||||
<div class="modal-header">
|
||||
<h1 class="modal-title fs-5" id="staticBackdropLabel">Calibrating center</h1>
|
||||
</div>
|
||||
<div class="modal-body">
|
||||
<p class="ds-i18n">Recentering the controller sticks.</p>
|
||||
<p class="ds-i18n">Please do not close this window and do not disconnect your controller. </p>
|
||||
<div class="progress" role="progressbar" aria-label="Centering" aria-valuenow="0" aria-valuemin="0" aria-valuemax="100">
|
||||
<div class="progress-bar" style="width: 0%"></div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="modal-footer">
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
34
templates/donate-modal.html
Normal file
34
templates/donate-modal.html
Normal file
@@ -0,0 +1,34 @@
|
||||
<div class="modal fade" id="donateModal" tabindex="-1" aria-labelledby="modal-title" aria-hidden="true">
|
||||
<div class="modal-dialog modal-dialog-centered">
|
||||
<div class="modal-content">
|
||||
<div class="modal-header">
|
||||
<h5 class="modal-title"></h5>
|
||||
<button type="button" class="btn-close" data-bs-dismiss="modal" aria-label="Close"></button>
|
||||
</div>
|
||||
|
||||
<div class="modal-body p-4" id="donateBody">
|
||||
<p class="ds-i18n">Hi, thank you for using this software.</p>
|
||||
<p><span class="ds-i18n">If you're finding it helpful and you want to support my efforts, feel free to</span> <a href="https://paypal.me/alaincarlucci" target="_blank" class="text-body-secondary ds-i18n">buy me a coffee</a><span class="ds-i18n">! :)</span></p>
|
||||
<p class="ds-i18n">Do you have any suggestion or issue? Drop me a message via email or discord.</p>
|
||||
<p class="ds-i18n">Cheers!</p>
|
||||
|
||||
<div class="collapse" id="ethereumCollapse">
|
||||
<div class="card card-body">
|
||||
<h5 class="card-title">Ethereum Address</h5>
|
||||
<center><img src="donate.png" width="128px" /></center>
|
||||
<input type="text" class="form-control" value="0x27dDA2f15A6A477fcdFB3709Ed0760aEF0246D5D" readonly />
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="modal-footer">
|
||||
<button data-bs-toggle="collapse" data-bs-target="#ethereumCollapse" aria-expanded="false" aria-controls="ethereumCollapse" type="button" class="btn btn-success">
|
||||
<svg class="bi" width="18" height="18"><use xlink:href="#ethereum"/></svg> Ethereum
|
||||
</button>
|
||||
|
||||
<button onclick="window.open('https://paypal.me/alaincarlucci')" type="button" class="btn btn-primary" data-bs-dismiss="modal">
|
||||
<svg class="bi" width="18" height="18"><use xlink:href="#paypal"/></svg> PayPal
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
35
templates/edge-modal.html
Normal file
35
templates/edge-modal.html
Normal file
@@ -0,0 +1,35 @@
|
||||
<div class="modal fade" id="edgeModal" tabindex="-1" aria-labelledby="modal-title" aria-hidden="true">
|
||||
<div class="modal-dialog modal-xl modal-dialog-centered">
|
||||
<div class="modal-content">
|
||||
<div class="modal-header">
|
||||
<h5 class="modal-title ds-i18n">DualSense Edge Calibration</h5>
|
||||
<button type="button" class="btn-close" data-bs-dismiss="modal" aria-label="Close"></button>
|
||||
</div>
|
||||
|
||||
<div class="modal-body p-4" id="donateBody">
|
||||
<p class="ds-i18n">Support for calibrating DualSense Edge stick modules is now available as an <b>experimental feature</b>.</p>
|
||||
<p class="ds-i18n">Please note: the stick modules on the DS Edge <b>cannot be calibrated via software alone</b>.</p>
|
||||
<p class="ds-i18n">To store a custom calibration on the stick's internal memory, a <b>hardware modification</b> is required.</p>
|
||||
<p class="ds-i18n">This involves temporarily disabling write protection by applying <b>+1.8V</b> to a specific test point on each module.</p>
|
||||
<p></p>
|
||||
|
||||
<p><span class="ds-i18n">You can do this in two ways:</span>
|
||||
<ul>
|
||||
<li class="ds-i18n"><b>Internally</b>: by soldering a wire from a +1.8V source to the write-protect TP.</li>
|
||||
<li class="ds-i18n"><b>Externally</b>: by applying +1.8V directly to the visible test point without opening the controller.</li>
|
||||
</ul>
|
||||
</p>
|
||||
|
||||
<p><b><span class="ds-i18n">This is only for advanced users. If you're not sure what you're doing, please do not attempt it.</span></b></p>
|
||||
<p><span class="ds-i18n">More details and images</span> <a href="https://github.com/lewy20041/Dualsense_Edge_Modules_Callibration">here</a>.</p>
|
||||
|
||||
<p class="ds-i18n">We are not responsible for any damage caused by attempting this modification.</p>
|
||||
<p class="ds-i18n">For more info or help, feel free to reach out on Discord.</p>
|
||||
|
||||
</div>
|
||||
<div class="modal-footer">
|
||||
<button type="button" class="btn btn-primary ds-i18n" data-bs-dismiss="modal">Understood</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
20
templates/edge-progress-modal.html
Normal file
20
templates/edge-progress-modal.html
Normal file
@@ -0,0 +1,20 @@
|
||||
<!-- Edge in progress Modal -->
|
||||
<div class="modal fade" id="edgeProgressModal" data-bs-backdrop="static" data-bs-keyboard="false" tabindex="-1" aria-labelledby="edgeProgressLabel" aria-hidden="true">
|
||||
<div class="modal-dialog modal-dialog-centered">
|
||||
<div class="modal-content">
|
||||
<div class="modal-header">
|
||||
<h1 class="modal-title fs-5 ds-i18n" id="edgeProgressLabel">Storing calibration...</h1>
|
||||
</div>
|
||||
<div class="modal-body">
|
||||
<p class="ds-i18n">Calibration is being stored in the stick modules.</p>
|
||||
<p class="ds-i18n">Please do not close this window and do not disconnect your controller. </p>
|
||||
|
||||
<div class="progress" role="progressbar" aria-valuenow="0" aria-valuemin="0" aria-valuemax="100">
|
||||
<div id="dsedge-progress" class="progress-bar progress-bar-striped progress-bar-animated" style="width: 0%"></div>
|
||||
</div>
|
||||
|
||||
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
168
templates/faq-modal.html
Normal file
168
templates/faq-modal.html
Normal file
@@ -0,0 +1,168 @@
|
||||
<!-- FAQ -->
|
||||
<div class="modal fade" id="faqModal" tabindex="-1" role="dialog" aria-labelledby="faqModalTitle" aria-hidden="true">
|
||||
<div class="modal-dialog modal-lg modal-fullscreen-md-down" role="document">
|
||||
<div class="modal-content">
|
||||
<div class="modal-header">
|
||||
<h5 class="modal-title ds-i18n" id="faqModalTitle">Frequently Asked Questions</h5>
|
||||
<button type="button" class="btn-close" data-bs-dismiss="modal" aria-label="Close"></button>
|
||||
</div>
|
||||
<div class="modal-body">
|
||||
<div class="p-3 ds-i18n">Welcome to the F.A.Q. section! Below, you'll find answers to some of the most commonly asked questions about this website. If you have any other inquiries or need further assistance, feel free to reach out to me directly. Your feedback and questions are always welcome!</div>
|
||||
<div class="accordion accordion-flush" id="accordionFlushExample">
|
||||
<div class="accordion-item">
|
||||
<h2 class="accordion-header">
|
||||
<button class="ds-i18n accordion-button collapsed" type="button" data-bs-toggle="collapse" data-bs-target="#flush-collapse3" aria-expanded="false" aria-controls="flush-collapse3">How does it work?</button>
|
||||
</h2>
|
||||
<div id="flush-collapse3" class="accordion-collapse collapse" data-bs-parent="#accordionFlushExample">
|
||||
<div class="accordion-body">
|
||||
<p class="ds-i18n">Behind the scenes, this website is the culmination of one year of dedicated effort in reverse-engineering DualShock controllers for fun/hobby from a random guy on the internet.</p>
|
||||
|
||||
<p><span class="ds-i18n">Through</span> <a class="ds-i18n" href='https://blog.the.al' target='_blank'>this research</a><span class="ds-i18n">, it was discovered that there exist some undocumented commands on DualShock controllers that can be sent via USB and are used during factory assembly process. If these commands are sent, the controller starts the recalibration of analog sticks.</span></p>
|
||||
<p class="ds-i18n">While the primary focus of this research wasn't initially centered on recalibration, it became apparent that a service offering this capability could greatly benefit numerous individuals. And thus, here we are.</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="accordion-item">
|
||||
<h2 class="accordion-header">
|
||||
<button class="ds-i18n accordion-button collapsed" type="button" data-bs-toggle="collapse" data-bs-target="#flush-collapseOne" aria-expanded="false" aria-controls="flush-collapseOne">Does the calibration remain effective during gameplay on PS4/PS5?</button>
|
||||
</h2>
|
||||
<div id="flush-collapseOne" class="accordion-collapse collapse" data-bs-parent="#accordionFlushExample">
|
||||
<div class="ds-i18n accordion-body">Yes, if you tick the checkbox "Write changes permanently in the controller". In that case, the calibration is flashed directly in the controller firmware. This ensures that it remains in place regardless of the console it's connected to.</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="accordion-item">
|
||||
<h2 class="accordion-header">
|
||||
<button class="ds-i18n accordion-button collapsed" type="button" data-bs-toggle="collapse" data-bs-target="#flush-collapseTwo" aria-expanded="false" aria-controls="flush-collapseTwo">Is this an officially endorsed service?</button>
|
||||
</h2>
|
||||
<div id="flush-collapseTwo" class="accordion-collapse collapse" data-bs-parent="#accordionFlushExample">
|
||||
<div class="ds-i18n accordion-body">No, this service is simply a creation by a DualShock enthusiast.</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="accordion-item">
|
||||
<h2 class="accordion-header">
|
||||
<button class="ds-i18n accordion-button collapsed" type="button" data-bs-toggle="collapse" data-bs-target="#flush-collapse4" aria-expanded="false" aria-controls="flush-collapse4">Does this website detects if a controller is a clone?</button>
|
||||
</h2>
|
||||
<div id="flush-collapse4" class="accordion-collapse collapse" data-bs-parent="#accordionFlushExample">
|
||||
<div class="accordion-body">
|
||||
<p class="ds-i18n">Yes, only DualShock4 at the moment. This happened because I accidentally purchased some clones, spent time identifying the differences and added this functionality to prevent future deception.</p>
|
||||
|
||||
<p class="ds-i18n">Unfortunately, the clones cannot be calibrated anyway, because they only clone the behavior of a DualShock4 during a normal gameplay, not all the undocumented functionalities.</p>
|
||||
|
||||
<p class="ds-i18n">If you want to extend this detection functionality to DualSense, please ship me a fake DualSense and you'll see it in few weeks.</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="accordion-item">
|
||||
<h2 class="accordion-header">
|
||||
<button class="ds-i18n accordion-button collapsed" type="button" data-bs-toggle="collapse" data-bs-target="#flush-collapse5" aria-expanded="false" aria-controls="flush-collapse5">What development is in plan?</button>
|
||||
</h2>
|
||||
<div id="flush-collapse5" class="accordion-collapse collapse" data-bs-parent="#accordionFlushExample">
|
||||
<div class="accordion-body">
|
||||
<p class="ds-i18n">I maintain two separate to-do lists for this project, although the priority has yet to be established.</p>
|
||||
|
||||
<p class="ds-i18n">The first list is about enhancing support for DualShock4 and DualSense controllers:</p>
|
||||
<ul>
|
||||
<li class="ds-i18n">Implement calibration of L2/R2 triggers.</li>
|
||||
<li class="ds-i18n">Improve detection of clones, particularly beneficial for those seeking to purchase used controllers with assurance of authenticity.</li>
|
||||
<li class="ds-i18n">Enhance user interface (e.g. provide additional controller information)</li>
|
||||
<li class="ds-i18n">Add support for recalibrating IMUs.</li>
|
||||
<li class="ds-i18n">Additionally, explore the possibility of reviving non-functioning DualShock controllers (further discussion available on Discord for interested parties).</li>
|
||||
</ul>
|
||||
|
||||
<p class="ds-i18n">The second list contains new controllers I aim to support:</p>
|
||||
<ul>
|
||||
<li class="ds-i18n">DualSense Edge</li>
|
||||
<li class="ds-i18n">DualShock 3</li>
|
||||
<li class="ds-i18n">XBox Controllers</li>
|
||||
</ul>
|
||||
|
||||
<p class="ds-i18n">Each of these tasks presents both immense interest and significant time investment. To provide context, supporting a new controller typically demands 6-12 months of full-time research, alongside a stroke of good fortune.</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="accordion-item">
|
||||
<h2 class="accordion-header">
|
||||
<button class="ds-i18n accordion-button collapsed" type="button" data-bs-toggle="collapse" data-bs-target="#flush-collapse7" aria-expanded="false" aria-controls="flush-collapse7">Can I reset a permanent calibration to previous calibration?</button>
|
||||
</h2>
|
||||
<div id="flush-collapse7" class="accordion-collapse collapse" data-bs-parent="#accordionFlushExample">
|
||||
<div class="accordion-body">
|
||||
<p class="ds-i18n">No.</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="accordion-item">
|
||||
<h2 class="accordion-header">
|
||||
<button class="ds-i18n accordion-button collapsed" type="button" data-bs-toggle="collapse" data-bs-target="#flush-collapse8" aria-expanded="false" aria-controls="flush-collapse8">Can you overwrite a permanent calibration?</button>
|
||||
</h2>
|
||||
<div id="flush-collapse8" class="accordion-collapse collapse" data-bs-parent="#accordionFlushExample">
|
||||
<div class="accordion-body">
|
||||
<p class="ds-i18n">Yes. Simply do another permanent calibration.</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="accordion-item">
|
||||
<h2 class="accordion-header">
|
||||
<button class="ds-i18n accordion-button collapsed" type="button" data-bs-toggle="collapse" data-bs-target="#flush-collapse9" aria-expanded="false" aria-controls="flush-collapse9">Does this software resolve stickdrift?</button>
|
||||
</h2>
|
||||
<div id="flush-collapse9" class="accordion-collapse collapse" data-bs-parent="#accordionFlushExample">
|
||||
<div class="accordion-body">
|
||||
<p class="ds-i18n">Stickdrift is caused by a physical defect; namely dirt, worn potentiometer or in some cases a worn spring.</p>
|
||||
<p class="ds-i18n">This software will not fix stick drift on its own if you already experience that. What it will help with, is ensuring the new joystick(s) will function properly after replacing the old one(s) to work well with.</p>
|
||||
<p class="ds-i18n">I have noticed some controllers out of the box have worse factory calibration than if I would recalibrate them. Especially true for circularity of SCUF controllers with a unique shell.</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="accordion-item">
|
||||
<h2 class="accordion-header">
|
||||
<button class="ds-i18n accordion-button collapsed" type="button" data-bs-toggle="collapse" data-bs-target="#flush-collapse10" aria-expanded="false" aria-controls="flush-collapse10">(Dualsense) Will updating the firmware reset calibration?</button>
|
||||
</h2>
|
||||
<div id="flush-collapse10" class="accordion-collapse collapse" data-bs-parent="#accordionFlushExample">
|
||||
<div class="accordion-body">
|
||||
<p class="ds-i18n">No.</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="accordion-item">
|
||||
<h2 class="accordion-header">
|
||||
<button class="ds-i18n accordion-button collapsed" type="button" data-bs-toggle="collapse" data-bs-target="#flush-collapse11" aria-expanded="false" aria-controls="flush-collapse11">After range calibration, joysticks always go in corners.</button>
|
||||
</h2>
|
||||
<div id="flush-collapse11" class="accordion-collapse collapse" data-bs-parent="#accordionFlushExample">
|
||||
<div class="accordion-body">
|
||||
<p class="ds-i18n">This issue happens because you have clicked "Done" immediately after starting a range calibration.</p>
|
||||
<b><p class="ds-i18n">Please read the instructions.</p></b>
|
||||
<p class="ds-i18n">You have to rotate the joysticks before you press "Done".</p>
|
||||
<p class="ds-i18n">Make sure to touch the edges of the joystick frame and rotate slowly, preferably in each direction - clockwise and anti-clockwise.</p>
|
||||
<p class="ds-i18n">Only after you have done that, you click on "Done".</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="accordion-item">
|
||||
<h2 class="accordion-header">
|
||||
<button class="ds-i18n accordion-button collapsed" type="button" data-bs-toggle="collapse" data-bs-target="#flush-collapse6" aria-expanded="false" aria-controls="flush-collapse6">I love this service, it helped me! How can I contribute?</button>
|
||||
</h2>
|
||||
<div id="flush-collapse6" class="accordion-collapse collapse" data-bs-parent="#accordionFlushExample">
|
||||
<div class="accordion-body">
|
||||
<p class="ds-i18n">I'm glad to hear that you found this helpful! If you're interested in contributing, here are a few ways you can help me:</p>
|
||||
<ul>
|
||||
<li><span class="ds-i18n">Consider making a</span> <a href="https://paypal.me/alaincarlucci" target="_blank" class="ds-i18n">donation</a> <span class="ds-i18n">to support my late-night caffeine-fueled reverse-engineering efforts.</span></li>
|
||||
<li class="ds-i18n">Ship me a controller you would love to add (send me an email for organization).</li>
|
||||
<li><a href="https://github.com/dualshock-tools/dualshock-tools.github.io/blob/main/TRANSLATIONS.md" class="ds-i18n" target="_blank">Translate this website in your language</a><span class="ds-i18n">, to help more people like you!</span></li>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
<div class="modal-footer">
|
||||
<button type="button" class="btn btn-primary ds-i18n" data-bs-dismiss="modal">Close</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
197
templates/finetune-modal.html
Normal file
197
templates/finetune-modal.html
Normal file
@@ -0,0 +1,197 @@
|
||||
<div class="modal fade" id="finetuneModal" data-bs-backdrop="static" data-bs-keyboard="false" tabindex="-1" aria-labelledby="finetuneModalLabel" aria-hidden="true">
|
||||
<div class="modal-dialog modal-dialog-centered modal-lg modal-fullscreen-lg-down">
|
||||
<div class="modal-content">
|
||||
<div class="modal-header">
|
||||
<h1 class="modal-title fs-5 ds-i18n" id="finetuneModalLabel">Finetune stick calibration</h1>
|
||||
<button type="button" class="btn-close" aria-label="Close" onclick="finetune_cancel()"></button>
|
||||
</div>
|
||||
<div class="modal-body">
|
||||
<p class="ds-i18n">This screen allows to finetune raw calibration data on your controller</p>
|
||||
|
||||
<div class="modal-header border-top-0 pt-0">
|
||||
<div class="btn-group w-100" role="group" aria-label="Finetune mode selection">
|
||||
<input type="radio" class="btn-check" name="finetuneMode" id="finetuneModeCenter" autocomplete="off" checked>
|
||||
<label class="btn btn-outline-primary ds-i18n" for="finetuneModeCenter">Center (L1)</label>
|
||||
|
||||
<input type="radio" class="btn-check" name="finetuneMode" id="finetuneModeCircularity" autocomplete="off">
|
||||
<label class="btn btn-outline-primary ds-i18n" for="finetuneModeCircularity">Circularity (R1)</label>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="alert alert-info finetune-center-mode" role="alert">
|
||||
<i class="fas fa-info-circle"></i>
|
||||
<span class="ds-i18n">
|
||||
Move the stick to select it for tuning, then without touching the stick use the D-pad buttons to adjust the center point. Flick it and adjust it again if it is off center or flickers.
|
||||
</span>
|
||||
</div>
|
||||
<div class="alert alert-warning finetune-center-mode" role="alert" id="finetuneCenterWarning">
|
||||
<i class="fas fa-exclamation-triangle"></i>
|
||||
<span class="ds-i18n">
|
||||
Please release the stick to center position before adjusting with D-pad buttons.
|
||||
</span>
|
||||
</div>
|
||||
<div class="alert alert-success finetune-center-mode" role="alert" id="finetuneCenterSuccess">
|
||||
<i class="fas fa-check-circle"></i>
|
||||
<span class="ds-i18n">
|
||||
Press the D-pad or face buttons in the direction you want the stick position to move.
|
||||
</span>
|
||||
</div>
|
||||
<div class="alert alert-info finetune-circularity-mode" role="alert">
|
||||
<i class="fas fa-info-circle"></i>
|
||||
<span class="ds-i18n">
|
||||
While holding the stick to be adjusted straight up/down/left/right, <em>observe the highlighted value below the circle</em>,
|
||||
then use the D-pad buttons to adjust the value to ±0.99 (just below ±1.00).
|
||||
</span>
|
||||
</div>
|
||||
<div class="alert alert-warning finetune-circularity-mode" role="alert" id="finetuneCircularityWarning">
|
||||
<i class="fas fa-exclamation-triangle"></i>
|
||||
<span class="ds-i18n">
|
||||
Push the stick straight up/down/left/right as far as possible.
|
||||
</span>
|
||||
</div>
|
||||
<div class="alert alert-success finetune-circularity-mode" role="alert" id="finetuneCircularitySuccess">
|
||||
<i class="fas fa-check-circle"></i>
|
||||
<span class="ds-i18n">
|
||||
Press the D-pad or face buttons in the direction you want the stick position to move.
|
||||
</span>
|
||||
</div>
|
||||
<div style="width: 100%; display: flex; justify-content: center;">
|
||||
<div class="container-fluid">
|
||||
<div class="row">
|
||||
<div class="col col-lg-6 col-12">
|
||||
|
||||
<div class="card text-bg-light" id="left-stick-card" style="height: 340px;">
|
||||
<div class="card-header"><span class="ds-i18n">Left stick</span></div>
|
||||
<div class="card-body">
|
||||
<div class="container-fluid">
|
||||
<div class="finetune-grid">
|
||||
<div class="finetune-top finetune-center-mode">
|
||||
<input id="finetuneLY" type="number" class="form-control" min="0" max="65535" value="0">
|
||||
</div>
|
||||
<div class="finetune-top finetune-circularity-mode">
|
||||
<input id="finetuneLT" type="number" class="form-control" min="0" max="65535" value="0">
|
||||
</div>
|
||||
<div class="finetune-left finetune-circularity-mode">
|
||||
<input id="finetuneLL" type="number" class="form-control" min="0" max="65535" value="0">
|
||||
</div>
|
||||
<div class="finetune-left finetune-center-mode">
|
||||
<input id="finetuneLX" type="number" class="form-control" min="0" max="65535" value="0">
|
||||
</div>
|
||||
<div class="finetune-center">
|
||||
<canvas id="finetuneStickCanvasL" width="150px" height="150px"></canvas>
|
||||
<canvas id="finetuneStickCanvasL_large" width="210px" height="210px"></canvas>
|
||||
</div>
|
||||
<div class="finetune-right finetune-circularity-mode">
|
||||
<input id="finetuneLR" type="number" class="form-control" min="0" max="65535" value="0">
|
||||
</div>
|
||||
<div class="finetune-bottom finetune-circularity-mode">
|
||||
<input id="finetuneLB" type="number" class="form-control" min="0" max="65535" value="0">
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="px-2">
|
||||
<div class="hstack">
|
||||
<div class="vstack" style="text-align: center;">
|
||||
<span>LX:</span>
|
||||
<strong><pre id="finetuneStickCanvasLx-lbl" style="min-width: 80px;"></pre></strong>
|
||||
</div>
|
||||
|
||||
<div class="vstack" style="text-align: center;">
|
||||
<span>LY:</span>
|
||||
<strong><pre id="finetuneStickCanvasLy-lbl" style="min-width: 80px;"></pre></strong>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
</div> <!-- col -->
|
||||
|
||||
<div class="col col-lg-6 col-12">
|
||||
<div class="card text-bg-light" id="right-stick-card" style="height: 340px;">
|
||||
<div class="card-header"><span class="ds-i18n">Right stick</span></div>
|
||||
<div class="card-body">
|
||||
<div class="container-fluid">
|
||||
<div class="finetune-grid">
|
||||
<div class="finetune-top finetune-center-mode">
|
||||
<input id="finetuneRY" type="number" class="form-control" min="0" max="65535" value="0">
|
||||
</div>
|
||||
<div class="finetune-top finetune-circularity-mode">
|
||||
<input id="finetuneRT" type="number" class="form-control" min="0" max="65535" value="0">
|
||||
</div>
|
||||
<div class="finetune-left finetune-circularity-mode">
|
||||
<input id="finetuneRL" type="number" class="form-control" min="0" max="65535" value="0">
|
||||
</div>
|
||||
<div class="finetune-left finetune-center-mode">
|
||||
<input id="finetuneRX" type="number" class="form-control" min="0" max="65535" value="0">
|
||||
</div>
|
||||
<div class="finetune-center">
|
||||
<canvas id="finetuneStickCanvasR" width="150px" height="150px"></canvas>
|
||||
<canvas id="finetuneStickCanvasR_large" width="210px" height="210px"></canvas>
|
||||
</div>
|
||||
<div class="finetune-right finetune-circularity-mode">
|
||||
<input id="finetuneRR" type="number" class="form-control" min="0" max="65535" value="0">
|
||||
</div>
|
||||
<div class="finetune-bottom finetune-circularity-mode">
|
||||
<input id="finetuneRB" type="number" class="form-control" min="0" max="65535" value="0">
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="px-2">
|
||||
<div class="hstack">
|
||||
<div class="vstack" style="text-align: center;">
|
||||
<span>RX:</span>
|
||||
<strong><pre id="finetuneStickCanvasRx-lbl" style="min-width: 80px;"></pre></strong>
|
||||
</div>
|
||||
|
||||
<div class="vstack" style="text-align: center;">
|
||||
<span>RY:</span>
|
||||
<strong><pre id="finetuneStickCanvasRy-lbl" style="min-width: 80px;"></pre></strong>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
</div> <!-- col -->
|
||||
</div> <!-- row -->
|
||||
</div>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="modal-footer">
|
||||
<div class="form-check me-auto">
|
||||
<input class="form-check-input" type="checkbox" id="showRawNumbersCheckbox">
|
||||
<label class="form-check-label ds-i18n" for="showRawNumbersCheckbox">Show raw numbers</label>
|
||||
</div>
|
||||
<div class="dropdown me-2">
|
||||
<a class="btn btn-link text-decoration-none" href="#" role="button" id="stepSizeDropdown" data-bs-toggle="dropdown" aria-expanded="false">
|
||||
<span class="ds-i18n">Step size</span>: <span id="stepSizeValue">1</span>
|
||||
</a>
|
||||
<ul class="dropdown-menu" aria-labelledby="stepSizeDropdown">
|
||||
<li><a class="dropdown-item" href="#" data-step="15">15</a></li>
|
||||
<li><a class="dropdown-item" href="#" data-step="14">14</a></li>
|
||||
<li><a class="dropdown-item" href="#" data-step="13">13</a></li>
|
||||
<li><a class="dropdown-item" href="#" data-step="12">12</a></li>
|
||||
<li><a class="dropdown-item" href="#" data-step="11">11</a></li>
|
||||
<li><a class="dropdown-item" href="#" data-step="10">10</a></li>
|
||||
<li><a class="dropdown-item" href="#" data-step="9">9</a></li>
|
||||
<li><a class="dropdown-item" href="#" data-step="8">8</a></li>
|
||||
<li><a class="dropdown-item" href="#" data-step="7">7</a></li>
|
||||
<li><a class="dropdown-item" href="#" data-step="6">6</a></li>
|
||||
<li><a class="dropdown-item" href="#" data-step="5">5</a></li>
|
||||
<li><a class="dropdown-item" href="#" data-step="4">4</a></li>
|
||||
<li><a class="dropdown-item" href="#" data-step="3">3</a></li>
|
||||
<li><a class="dropdown-item" href="#" data-step="2">2</a></li>
|
||||
<li><a class="dropdown-item" href="#" data-step="1">1</a></li>
|
||||
</ul>
|
||||
</div>
|
||||
<button type="button" class="btn btn-secondary ds-i18n" onclick="finetune_cancel()">Cancel</button>
|
||||
<button type="button" class="btn btn-primary ds-i18n" onclick="finetune_save()">Done</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
11
templates/popup-modal.html
Normal file
11
templates/popup-modal.html
Normal file
@@ -0,0 +1,11 @@
|
||||
<!-- Popup -->
|
||||
<div class="modal fade" id="popupModal" tabindex="-1" aria-labelledby="popupTitle" aria-hidden="true">
|
||||
<div class="modal-dialog modal-dialog-centered">
|
||||
<div class="modal-content">
|
||||
<div class="modal-body" id="popupBody"></div>
|
||||
<div class="modal-footer">
|
||||
<button type="button" class="btn btn-primary" data-bs-dismiss="modal">OK</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
17
templates/range-modal.html
Normal file
17
templates/range-modal.html
Normal file
@@ -0,0 +1,17 @@
|
||||
<!-- Modal -->
|
||||
<div class="modal fade" id="rangeModal" data-bs-backdrop="static" data-bs-keyboard="false" tabindex="-1" aria-labelledby="staticBackdropLabel" aria-hidden="true">
|
||||
<div class="modal-dialog">
|
||||
<div class="modal-content">
|
||||
<div class="modal-header">
|
||||
<h1 class="modal-title fs-5 ds-i18n" id="staticBackdropLabel">Range calibration</h1>
|
||||
</div>
|
||||
<div class="modal-body">
|
||||
<p class="ds-i18n"><b>The controller is now sampling data!</b></p>
|
||||
<p class="ds-i18n">Rotate the sticks slowly to cover the whole range. Press "Done" when completed.</p>
|
||||
</div>
|
||||
<div class="modal-footer">
|
||||
<button type="button" class="btn btn-primary ds-i18n" onclick="calibrate_range_on_close()">Done</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
23
templates/welcome-modal.html
Normal file
23
templates/welcome-modal.html
Normal file
@@ -0,0 +1,23 @@
|
||||
<!-- Welcome Modal -->
|
||||
<div class="modal fade" id="welcomeModal" data-bs-backdrop="static" data-bs-keyboard="false" tabindex="-1" aria-labelledby="welcomeModalLabel" aria-hidden="true">
|
||||
<div class="modal-dialog modal-dialog-centered modal-lg">
|
||||
<div class="modal-content">
|
||||
<div class="modal-header">
|
||||
<h1 class="modal-title fs-5 ds-i18n" id="welcomeModalLabel">Welcome to the Calibration GUI</h1>
|
||||
</div>
|
||||
<div class="modal-body">
|
||||
<p class="ds-i18n">Just few things to know before you can start:</p>
|
||||
<ul>
|
||||
<li class="ds-i18n">This website is not affiliated with Sony, PlayStation & co.</li>
|
||||
<li class="ds-i18n">This service is provided without warranty. Use at your own risk.</li>
|
||||
<li class="ds-i18n">This website uses analytics to improve the service.</li>
|
||||
<li class="ds-i18n">Keep the internal battery of the controller connected and ensure it is well charged. If the battery dies during operations, the controller will be damaged and rendered unusable.</li>
|
||||
<li class="ds-i18n">Before doing the permanent calibration, try the temporary one to ensure that everything is working well.</li>
|
||||
</ul>
|
||||
</div>
|
||||
<div class="modal-footer">
|
||||
<button type="button" class="btn btn-primary ds-i18n" onclick="welcome_accepted();">Understood</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
Reference in New Issue
Block a user