mirror of
https://github.com/PCSX2/pcsx2.git
synced 2026-01-31 01:15:24 +01:00
Compare commits
21 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
05e19470b2 | ||
|
|
b6680e4aca | ||
|
|
f9d70af841 | ||
|
|
7587581d1f | ||
|
|
8f19976c10 | ||
|
|
8567d68433 | ||
|
|
6542301566 | ||
|
|
a359f77cf6 | ||
|
|
4c9a81f3d8 | ||
|
|
9234b493a3 | ||
|
|
f84425b67c | ||
|
|
8a0c1874dd | ||
|
|
fa23628ae2 | ||
|
|
8a594e673d | ||
|
|
92b9390c51 | ||
|
|
c5c5b2a7b9 | ||
|
|
32a9d0e48b | ||
|
|
80a961bb25 | ||
|
|
d4e227286e | ||
|
|
ba705c8c24 | ||
|
|
b6ae4b173e |
337
.github/workflows/scripts/releases/generate-release-notes/package-lock.json
generated
vendored
337
.github/workflows/scripts/releases/generate-release-notes/package-lock.json
generated
vendored
@@ -1,22 +1,33 @@
|
||||
{
|
||||
"name": "generate-release-notes",
|
||||
"version": "1.0.0",
|
||||
"lockfileVersion": 1,
|
||||
"lockfileVersion": 3,
|
||||
"requires": true,
|
||||
"dependencies": {
|
||||
"@octokit/auth-token": {
|
||||
"packages": {
|
||||
"": {
|
||||
"version": "1.0.0",
|
||||
"license": "ISC",
|
||||
"dependencies": {
|
||||
"@octokit/plugin-retry": "^3.0.9",
|
||||
"@octokit/plugin-throttling": "^3.5.2",
|
||||
"@octokit/rest": "^21.1.1"
|
||||
}
|
||||
},
|
||||
"node_modules/@octokit/auth-token": {
|
||||
"version": "2.5.0",
|
||||
"resolved": "https://registry.npmjs.org/@octokit/auth-token/-/auth-token-2.5.0.tgz",
|
||||
"integrity": "sha512-r5FVUJCOLl19AxiuZD2VRZ/ORjp/4IN98Of6YJoJOkY75CIBuYfmiNHGrDwXr+aLGG55igl9QrxX3hbiXlLb+g==",
|
||||
"requires": {
|
||||
"peer": true,
|
||||
"dependencies": {
|
||||
"@octokit/types": "^6.0.3"
|
||||
}
|
||||
},
|
||||
"@octokit/core": {
|
||||
"node_modules/@octokit/core": {
|
||||
"version": "3.5.1",
|
||||
"resolved": "https://registry.npmjs.org/@octokit/core/-/core-3.5.1.tgz",
|
||||
"integrity": "sha512-omncwpLVxMP+GLpLPgeGJBF6IWJFjXDS5flY5VbppePYX9XehevbDykRH9PdCdvqt9TS5AOTiDide7h0qrkHjw==",
|
||||
"requires": {
|
||||
"peer": true,
|
||||
"dependencies": {
|
||||
"@octokit/auth-token": "^2.4.4",
|
||||
"@octokit/graphql": "^4.5.8",
|
||||
"@octokit/request": "^5.6.0",
|
||||
@@ -26,76 +37,60 @@
|
||||
"universal-user-agent": "^6.0.0"
|
||||
}
|
||||
},
|
||||
"@octokit/endpoint": {
|
||||
"node_modules/@octokit/endpoint": {
|
||||
"version": "6.0.12",
|
||||
"resolved": "https://registry.npmjs.org/@octokit/endpoint/-/endpoint-6.0.12.tgz",
|
||||
"integrity": "sha512-lF3puPwkQWGfkMClXb4k/eUT/nZKQfxinRWJrdZaJO85Dqwo/G0yOC434Jr2ojwafWJMYqFGFa5ms4jJUgujdA==",
|
||||
"requires": {
|
||||
"peer": true,
|
||||
"dependencies": {
|
||||
"@octokit/types": "^6.0.3",
|
||||
"is-plain-object": "^5.0.0",
|
||||
"universal-user-agent": "^6.0.0"
|
||||
}
|
||||
},
|
||||
"@octokit/graphql": {
|
||||
"node_modules/@octokit/graphql": {
|
||||
"version": "4.8.0",
|
||||
"resolved": "https://registry.npmjs.org/@octokit/graphql/-/graphql-4.8.0.tgz",
|
||||
"integrity": "sha512-0gv+qLSBLKF0z8TKaSKTsS39scVKF9dbMxJpj3U0vC7wjNWFuIpL/z76Qe2fiuCbDRcJSavkXsVtMS6/dtQQsg==",
|
||||
"requires": {
|
||||
"peer": true,
|
||||
"dependencies": {
|
||||
"@octokit/request": "^5.6.0",
|
||||
"@octokit/types": "^6.0.3",
|
||||
"universal-user-agent": "^6.0.0"
|
||||
}
|
||||
},
|
||||
"@octokit/openapi-types": {
|
||||
"node_modules/@octokit/openapi-types": {
|
||||
"version": "11.1.0",
|
||||
"resolved": "https://registry.npmjs.org/@octokit/openapi-types/-/openapi-types-11.1.0.tgz",
|
||||
"integrity": "sha512-dWZfYvCCdjZzDYA3lIAMF72Q0jld8xidqCq5Ryw09eBJXZdcM6he0vWBTvw/b5UnGYqexxOyHWgfrsTlUJL3Gw=="
|
||||
},
|
||||
"@octokit/plugin-paginate-rest": {
|
||||
"version": "2.16.9",
|
||||
"resolved": "https://registry.npmjs.org/@octokit/plugin-paginate-rest/-/plugin-paginate-rest-2.16.9.tgz",
|
||||
"integrity": "sha512-gfSCMgz5scFKsR0dW4jaYsDJVt/UwCHp4dF7sHlmSekZvwzvLiOAGZ4MQkEsL5DW9hIk2W+UQkYZMTA1b6Wsqw==",
|
||||
"requires": {
|
||||
"@octokit/types": "^6.33.0"
|
||||
}
|
||||
},
|
||||
"@octokit/plugin-request-log": {
|
||||
"version": "1.0.4",
|
||||
"resolved": "https://registry.npmjs.org/@octokit/plugin-request-log/-/plugin-request-log-1.0.4.tgz",
|
||||
"integrity": "sha512-mLUsMkgP7K/cnFEw07kWqXGF5LKrOkD+lhCrKvPHXWDywAwuDUeDwWBpc69XK3pNX0uKiVt8g5z96PJ6z9xCFA=="
|
||||
},
|
||||
"@octokit/plugin-rest-endpoint-methods": {
|
||||
"version": "5.12.1",
|
||||
"resolved": "https://registry.npmjs.org/@octokit/plugin-rest-endpoint-methods/-/plugin-rest-endpoint-methods-5.12.1.tgz",
|
||||
"integrity": "sha512-0nY3htfl6x9UkPcqv8pm9vOC/bTA7f4IMDWln13neHRdNWQvOQgZ9fRxK7BAc74rye4yVINEFi9Yb9rnGUvosA==",
|
||||
"requires": {
|
||||
"@octokit/types": "^6.33.0",
|
||||
"deprecation": "^2.3.1"
|
||||
}
|
||||
},
|
||||
"@octokit/plugin-retry": {
|
||||
"node_modules/@octokit/plugin-retry": {
|
||||
"version": "3.0.9",
|
||||
"resolved": "https://registry.npmjs.org/@octokit/plugin-retry/-/plugin-retry-3.0.9.tgz",
|
||||
"integrity": "sha512-r+fArdP5+TG6l1Rv/C9hVoty6tldw6cE2pRHNGmFPdyfrc696R6JjrQ3d7HdVqGwuzfyrcaLAKD7K8TX8aehUQ==",
|
||||
"requires": {
|
||||
"dependencies": {
|
||||
"@octokit/types": "^6.0.3",
|
||||
"bottleneck": "^2.15.3"
|
||||
}
|
||||
},
|
||||
"@octokit/plugin-throttling": {
|
||||
"node_modules/@octokit/plugin-throttling": {
|
||||
"version": "3.5.2",
|
||||
"resolved": "https://registry.npmjs.org/@octokit/plugin-throttling/-/plugin-throttling-3.5.2.tgz",
|
||||
"integrity": "sha512-Eu7kfJxU8vmHqWGNszWpg+GVp2tnAfax3XQV5CkYPEE69C+KvInJXW9WajgSeW+cxYe0UVdouzCtcreGNuJo7A==",
|
||||
"requires": {
|
||||
"dependencies": {
|
||||
"@octokit/types": "^6.0.1",
|
||||
"bottleneck": "^2.15.3"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"@octokit/core": "^3.5.0"
|
||||
}
|
||||
},
|
||||
"@octokit/request": {
|
||||
"node_modules/@octokit/request": {
|
||||
"version": "5.6.2",
|
||||
"resolved": "https://registry.npmjs.org/@octokit/request/-/request-5.6.2.tgz",
|
||||
"integrity": "sha512-je66CvSEVf0jCpRISxkUcCa0UkxmFs6eGDRSbfJtAVwbLH5ceqF+YEyC8lj8ystKyZTy8adWr0qmkY52EfOeLA==",
|
||||
"requires": {
|
||||
"peer": true,
|
||||
"dependencies": {
|
||||
"@octokit/endpoint": "^6.0.1",
|
||||
"@octokit/request-error": "^2.1.0",
|
||||
"@octokit/types": "^6.16.1",
|
||||
@@ -104,99 +99,295 @@
|
||||
"universal-user-agent": "^6.0.0"
|
||||
}
|
||||
},
|
||||
"@octokit/request-error": {
|
||||
"node_modules/@octokit/request-error": {
|
||||
"version": "2.1.0",
|
||||
"resolved": "https://registry.npmjs.org/@octokit/request-error/-/request-error-2.1.0.tgz",
|
||||
"integrity": "sha512-1VIvgXxs9WHSjicsRwq8PlR2LR2x6DwsJAaFgzdi0JfJoGSO8mYI/cHJQ+9FbN21aa+DrgNLnwObmyeSC8Rmpg==",
|
||||
"requires": {
|
||||
"peer": true,
|
||||
"dependencies": {
|
||||
"@octokit/types": "^6.0.3",
|
||||
"deprecation": "^2.0.0",
|
||||
"once": "^1.4.0"
|
||||
}
|
||||
},
|
||||
"@octokit/rest": {
|
||||
"version": "18.12.0",
|
||||
"resolved": "https://registry.npmjs.org/@octokit/rest/-/rest-18.12.0.tgz",
|
||||
"integrity": "sha512-gDPiOHlyGavxr72y0guQEhLsemgVjwRePayJ+FcKc2SJqKUbxbkvf5kAZEWA/MKvsfYlQAMVzNJE3ezQcxMJ2Q==",
|
||||
"requires": {
|
||||
"@octokit/core": "^3.5.1",
|
||||
"@octokit/plugin-paginate-rest": "^2.16.8",
|
||||
"@octokit/plugin-request-log": "^1.0.4",
|
||||
"@octokit/plugin-rest-endpoint-methods": "^5.12.0"
|
||||
"node_modules/@octokit/rest": {
|
||||
"version": "21.1.1",
|
||||
"resolved": "https://registry.npmjs.org/@octokit/rest/-/rest-21.1.1.tgz",
|
||||
"integrity": "sha512-sTQV7va0IUVZcntzy1q3QqPm/r8rWtDCqpRAmb8eXXnKkjoQEtFe3Nt5GTVsHft+R6jJoHeSiVLcgcvhtue/rg==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@octokit/core": "^6.1.4",
|
||||
"@octokit/plugin-paginate-rest": "^11.4.2",
|
||||
"@octokit/plugin-request-log": "^5.3.1",
|
||||
"@octokit/plugin-rest-endpoint-methods": "^13.3.0"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">= 18"
|
||||
}
|
||||
},
|
||||
"@octokit/types": {
|
||||
"node_modules/@octokit/rest/node_modules/@octokit/auth-token": {
|
||||
"version": "5.1.2",
|
||||
"resolved": "https://registry.npmjs.org/@octokit/auth-token/-/auth-token-5.1.2.tgz",
|
||||
"integrity": "sha512-JcQDsBdg49Yky2w2ld20IHAlwr8d/d8N6NiOXbtuoPCqzbsiJgF633mVUw3x4mo0H5ypataQIX7SFu3yy44Mpw==",
|
||||
"license": "MIT",
|
||||
"engines": {
|
||||
"node": ">= 18"
|
||||
}
|
||||
},
|
||||
"node_modules/@octokit/rest/node_modules/@octokit/core": {
|
||||
"version": "6.1.4",
|
||||
"resolved": "https://registry.npmjs.org/@octokit/core/-/core-6.1.4.tgz",
|
||||
"integrity": "sha512-lAS9k7d6I0MPN+gb9bKDt7X8SdxknYqAMh44S5L+lNqIN2NuV8nvv3g8rPp7MuRxcOpxpUIATWprO0C34a8Qmg==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@octokit/auth-token": "^5.0.0",
|
||||
"@octokit/graphql": "^8.1.2",
|
||||
"@octokit/request": "^9.2.1",
|
||||
"@octokit/request-error": "^6.1.7",
|
||||
"@octokit/types": "^13.6.2",
|
||||
"before-after-hook": "^3.0.2",
|
||||
"universal-user-agent": "^7.0.0"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">= 18"
|
||||
}
|
||||
},
|
||||
"node_modules/@octokit/rest/node_modules/@octokit/endpoint": {
|
||||
"version": "10.1.3",
|
||||
"resolved": "https://registry.npmjs.org/@octokit/endpoint/-/endpoint-10.1.3.tgz",
|
||||
"integrity": "sha512-nBRBMpKPhQUxCsQQeW+rCJ/OPSMcj3g0nfHn01zGYZXuNDvvXudF/TYY6APj5THlurerpFN4a/dQAIAaM6BYhA==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@octokit/types": "^13.6.2",
|
||||
"universal-user-agent": "^7.0.2"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">= 18"
|
||||
}
|
||||
},
|
||||
"node_modules/@octokit/rest/node_modules/@octokit/graphql": {
|
||||
"version": "8.2.1",
|
||||
"resolved": "https://registry.npmjs.org/@octokit/graphql/-/graphql-8.2.1.tgz",
|
||||
"integrity": "sha512-n57hXtOoHrhwTWdvhVkdJHdhTv0JstjDbDRhJfwIRNfFqmSo1DaK/mD2syoNUoLCyqSjBpGAKOG0BuwF392slw==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@octokit/request": "^9.2.2",
|
||||
"@octokit/types": "^13.8.0",
|
||||
"universal-user-agent": "^7.0.0"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">= 18"
|
||||
}
|
||||
},
|
||||
"node_modules/@octokit/rest/node_modules/@octokit/openapi-types": {
|
||||
"version": "23.0.1",
|
||||
"resolved": "https://registry.npmjs.org/@octokit/openapi-types/-/openapi-types-23.0.1.tgz",
|
||||
"integrity": "sha512-izFjMJ1sir0jn0ldEKhZ7xegCTj/ObmEDlEfpFrx4k/JyZSMRHbO3/rBwgE7f3m2DHt+RrNGIVw4wSmwnm3t/g==",
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/@octokit/rest/node_modules/@octokit/plugin-paginate-rest": {
|
||||
"version": "11.4.2",
|
||||
"resolved": "https://registry.npmjs.org/@octokit/plugin-paginate-rest/-/plugin-paginate-rest-11.4.2.tgz",
|
||||
"integrity": "sha512-BXJ7XPCTDXFF+wxcg/zscfgw2O/iDPtNSkwwR1W1W5c4Mb3zav/M2XvxQ23nVmKj7jpweB4g8viMeCQdm7LMVA==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@octokit/types": "^13.7.0"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">= 18"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"@octokit/core": ">=6"
|
||||
}
|
||||
},
|
||||
"node_modules/@octokit/rest/node_modules/@octokit/plugin-request-log": {
|
||||
"version": "5.3.1",
|
||||
"resolved": "https://registry.npmjs.org/@octokit/plugin-request-log/-/plugin-request-log-5.3.1.tgz",
|
||||
"integrity": "sha512-n/lNeCtq+9ofhC15xzmJCNKP2BWTv8Ih2TTy+jatNCCq/gQP/V7rK3fjIfuz0pDWDALO/o/4QY4hyOF6TQQFUw==",
|
||||
"license": "MIT",
|
||||
"engines": {
|
||||
"node": ">= 18"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"@octokit/core": ">=6"
|
||||
}
|
||||
},
|
||||
"node_modules/@octokit/rest/node_modules/@octokit/plugin-rest-endpoint-methods": {
|
||||
"version": "13.3.1",
|
||||
"resolved": "https://registry.npmjs.org/@octokit/plugin-rest-endpoint-methods/-/plugin-rest-endpoint-methods-13.3.1.tgz",
|
||||
"integrity": "sha512-o8uOBdsyR+WR8MK9Cco8dCgvG13H1RlM1nWnK/W7TEACQBFux/vPREgKucxUfuDQ5yi1T3hGf4C5ZmZXAERgwQ==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@octokit/types": "^13.8.0"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">= 18"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"@octokit/core": ">=6"
|
||||
}
|
||||
},
|
||||
"node_modules/@octokit/rest/node_modules/@octokit/request": {
|
||||
"version": "9.2.2",
|
||||
"resolved": "https://registry.npmjs.org/@octokit/request/-/request-9.2.2.tgz",
|
||||
"integrity": "sha512-dZl0ZHx6gOQGcffgm1/Sf6JfEpmh34v3Af2Uci02vzUYz6qEN6zepoRtmybWXIGXFIK8K9ylE3b+duCWqhArtg==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@octokit/endpoint": "^10.1.3",
|
||||
"@octokit/request-error": "^6.1.7",
|
||||
"@octokit/types": "^13.6.2",
|
||||
"fast-content-type-parse": "^2.0.0",
|
||||
"universal-user-agent": "^7.0.2"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">= 18"
|
||||
}
|
||||
},
|
||||
"node_modules/@octokit/rest/node_modules/@octokit/request-error": {
|
||||
"version": "6.1.7",
|
||||
"resolved": "https://registry.npmjs.org/@octokit/request-error/-/request-error-6.1.7.tgz",
|
||||
"integrity": "sha512-69NIppAwaauwZv6aOzb+VVLwt+0havz9GT5YplkeJv7fG7a40qpLt/yZKyiDxAhgz0EtgNdNcb96Z0u+Zyuy2g==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@octokit/types": "^13.6.2"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">= 18"
|
||||
}
|
||||
},
|
||||
"node_modules/@octokit/rest/node_modules/@octokit/types": {
|
||||
"version": "13.8.0",
|
||||
"resolved": "https://registry.npmjs.org/@octokit/types/-/types-13.8.0.tgz",
|
||||
"integrity": "sha512-x7DjTIbEpEWXK99DMd01QfWy0hd5h4EN+Q7shkdKds3otGQP+oWE/y0A76i1OvH9fygo4ddvNf7ZvF0t78P98A==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@octokit/openapi-types": "^23.0.1"
|
||||
}
|
||||
},
|
||||
"node_modules/@octokit/rest/node_modules/before-after-hook": {
|
||||
"version": "3.0.2",
|
||||
"resolved": "https://registry.npmjs.org/before-after-hook/-/before-after-hook-3.0.2.tgz",
|
||||
"integrity": "sha512-Nik3Sc0ncrMK4UUdXQmAnRtzmNQTAAXmXIopizwZ1W1t8QmfJj+zL4OA2I7XPTPW5z5TDqv4hRo/JzouDJnX3A==",
|
||||
"license": "Apache-2.0"
|
||||
},
|
||||
"node_modules/@octokit/rest/node_modules/universal-user-agent": {
|
||||
"version": "7.0.2",
|
||||
"resolved": "https://registry.npmjs.org/universal-user-agent/-/universal-user-agent-7.0.2.tgz",
|
||||
"integrity": "sha512-0JCqzSKnStlRRQfCdowvqy3cy0Dvtlb8xecj/H8JFZuCze4rwjPZQOgvFvn0Ws/usCHQFGpyr+pB9adaGwXn4Q==",
|
||||
"license": "ISC"
|
||||
},
|
||||
"node_modules/@octokit/types": {
|
||||
"version": "6.33.0",
|
||||
"resolved": "https://registry.npmjs.org/@octokit/types/-/types-6.33.0.tgz",
|
||||
"integrity": "sha512-0zffZ048M0UhthyPXQHLz4038Ak46nMWZXkzlXvXB/M/L1jYPBceq4iZj4qjKVrvveaJrrgKdJ9+3yUuITfcCw==",
|
||||
"requires": {
|
||||
"dependencies": {
|
||||
"@octokit/openapi-types": "^11.1.0"
|
||||
}
|
||||
},
|
||||
"before-after-hook": {
|
||||
"node_modules/before-after-hook": {
|
||||
"version": "2.2.2",
|
||||
"resolved": "https://registry.npmjs.org/before-after-hook/-/before-after-hook-2.2.2.tgz",
|
||||
"integrity": "sha512-3pZEU3NT5BFUo/AD5ERPWOgQOCZITni6iavr5AUw5AUwQjMlI0kzu5btnyD39AF0gUEsDPwJT+oY1ORBJijPjQ=="
|
||||
"integrity": "sha512-3pZEU3NT5BFUo/AD5ERPWOgQOCZITni6iavr5AUw5AUwQjMlI0kzu5btnyD39AF0gUEsDPwJT+oY1ORBJijPjQ==",
|
||||
"peer": true
|
||||
},
|
||||
"bottleneck": {
|
||||
"node_modules/bottleneck": {
|
||||
"version": "2.19.5",
|
||||
"resolved": "https://registry.npmjs.org/bottleneck/-/bottleneck-2.19.5.tgz",
|
||||
"integrity": "sha512-VHiNCbI1lKdl44tGrhNfU3lup0Tj/ZBMJB5/2ZbNXRCPuRCO7ed2mgcK4r17y+KB2EfuYuRaVlwNbAeaWGSpbw=="
|
||||
},
|
||||
"deprecation": {
|
||||
"node_modules/deprecation": {
|
||||
"version": "2.3.1",
|
||||
"resolved": "https://registry.npmjs.org/deprecation/-/deprecation-2.3.1.tgz",
|
||||
"integrity": "sha512-xmHIy4F3scKVwMsQ4WnVaS8bHOx0DmVwRywosKhaILI0ywMDWPtBSku2HNxRvF7jtwDRsoEwYQSfbxj8b7RlJQ=="
|
||||
"integrity": "sha512-xmHIy4F3scKVwMsQ4WnVaS8bHOx0DmVwRywosKhaILI0ywMDWPtBSku2HNxRvF7jtwDRsoEwYQSfbxj8b7RlJQ==",
|
||||
"peer": true
|
||||
},
|
||||
"is-plain-object": {
|
||||
"node_modules/fast-content-type-parse": {
|
||||
"version": "2.0.1",
|
||||
"resolved": "https://registry.npmjs.org/fast-content-type-parse/-/fast-content-type-parse-2.0.1.tgz",
|
||||
"integrity": "sha512-nGqtvLrj5w0naR6tDPfB4cUmYCqouzyQiz6C5y/LtcDllJdrcc6WaWW6iXyIIOErTa/XRybj28aasdn4LkVk6Q==",
|
||||
"funding": [
|
||||
{
|
||||
"type": "github",
|
||||
"url": "https://github.com/sponsors/fastify"
|
||||
},
|
||||
{
|
||||
"type": "opencollective",
|
||||
"url": "https://opencollective.com/fastify"
|
||||
}
|
||||
],
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/is-plain-object": {
|
||||
"version": "5.0.0",
|
||||
"resolved": "https://registry.npmjs.org/is-plain-object/-/is-plain-object-5.0.0.tgz",
|
||||
"integrity": "sha512-VRSzKkbMm5jMDoKLbltAkFQ5Qr7VDiTFGXxYFXXowVj387GeGNOCsOH6Msy00SGZ3Fp84b1Naa1psqgcCIEP5Q=="
|
||||
"integrity": "sha512-VRSzKkbMm5jMDoKLbltAkFQ5Qr7VDiTFGXxYFXXowVj387GeGNOCsOH6Msy00SGZ3Fp84b1Naa1psqgcCIEP5Q==",
|
||||
"peer": true,
|
||||
"engines": {
|
||||
"node": ">=0.10.0"
|
||||
}
|
||||
},
|
||||
"node-fetch": {
|
||||
"node_modules/node-fetch": {
|
||||
"version": "2.6.7",
|
||||
"resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-2.6.7.tgz",
|
||||
"integrity": "sha512-ZjMPFEfVx5j+y2yF35Kzx5sF7kDzxuDj6ziH4FFbOp87zKDZNx8yExJIb05OGF4Nlt9IHFIMBkRl41VdvcNdbQ==",
|
||||
"requires": {
|
||||
"peer": true,
|
||||
"dependencies": {
|
||||
"whatwg-url": "^5.0.0"
|
||||
},
|
||||
"engines": {
|
||||
"node": "4.x || >=6.0.0"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"encoding": "^0.1.0"
|
||||
},
|
||||
"peerDependenciesMeta": {
|
||||
"encoding": {
|
||||
"optional": true
|
||||
}
|
||||
}
|
||||
},
|
||||
"once": {
|
||||
"node_modules/once": {
|
||||
"version": "1.4.0",
|
||||
"resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz",
|
||||
"integrity": "sha1-WDsap3WWHUsROsF9nFC6753Xa9E=",
|
||||
"requires": {
|
||||
"peer": true,
|
||||
"dependencies": {
|
||||
"wrappy": "1"
|
||||
}
|
||||
},
|
||||
"tr46": {
|
||||
"node_modules/tr46": {
|
||||
"version": "0.0.3",
|
||||
"resolved": "https://registry.npmjs.org/tr46/-/tr46-0.0.3.tgz",
|
||||
"integrity": "sha1-gYT9NH2snNwYWZLzpmIuFLnZq2o="
|
||||
"integrity": "sha1-gYT9NH2snNwYWZLzpmIuFLnZq2o=",
|
||||
"peer": true
|
||||
},
|
||||
"universal-user-agent": {
|
||||
"node_modules/universal-user-agent": {
|
||||
"version": "6.0.0",
|
||||
"resolved": "https://registry.npmjs.org/universal-user-agent/-/universal-user-agent-6.0.0.tgz",
|
||||
"integrity": "sha512-isyNax3wXoKaulPDZWHQqbmIx1k2tb9fb3GGDBRxCscfYV2Ch7WxPArBsFEG8s/safwXTT7H4QGhaIkTp9447w=="
|
||||
"integrity": "sha512-isyNax3wXoKaulPDZWHQqbmIx1k2tb9fb3GGDBRxCscfYV2Ch7WxPArBsFEG8s/safwXTT7H4QGhaIkTp9447w==",
|
||||
"peer": true
|
||||
},
|
||||
"webidl-conversions": {
|
||||
"node_modules/webidl-conversions": {
|
||||
"version": "3.0.1",
|
||||
"resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-3.0.1.tgz",
|
||||
"integrity": "sha1-JFNCdeKnvGvnvIZhHMFq4KVlSHE="
|
||||
"integrity": "sha1-JFNCdeKnvGvnvIZhHMFq4KVlSHE=",
|
||||
"peer": true
|
||||
},
|
||||
"whatwg-url": {
|
||||
"node_modules/whatwg-url": {
|
||||
"version": "5.0.0",
|
||||
"resolved": "https://registry.npmjs.org/whatwg-url/-/whatwg-url-5.0.0.tgz",
|
||||
"integrity": "sha1-lmRU6HZUYuN2RNNib2dCzotwll0=",
|
||||
"requires": {
|
||||
"peer": true,
|
||||
"dependencies": {
|
||||
"tr46": "~0.0.3",
|
||||
"webidl-conversions": "^3.0.0"
|
||||
}
|
||||
},
|
||||
"wrappy": {
|
||||
"node_modules/wrappy": {
|
||||
"version": "1.0.2",
|
||||
"resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz",
|
||||
"integrity": "sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8="
|
||||
"integrity": "sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8=",
|
||||
"peer": true
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -12,6 +12,6 @@
|
||||
"dependencies": {
|
||||
"@octokit/plugin-retry": "^3.0.9",
|
||||
"@octokit/plugin-throttling": "^3.5.2",
|
||||
"@octokit/rest": "^18.12.0"
|
||||
"@octokit/rest": "^21.1.1"
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1270,6 +1270,7 @@ SCAJ-10015:
|
||||
region: "NTSC-Unk"
|
||||
gsHWFixes:
|
||||
alignSprite: 1 # Fixes vertical lines.
|
||||
getSkipCount: "GSC_Tekken5" # Fixes upscaling grid, same engine.
|
||||
SCAJ-20001:
|
||||
name: "Ratchet & Clank"
|
||||
region: "NTSC-Unk"
|
||||
@@ -2236,6 +2237,7 @@ SCAJ-20163:
|
||||
gsHWFixes:
|
||||
halfPixelOffset: 2 # Fixes ghosting.
|
||||
autoFlush: 2 # Fixes post lighting.
|
||||
getSkipCount: "GSC_Tekken5" # Fixes upscaling grid, same engine.
|
||||
SCAJ-20164:
|
||||
name: "Kingdom Hearts II"
|
||||
region: "NTSC-Unk"
|
||||
@@ -54687,6 +54689,7 @@ SLPS-20485:
|
||||
region: "NTSC-J"
|
||||
gsHWFixes:
|
||||
alignSprite: 1 # Fixes vertical lines.
|
||||
getSkipCount: "GSC_Tekken5" # Fixes upscaling grid, same engine.
|
||||
SLPS-20486:
|
||||
name: "太鼓の達人 ドカッ!と大盛り七代目 [ソフト単体]"
|
||||
name-sort: "たいこのたつじん どかっ!とおおもりななだいめ [そふとたんたい]"
|
||||
@@ -54694,6 +54697,7 @@ SLPS-20486:
|
||||
region: "NTSC-J"
|
||||
gsHWFixes:
|
||||
alignSprite: 1 # Fixes vertical lines.
|
||||
getSkipCount: "GSC_Tekken5" # Fixes upscaling grid, same engine.
|
||||
SLPS-20487:
|
||||
name: "パチスロキング! 科学忍者隊ガッチャマン"
|
||||
name-sort: "ぱちすろきんぐ! かがくにんじゃたいがっちゃまん"
|
||||
@@ -58271,6 +58275,7 @@ SLPS-25586:
|
||||
halfPixelOffset: 4 # Fixes post positioning.
|
||||
nativeScaling: 1 # Fixes post effects.
|
||||
autoFlush: 2 # Fixes post lighting.
|
||||
getSkipCount: "GSC_Tekken5" # Fixes upscaling grid, same engine.
|
||||
SLPS-25587:
|
||||
name: "シュガシュガルーン 恋もおしゃれもピックアップ!"
|
||||
name-sort: "しゅがしゅがるーん こいもおしゃれもぴっくあっぷ!"
|
||||
@@ -61304,6 +61309,7 @@ SLPS-73252:
|
||||
halfPixelOffset: 4 # Fixes post positioning.
|
||||
nativeScaling: 1 # Fixes post effects.
|
||||
autoFlush: 2 # Fixes post lighting.
|
||||
getSkipCount: "GSC_Tekken5" # Fixes upscaling grid, same engine.
|
||||
SLPS-73253:
|
||||
name: "るろうに剣心-明治剣客浪漫譚- 炎上!京都輪廻 [PlayStation2 the Best]"
|
||||
name-sort: "るろうにけんしん めいじけんかくろまんたん えんじょう きょうとりんね [PlayStation2 the Best]"
|
||||
@@ -69137,6 +69143,7 @@ SLUS-21386:
|
||||
halfPixelOffset: 4 # Fixes post positioning.
|
||||
nativeScaling: 1 # Fixes post effects.
|
||||
autoFlush: 2 # Fixes post lighting.
|
||||
getSkipCount: "GSC_Tekken5" # Fixes upscaling grid, same engine.
|
||||
SLUS-21387:
|
||||
name: "Warship Gunner 2"
|
||||
region: "NTSC-U"
|
||||
|
||||
@@ -1354,8 +1354,11 @@ static u32 TranslateWin32Attributes(u32 Win32Attributes)
|
||||
}
|
||||
|
||||
static u32 RecursiveFindFiles(const char* origin_path, const char* parent_path, const char* path, const char* pattern,
|
||||
u32 flags, FileSystem::FindResultsArray* results, std::vector<std::string>& visited)
|
||||
u32 flags, FileSystem::FindResultsArray* results, std::vector<std::string>& visited, ProgressCallback* cancel)
|
||||
{
|
||||
if (cancel && cancel->IsCancelled())
|
||||
return 0;
|
||||
|
||||
std::string search_dir;
|
||||
if (path)
|
||||
{
|
||||
@@ -1427,11 +1430,11 @@ static u32 RecursiveFindFiles(const char* origin_path, const char* parent_path,
|
||||
if (parent_path)
|
||||
{
|
||||
const std::string recurse_dir = fmt::format("{}\\{}", parent_path, path);
|
||||
nFiles += RecursiveFindFiles(origin_path, recurse_dir.c_str(), utf8_filename.c_str(), pattern, flags, results, visited);
|
||||
nFiles += RecursiveFindFiles(origin_path, recurse_dir.c_str(), utf8_filename.c_str(), pattern, flags, results, visited, cancel);
|
||||
}
|
||||
else
|
||||
{
|
||||
nFiles += RecursiveFindFiles(origin_path, path, utf8_filename.c_str(), pattern, flags, results, visited);
|
||||
nFiles += RecursiveFindFiles(origin_path, path, utf8_filename.c_str(), pattern, flags, results, visited, cancel);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1494,7 +1497,7 @@ static u32 RecursiveFindFiles(const char* origin_path, const char* parent_path,
|
||||
return nFiles;
|
||||
}
|
||||
|
||||
bool FileSystem::FindFiles(const char* path, const char* pattern, u32 flags, FindResultsArray* results)
|
||||
bool FileSystem::FindFiles(const char* path, const char* pattern, u32 flags, FindResultsArray* results, ProgressCallback* cancel)
|
||||
{
|
||||
// has a path
|
||||
if (path[0] == '\0')
|
||||
@@ -1514,7 +1517,7 @@ bool FileSystem::FindFiles(const char* path, const char* pattern, u32 flags, Fin
|
||||
}
|
||||
|
||||
// enter the recursive function
|
||||
if (RecursiveFindFiles(path, nullptr, nullptr, pattern, flags, results, visited) == 0)
|
||||
if (RecursiveFindFiles(path, nullptr, nullptr, pattern, flags, results, visited, cancel) == 0)
|
||||
return false;
|
||||
|
||||
if (flags & FILESYSTEM_FIND_SORT_BY_NAME)
|
||||
@@ -2046,8 +2049,11 @@ bool FileSystem::DeleteSymbolicLink(const char* path, Error* error)
|
||||
static_assert(sizeof(off_t) == sizeof(s64));
|
||||
|
||||
static u32 RecursiveFindFiles(const char* OriginPath, const char* ParentPath, const char* Path, const char* Pattern,
|
||||
u32 Flags, FileSystem::FindResultsArray* pResults, std::vector<std::string>& visited)
|
||||
u32 Flags, FileSystem::FindResultsArray* pResults, std::vector<std::string>& visited, ProgressCallback* cancel)
|
||||
{
|
||||
if (cancel && cancel->IsCancelled())
|
||||
return 0;
|
||||
|
||||
std::string tempStr;
|
||||
if (Path)
|
||||
{
|
||||
@@ -2118,11 +2124,11 @@ static u32 RecursiveFindFiles(const char* OriginPath, const char* ParentPath, co
|
||||
if (ParentPath)
|
||||
{
|
||||
const std::string recursive_dir = fmt::format("{}/{}", ParentPath, Path);
|
||||
nFiles += RecursiveFindFiles(OriginPath, recursive_dir.c_str(), pDirEnt->d_name, Pattern, Flags, pResults, visited);
|
||||
nFiles += RecursiveFindFiles(OriginPath, recursive_dir.c_str(), pDirEnt->d_name, Pattern, Flags, pResults, visited, cancel);
|
||||
}
|
||||
else
|
||||
{
|
||||
nFiles += RecursiveFindFiles(OriginPath, Path, pDirEnt->d_name, Pattern, Flags, pResults, visited);
|
||||
nFiles += RecursiveFindFiles(OriginPath, Path, pDirEnt->d_name, Pattern, Flags, pResults, visited, cancel);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -2177,7 +2183,7 @@ static u32 RecursiveFindFiles(const char* OriginPath, const char* ParentPath, co
|
||||
return nFiles;
|
||||
}
|
||||
|
||||
bool FileSystem::FindFiles(const char* path, const char* pattern, u32 flags, FindResultsArray* results)
|
||||
bool FileSystem::FindFiles(const char* path, const char* pattern, u32 flags, FindResultsArray* results, ProgressCallback* cancel)
|
||||
{
|
||||
// has a path
|
||||
if (path[0] == '\0')
|
||||
@@ -2197,7 +2203,7 @@ bool FileSystem::FindFiles(const char* path, const char* pattern, u32 flags, Fin
|
||||
}
|
||||
|
||||
// enter the recursive function
|
||||
if (RecursiveFindFiles(path, nullptr, nullptr, pattern, flags, results, visited) == 0)
|
||||
if (RecursiveFindFiles(path, nullptr, nullptr, pattern, flags, results, visited, cancel) == 0)
|
||||
return false;
|
||||
|
||||
if (flags & FILESYSTEM_FIND_SORT_BY_NAME)
|
||||
|
||||
@@ -67,7 +67,7 @@ namespace FileSystem
|
||||
std::vector<std::string> GetRootDirectoryList();
|
||||
|
||||
/// Search for files
|
||||
bool FindFiles(const char* path, const char* pattern, u32 flags, FindResultsArray* results);
|
||||
bool FindFiles(const char* path, const char* pattern, u32 flags, FindResultsArray* results, ProgressCallback* cancel = nullptr);
|
||||
|
||||
/// Stat file
|
||||
bool StatFile(const char* path, struct stat* st);
|
||||
|
||||
@@ -212,7 +212,7 @@
|
||||
</size>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>1</string>
|
||||
<string>4</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
|
||||
@@ -453,7 +453,7 @@ std::vector<SearchResult> startWorker(DebugInterface* cpu, const SearchType type
|
||||
isSigned ? searchWorker<s32>(cpu, searchResults, type, comparison, start, end, value.toInt(nullptr, base)) : searchWorker<u32>(cpu, searchResults, type, comparison, start, end, value.toUInt(nullptr, base));
|
||||
break;
|
||||
case SearchType::Int64Type:
|
||||
isSigned ? searchWorker<s64>(cpu, searchResults, type, comparison, start, end, value.toLong(nullptr, base)) : searchWorker<s64>(cpu, searchResults, type, comparison, start, end, value.toULongLong(nullptr, base));
|
||||
isSigned ? searchWorker<s64>(cpu, searchResults, type, comparison, start, end, value.toLongLong(nullptr, base)) : searchWorker<u64>(cpu, searchResults, type, comparison, start, end, value.toULongLong(nullptr, base));
|
||||
break;
|
||||
case SearchType::FloatType:
|
||||
searchWorker<float>(cpu, searchResults, type, comparison, start, end, value.toFloat());
|
||||
|
||||
@@ -99,6 +99,9 @@ static QString s_current_disc_serial;
|
||||
static quint32 s_current_disc_crc;
|
||||
static quint32 s_current_running_crc;
|
||||
|
||||
static bool s_record_on_start = false;
|
||||
static QString s_path_to_recording_for_record_on_start;
|
||||
|
||||
MainWindow::MainWindow()
|
||||
{
|
||||
pxAssert(!g_main_window);
|
||||
@@ -738,7 +741,48 @@ void MainWindow::updateAdvancedSettingsVisibility()
|
||||
void MainWindow::onVideoCaptureToggled(bool checked)
|
||||
{
|
||||
if (!s_vm_valid)
|
||||
{
|
||||
if (!s_record_on_start)
|
||||
{
|
||||
QMessageBox msgbox(this);
|
||||
msgbox.setIcon(QMessageBox::Question);
|
||||
msgbox.setWindowIcon(QtHost::GetAppIcon());
|
||||
msgbox.setWindowTitle(tr("Record On Boot"));
|
||||
msgbox.setWindowModality(Qt::WindowModal);
|
||||
msgbox.setText(tr("Did you want to start recording on boot?"));
|
||||
msgbox.addButton(QMessageBox::Yes);
|
||||
msgbox.addButton(QMessageBox::No);
|
||||
msgbox.setDefaultButton(QMessageBox::Yes);
|
||||
if (msgbox.exec() == QMessageBox::Yes)
|
||||
{
|
||||
const QString container(QString::fromStdString(
|
||||
Host::GetStringSettingValue("EmuCore/GS", "CaptureContainer", Pcsx2Config::GSOptions::DEFAULT_CAPTURE_CONTAINER)));
|
||||
const QString filter(tr("%1 Files (*.%2)").arg(container.toUpper()).arg(container));
|
||||
|
||||
QString temp(QStringLiteral("%1.%2").arg(QString::fromStdString(GSGetBaseVideoFilename())).arg(container));
|
||||
temp = QDir::toNativeSeparators(QFileDialog::getSaveFileName(this, tr("Video Capture"), temp, filter));
|
||||
s_path_to_recording_for_record_on_start = temp;
|
||||
if (s_path_to_recording_for_record_on_start.isEmpty())
|
||||
return;
|
||||
s_record_on_start = true;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
QMessageBox msgbox(this);
|
||||
msgbox.setIcon(QMessageBox::Question);
|
||||
msgbox.setWindowIcon(QtHost::GetAppIcon());
|
||||
msgbox.setWindowTitle(tr("Record On Boot"));
|
||||
msgbox.setWindowModality(Qt::WindowModal);
|
||||
msgbox.setText(tr("Did you want to cancel recording on boot?"));
|
||||
msgbox.addButton(QMessageBox::Yes);
|
||||
msgbox.addButton(QMessageBox::No);
|
||||
msgbox.setDefaultButton(QMessageBox::Yes);
|
||||
if (msgbox.exec() == QMessageBox::Yes)
|
||||
s_record_on_start = false;
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
// Reset the checked state, we'll get updated by the GS thread.
|
||||
QSignalBlocker sb(m_ui.actionVideoCapture);
|
||||
@@ -750,16 +794,26 @@ void MainWindow::onVideoCaptureToggled(bool checked)
|
||||
return;
|
||||
}
|
||||
|
||||
const QString container(QString::fromStdString(
|
||||
Host::GetStringSettingValue("EmuCore/GS", "CaptureContainer", Pcsx2Config::GSOptions::DEFAULT_CAPTURE_CONTAINER)));
|
||||
const QString filter(tr("%1 Files (*.%2)").arg(container.toUpper()).arg(container));
|
||||
if (s_record_on_start && !s_path_to_recording_for_record_on_start.isEmpty())
|
||||
{
|
||||
// We can't start recording immediately, this is called before full GS init (specifically the fps amount)
|
||||
// and GSCapture ends up unhappy.
|
||||
// TODO: Pass some sort of flag or callback to the GS thread to start recording on frame 0.
|
||||
Host::AddOSDMessage(tr("Recording will start in a moment").toStdString(), 3.0f);
|
||||
QTimer::singleShot(2000, []() { g_emu_thread->beginCapture(s_path_to_recording_for_record_on_start); });
|
||||
}
|
||||
else
|
||||
{
|
||||
const QString container(QString::fromStdString(
|
||||
Host::GetStringSettingValue("EmuCore/GS", "CaptureContainer", Pcsx2Config::GSOptions::DEFAULT_CAPTURE_CONTAINER)));
|
||||
const QString filter(tr("%1 Files (*.%2)").arg(container.toUpper()).arg(container));
|
||||
|
||||
QString path(QStringLiteral("%1.%2").arg(QString::fromStdString(GSGetBaseVideoFilename())).arg(container));
|
||||
path = QDir::toNativeSeparators(QFileDialog::getSaveFileName(this, tr("Video Capture"), path, filter));
|
||||
if (path.isEmpty())
|
||||
return;
|
||||
|
||||
g_emu_thread->beginCapture(path);
|
||||
QString path(QStringLiteral("%1.%2").arg(QString::fromStdString(GSGetBaseVideoFilename())).arg(container));
|
||||
path = QDir::toNativeSeparators(QFileDialog::getSaveFileName(this, tr("Video Capture"), path, filter));
|
||||
if (path.isEmpty())
|
||||
return;
|
||||
g_emu_thread->beginCapture(path);
|
||||
}
|
||||
}
|
||||
|
||||
void MainWindow::onCaptureStarted(const QString& filename)
|
||||
@@ -904,8 +958,6 @@ void MainWindow::updateEmulationActions(bool starting, bool running, bool stoppi
|
||||
m_ui.actionToolbarSaveState->setEnabled(running);
|
||||
|
||||
m_ui.actionViewGameProperties->setEnabled(running);
|
||||
|
||||
m_ui.actionVideoCapture->setEnabled(running);
|
||||
if (!running && m_ui.actionVideoCapture->isChecked())
|
||||
{
|
||||
QSignalBlocker sb(m_ui.actionVideoCapture);
|
||||
@@ -1991,6 +2043,11 @@ void MainWindow::onVMStarted()
|
||||
updateWindowTitle();
|
||||
updateStatusBarWidgetVisibility();
|
||||
updateInputRecordingActions(true);
|
||||
if (s_record_on_start)
|
||||
{
|
||||
m_ui.actionVideoCapture->setChecked(true);
|
||||
s_record_on_start = false;
|
||||
}
|
||||
}
|
||||
|
||||
void MainWindow::onVMPaused()
|
||||
|
||||
@@ -1055,7 +1055,12 @@
|
||||
</item>
|
||||
<item>
|
||||
<property name="text">
|
||||
<string>Align To Native</string>
|
||||
<string>Align to Native</string>
|
||||
</property>
|
||||
</item>
|
||||
<item>
|
||||
<property name="text">
|
||||
<string>Align to Native - with Texture Offset</string>
|
||||
</property>
|
||||
</item>
|
||||
</widget>
|
||||
|
||||
@@ -11,6 +11,7 @@
|
||||
#include "common/SmallString.h"
|
||||
#include "common/StringUtil.h"
|
||||
|
||||
#include "pcsx2/ImGui/FullscreenUI.h"
|
||||
#include "pcsx2/ImGui/ImGuiManager.h"
|
||||
#include "pcsx2/MTGS.h"
|
||||
|
||||
@@ -191,6 +192,13 @@ void QtHost::InstallTranslator(QWidget* dialog_parent)
|
||||
}
|
||||
|
||||
UpdateGlyphRangesAndClearCache(dialog_parent, language.toStdString());
|
||||
|
||||
if (FullscreenUI::IsInitialized())
|
||||
{
|
||||
MTGS::RunOnGSThread([]() mutable {
|
||||
FullscreenUI::LocaleChanged();
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
const char* QtHost::GetDefaultLanguage()
|
||||
@@ -220,6 +228,12 @@ std::string Host::TranslatePluralToString(const char* context, const char* msg,
|
||||
return qApp->translate(context, msg, disambiguation, count).toStdString();
|
||||
}
|
||||
|
||||
bool Host::LocaleCircleConfirm()
|
||||
{
|
||||
QLocale& loc = QtHost::s_current_locale;
|
||||
return (loc.language() == QLocale::Japanese) || (loc.language() == QLocale::Chinese) || (loc.language() == QLocale::Korean);
|
||||
}
|
||||
|
||||
std::vector<std::pair<QString, QString>> QtHost::GetAvailableLanguageList()
|
||||
{
|
||||
return {
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -440,6 +440,7 @@ enum class GSHalfPixelOffset : u8
|
||||
Special,
|
||||
SpecialAggressive,
|
||||
Native,
|
||||
NativeWTexOffset,
|
||||
MaxCount
|
||||
};
|
||||
|
||||
|
||||
@@ -179,7 +179,7 @@ The clamp modes are also numerically based.
|
||||
* bilinearUpscale [`0` or `1` or `2`] {Automatic, Force Bilinear, Force Nearest} Default: Automatic
|
||||
* skipDrawStart [Value between `0` to `10000`] {0-10000} Default: Off (`0`)
|
||||
* skipDrawEnd [Value between `0` to `10000`] {0-10000} Default: Off (`0`)
|
||||
* halfPixelOffset [`0` or `1` or `2` or `3` or `4`] {Off, Normal Vertex, Special (Texture), Special (Texture Aggressive), Align to Native} Default: Off (`0`)
|
||||
* halfPixelOffset [`0` or `1` or `2` or `3` or `4` or `5`] {Off, Normal Vertex, Special (Texture), Special (Texture Aggressive), Align to Native, Align to Native with Texture Offsets} Default: Off (`0`)
|
||||
* nativeScaling [`0` or `1` or `2`] {Normal, Aggressive or Off} Default: Normal (`0`)
|
||||
* nativePaletteDraw [`0` or `1`] {Off, On} Default: Off (`0`)
|
||||
* roundSprite [`0` or `1` or `2`] {Off, Half or Full} Default: Off (`0`)
|
||||
|
||||
@@ -237,7 +237,7 @@
|
||||
"halfPixelOffset": {
|
||||
"type": "integer",
|
||||
"minimum": 0,
|
||||
"maximum": 4
|
||||
"maximum": 5
|
||||
},
|
||||
"nativeScaling": {
|
||||
"type": "integer",
|
||||
|
||||
@@ -212,10 +212,8 @@ bool GSHwHack::GSC_Tekken5(GSRendererHW& r, int& skip)
|
||||
{
|
||||
if (skip == 0)
|
||||
{
|
||||
if (r.IsPossibleChannelShuffle())
|
||||
if (r.IsPossibleChannelShuffle() && (RTBP0 & 31))
|
||||
{
|
||||
pxAssertMsg((RTBP0 & 31) == 0, "TEX0 should be page aligned");
|
||||
|
||||
GSVertex* v = &r.m_vertex.buff[0];
|
||||
|
||||
// Make sure we're detecting the right effect.
|
||||
|
||||
@@ -732,7 +732,7 @@ void GSRendererHW::ConvertSpriteTextureShuffle(u32& process_rg, u32& process_ba,
|
||||
GSVector4 GSRendererHW::RealignTargetTextureCoordinate(const GSTextureCache::Source* tex)
|
||||
{
|
||||
if (GSConfig.UserHacks_HalfPixelOffset <= GSHalfPixelOffset::Normal ||
|
||||
GSConfig.UserHacks_HalfPixelOffset == GSHalfPixelOffset::Native ||
|
||||
GSConfig.UserHacks_HalfPixelOffset >= GSHalfPixelOffset::Native ||
|
||||
GetUpscaleMultiplier() == 1.0f || m_downscale_source || tex->GetScale() == 1.0f)
|
||||
{
|
||||
return GSVector4(0.0f);
|
||||
@@ -5160,6 +5160,26 @@ __ri void GSRendererHW::EmulateTextureSampler(const GSTextureCache::Target* rt,
|
||||
|
||||
const GSVector4 half_pixel = RealignTargetTextureCoordinate(tex);
|
||||
m_conf.cb_vs.texture_offset = GSVector2(half_pixel.x, half_pixel.y);
|
||||
|
||||
// Can be seen with the cabin part of the ship in God of War, offsets are required when using FST.
|
||||
// ST uses a normalized position so doesn't need an offset here, will break Bionicle Heroes.
|
||||
if (GSConfig.UserHacks_HalfPixelOffset == GSHalfPixelOffset::NativeWTexOffset)
|
||||
{
|
||||
if (!m_downscale_source && tex->m_scale > 1.0f)
|
||||
{
|
||||
const GSVertex* v = &m_vertex.buff[0];
|
||||
if (PRIM->FST)
|
||||
{
|
||||
const int x1_frac = ((v[1].XYZ.X - m_context->XYOFFSET.OFX) & 0xf);
|
||||
const int y1_frac = ((v[1].XYZ.Y - m_context->XYOFFSET.OFY) & 0xf);
|
||||
|
||||
if (!(x1_frac & 8))
|
||||
m_conf.cb_vs.texture_offset.x = 6.0f + (0.25f * tex->m_scale);
|
||||
if (!(y1_frac & 8))
|
||||
m_conf.cb_vs.texture_offset.y = 6.0f + (0.25f * tex->m_scale);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (tex->m_target)
|
||||
{
|
||||
@@ -5211,6 +5231,33 @@ __ri void GSRendererHW::EmulateTextureSampler(const GSTextureCache::Target* rt,
|
||||
const GSVector4 half_pixel = RealignTargetTextureCoordinate(tex);
|
||||
m_conf.cb_vs.texture_offset = GSVector2(half_pixel.x, half_pixel.y);
|
||||
|
||||
if (GSConfig.UserHacks_HalfPixelOffset == GSHalfPixelOffset::NativeWTexOffset)
|
||||
{
|
||||
if (!m_downscale_source && tex->m_scale > 1.0f)
|
||||
{
|
||||
const GSVertex* v = &m_vertex.buff[0];
|
||||
if (PRIM->FST)
|
||||
{
|
||||
const int x1_frac = ((v[1].XYZ.X - m_context->XYOFFSET.OFX) & 0xf);
|
||||
const int y1_frac = ((v[1].XYZ.Y - m_context->XYOFFSET.OFY) & 0xf);
|
||||
|
||||
if (!(x1_frac & 8))
|
||||
m_conf.cb_vs.texture_offset.x = 6.0f + (0.25f * tex->m_scale);
|
||||
if (!(y1_frac & 8))
|
||||
m_conf.cb_vs.texture_offset.y = 6.0f + (0.25f * tex->m_scale);
|
||||
}
|
||||
else
|
||||
{
|
||||
const float tw = static_cast<float>(1 << m_cached_ctx.TEX0.TW);
|
||||
const float th = static_cast<float>(1 << m_cached_ctx.TEX0.TH);
|
||||
const float q = v[0].RGBAQ.Q;
|
||||
|
||||
m_conf.cb_vs.texture_offset.x = 0.5f * q / tw;
|
||||
m_conf.cb_vs.texture_offset.y = 0.5f * q / th;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (m_vt.m_primclass == GS_SPRITE_CLASS && GSLocalMemory::m_psm[m_cached_ctx.TEX0.PSM].pal > 0 && m_index.tail >= 4)
|
||||
{
|
||||
HandleManualDeswizzle();
|
||||
@@ -5540,7 +5587,7 @@ __ri void GSRendererHW::HandleTextureHazards(const GSTextureCache::Target* rt, c
|
||||
// When using native HPO, the top-left column/row of pixels are often not drawn. Clamp these away to avoid sampling black,
|
||||
// causing bleeding into the edges of the downsampled texture.
|
||||
const u32 downsample_factor = static_cast<u32>(src_target->GetScale());
|
||||
const GSVector2i clamp_min = (GSConfig.UserHacks_HalfPixelOffset != GSHalfPixelOffset::Native) ?
|
||||
const GSVector2i clamp_min = (GSConfig.UserHacks_HalfPixelOffset < GSHalfPixelOffset::Native) ?
|
||||
GSVector2i(0, 0) :
|
||||
GSVector2i(downsample_factor, downsample_factor);
|
||||
GSVector4i copy_rect = tmm.coverage;
|
||||
@@ -6272,7 +6319,8 @@ __ri void GSRendererHW::DrawPrims(GSTextureCache::Target* rt, GSTextureCache::Ta
|
||||
float sx, sy, ox2, oy2;
|
||||
const float ox = static_cast<float>(static_cast<int>(m_context->XYOFFSET.OFX));
|
||||
const float oy = static_cast<float>(static_cast<int>(m_context->XYOFFSET.OFY));
|
||||
if (GSConfig.UserHacks_HalfPixelOffset != GSHalfPixelOffset::Native && rtscale > 1.0f)
|
||||
|
||||
if ((GSConfig.UserHacks_HalfPixelOffset < GSHalfPixelOffset::Native || m_channel_shuffle) && rtscale > 1.0f)
|
||||
{
|
||||
sx = 2.0f * rtscale / (rtsize.x << 4);
|
||||
sy = 2.0f * rtscale / (rtsize.y << 4);
|
||||
@@ -6301,8 +6349,31 @@ __ri void GSRendererHW::DrawPrims(GSTextureCache::Target* rt, GSTextureCache::Ta
|
||||
const int unscaled_y = rt_or_ds ? rt_or_ds->GetUnscaledHeight() : 0;
|
||||
sx = 2.0f / (unscaled_x << 4);
|
||||
sy = 2.0f / (unscaled_y << 4);
|
||||
ox2 = -1.0f / unscaled_x;
|
||||
oy2 = -1.0f / unscaled_y;
|
||||
|
||||
if (GSConfig.UserHacks_HalfPixelOffset == GSHalfPixelOffset::NativeWTexOffset)
|
||||
{
|
||||
ox2 = (-1.0f / (unscaled_x * rtscale));
|
||||
oy2 = (-1.0f / (unscaled_y * rtscale));
|
||||
|
||||
// Having the vertex negatively offset is a common thing for copying sprites but this causes problems when upscaling, so we need to further adjust the offset.
|
||||
// This kinda screws things up when using ST, so let's not.
|
||||
if (m_vt.m_primclass == GS_SPRITE_CLASS && rtscale > 1.0f && (!tex || PRIM->FST))
|
||||
{
|
||||
const GSVertex* v = &m_vertex.buff[0];
|
||||
const int x1_frac = ((v[1].XYZ.X - m_context->XYOFFSET.OFX) & 0xf);
|
||||
const int y1_frac = ((v[1].XYZ.Y - m_context->XYOFFSET.OFY) & 0xf);
|
||||
if (x1_frac & 8)
|
||||
ox2 *= 1.0f + ((static_cast<float>(16 - x1_frac) / 8.0f) * rtscale);
|
||||
|
||||
if (y1_frac & 8)
|
||||
oy2 *= 1.0f + ((static_cast<float>(16 - y1_frac) / 8.0f) * rtscale);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
ox2 = -1.0f / unscaled_x;
|
||||
oy2 = -1.0f / unscaled_y;
|
||||
}
|
||||
}
|
||||
|
||||
m_conf.cb_vs.vertex_scale = GSVector2(sx, sy);
|
||||
|
||||
@@ -2132,8 +2132,8 @@ GSTextureCache::Target* GSTextureCache::LookupTarget(GIFRegTEX0 TEX0, const GSVe
|
||||
// And invalidate the target, we're drawing over it so we don't care what's there.
|
||||
// We can't do this when upscaling, because of the vertex offset, the top/left rows often aren't drawn.
|
||||
GL_INS("TC: Invalidating%s target %s[%x] because it's completely overwritten.", to_string(type),
|
||||
(scale > 1.0f && GSConfig.UserHacks_HalfPixelOffset == GSHalfPixelOffset::Native) ? "[clearing] " : "", dst->m_TEX0.TBP0);
|
||||
if (scale > 1.0f && GSConfig.UserHacks_HalfPixelOffset != GSHalfPixelOffset::Native)
|
||||
(scale > 1.0f && GSConfig.UserHacks_HalfPixelOffset >= GSHalfPixelOffset::Native) ? "[clearing] " : "", dst->m_TEX0.TBP0);
|
||||
if (scale > 1.0f && GSConfig.UserHacks_HalfPixelOffset < GSHalfPixelOffset::Native)
|
||||
{
|
||||
if (dst->m_type == RenderTarget)
|
||||
g_gs_device->ClearRenderTarget(dst->m_texture, 0);
|
||||
|
||||
@@ -593,15 +593,14 @@ void GameList::ScanDirectory(const char* path, bool recursive, bool only_cache,
|
||||
progress->PushState();
|
||||
progress->SetStatusText(fmt::format(
|
||||
recursive ? TRANSLATE_FS("GameList", "Scanning directory {} (recursively)...") :
|
||||
TRANSLATE_FS("GameList", "Scanning directory {}..."),
|
||||
path)
|
||||
.c_str());
|
||||
TRANSLATE_FS("GameList", "Scanning directory {}..."),
|
||||
path).c_str());
|
||||
|
||||
FileSystem::FindResultsArray files;
|
||||
FileSystem::FindFiles(path, "*",
|
||||
recursive ? (FILESYSTEM_FIND_FILES | FILESYSTEM_FIND_HIDDEN_FILES | FILESYSTEM_FIND_RECURSIVE) :
|
||||
(FILESYSTEM_FIND_FILES | FILESYSTEM_FIND_HIDDEN_FILES),
|
||||
&files);
|
||||
(FILESYSTEM_FIND_FILES | FILESYSTEM_FIND_HIDDEN_FILES),
|
||||
&files, progress);
|
||||
|
||||
u32 files_scanned = 0;
|
||||
progress->SetProgressRange(static_cast<u32>(files.size()));
|
||||
|
||||
@@ -237,6 +237,7 @@ namespace FullscreenUI
|
||||
static void DrawAboutWindow();
|
||||
static void OpenAboutWindow();
|
||||
static void GetStandardSelectionFooterText(SmallStringBase& dest, bool back_instead_of_cancel);
|
||||
static void ApplyConfirmSetting(const SettingsInterface* bsi = nullptr);
|
||||
|
||||
static MainWindowType s_current_main_window = MainWindowType::None;
|
||||
static PauseSubMenu s_current_pause_submenu = PauseSubMenu::None;
|
||||
@@ -570,6 +571,64 @@ void ImGuiFullscreen::GetInputDialogHelpText(SmallStringBase& dest)
|
||||
}
|
||||
}
|
||||
|
||||
void FullscreenUI::ApplyConfirmSetting(const SettingsInterface* bsi)
|
||||
{
|
||||
ImGuiIO& io = ImGui::GetIO();
|
||||
SmallString swap_mode;
|
||||
if (bsi)
|
||||
swap_mode = bsi->GetSmallStringValue("UI", "SwapOKFullscreenUI", "auto");
|
||||
else
|
||||
swap_mode = Host::GetBaseSmallStringSettingValue("UI", "SwapOKFullscreenUI", "auto");
|
||||
|
||||
if (swap_mode == "true")
|
||||
io.ConfigNavSwapGamepadButtons = true;
|
||||
else if (swap_mode == "false")
|
||||
io.ConfigNavSwapGamepadButtons = false;
|
||||
else if (swap_mode == "auto")
|
||||
{
|
||||
// Check language
|
||||
if (Host::LocaleCircleConfirm())
|
||||
{
|
||||
io.ConfigNavSwapGamepadButtons = true;
|
||||
return;
|
||||
}
|
||||
|
||||
// Check BIOS
|
||||
SmallString bios_selection;
|
||||
if (bsi)
|
||||
bios_selection = bsi->GetSmallStringValue("Filenames", "BIOS", "");
|
||||
else
|
||||
bios_selection = Host::GetBaseSmallStringSettingValue("Filenames", "BIOS", "");
|
||||
|
||||
if (bios_selection != "")
|
||||
{
|
||||
u32 bios_version, bios_region;
|
||||
std::string bios_description, bios_zone;
|
||||
if (IsBIOS(Path::Combine(EmuFolders::Bios, bios_selection).c_str(), bios_version, bios_description, bios_region, bios_zone))
|
||||
{
|
||||
// Japan, Asia, China
|
||||
if (bios_region == 0 || bios_region == 4 || bios_region == 6)
|
||||
{
|
||||
io.ConfigNavSwapGamepadButtons = true;
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// X is confirm
|
||||
io.ConfigNavSwapGamepadButtons = false;
|
||||
return;
|
||||
}
|
||||
// Invalid setting
|
||||
else
|
||||
io.ConfigNavSwapGamepadButtons = false;
|
||||
}
|
||||
|
||||
void FullscreenUI::LocaleChanged()
|
||||
{
|
||||
ApplyConfirmSetting();
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
// Main
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
@@ -584,7 +643,7 @@ bool FullscreenUI::Initialize()
|
||||
|
||||
ImGuiFullscreen::SetTheme(Host::GetBaseBoolSettingValue("UI", "UseLightFullscreenUITheme", false));
|
||||
ImGuiFullscreen::UpdateLayoutScale();
|
||||
ImGui::GetIO().ConfigNavSwapGamepadButtons = Host::GetBaseBoolSettingValue("UI", "SwapOKFullscreenUI");
|
||||
ApplyConfirmSetting();
|
||||
|
||||
if (!ImGuiManager::AddFullscreenFontsIfMissing() || !ImGuiFullscreen::Initialize("fullscreenui/placeholder.png") || !LoadResources())
|
||||
{
|
||||
@@ -649,6 +708,13 @@ void FullscreenUI::CheckForConfigChanges(const Pcsx2Config& old_config)
|
||||
});
|
||||
MTGS::WaitGS(false, false, false);
|
||||
}
|
||||
|
||||
if (old_config.FullpathToBios() != EmuConfig.FullpathToBios())
|
||||
{
|
||||
MTGS::RunOnGSThread([]() {
|
||||
ApplyConfirmSetting();
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
void FullscreenUI::OnVMStarted()
|
||||
@@ -1317,8 +1383,7 @@ void FullscreenUI::DrawLandingWindow()
|
||||
std::make_pair(ICON_PF_BUTTON_TRIANGLE, FSUI_VSTR("Game List")),
|
||||
std::make_pair(ICON_PF_BUTTON_SQUARE, FSUI_VSTR("Toggle Fullscreen")),
|
||||
std::make_pair(circleOK ? ICON_PF_BUTTON_CIRCLE : ICON_PF_BUTTON_CROSS, FSUI_VSTR("Select")),
|
||||
std::make_pair(circleOK ? ICON_PF_BUTTON_CROSS : ICON_PF_BUTTON_CIRCLE, FSUI_VSTR("Exit"))
|
||||
});
|
||||
std::make_pair(circleOK ? ICON_PF_BUTTON_CROSS : ICON_PF_BUTTON_CIRCLE, FSUI_VSTR("Exit"))});
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -1328,8 +1393,7 @@ void FullscreenUI::DrawLandingWindow()
|
||||
std::make_pair(ICON_PF_ARROW_LEFT ICON_PF_ARROW_RIGHT, FSUI_VSTR("Navigate")),
|
||||
std::make_pair(ICON_PF_SPACE, FSUI_VSTR("Game List")),
|
||||
std::make_pair(ICON_PF_ENTER, FSUI_VSTR("Select")),
|
||||
std::make_pair(ICON_PF_ESC, FSUI_VSTR("Exit"))
|
||||
});
|
||||
std::make_pair(ICON_PF_ESC, FSUI_VSTR("Exit"))});
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1440,16 +1504,14 @@ void FullscreenUI::DrawExitWindow()
|
||||
SetFullscreenFooterText(std::array{
|
||||
std::make_pair(ICON_PF_DPAD_LEFT_RIGHT, FSUI_VSTR("Navigate")),
|
||||
std::make_pair(circleOK ? ICON_PF_BUTTON_CIRCLE : ICON_PF_BUTTON_CROSS, FSUI_VSTR("Select")),
|
||||
std::make_pair(circleOK ? ICON_PF_BUTTON_CROSS : ICON_PF_BUTTON_CIRCLE, FSUI_VSTR("Back"))}
|
||||
);
|
||||
std::make_pair(circleOK ? ICON_PF_BUTTON_CROSS : ICON_PF_BUTTON_CIRCLE, FSUI_VSTR("Back"))});
|
||||
}
|
||||
else
|
||||
{
|
||||
SetFullscreenFooterText(std::array{
|
||||
std::make_pair(ICON_PF_ARROW_LEFT ICON_PF_ARROW_RIGHT, FSUI_VSTR("Navigate")),
|
||||
std::make_pair(ICON_PF_ENTER, FSUI_VSTR("Select")),
|
||||
std::make_pair(ICON_PF_ESC, FSUI_VSTR("Back"))}
|
||||
);
|
||||
std::make_pair(ICON_PF_ESC, FSUI_VSTR("Back"))});
|
||||
}
|
||||
}
|
||||
|
||||
@@ -3185,12 +3247,51 @@ void FullscreenUI::DrawInterfaceSettingsPage()
|
||||
{
|
||||
ImGuiFullscreen::SetTheme(bsi->GetBoolValue("UI", "UseLightFullscreenUITheme", false));
|
||||
}
|
||||
SmallStackString<256> SwapSummery;
|
||||
SwapSummery.format(FSUI_FSTR("Uses {} as confirm as confirm when using a controller"), ICON_PF_BUTTON_CIRCLE);
|
||||
if (DrawToggleSetting(bsi, FSUI_ICONSTR(ICON_FA_GAMEPAD, "Swap OK/Cancel in Big Picture Mode"),
|
||||
SwapSummery.c_str(), "UI", "SwapOKFullscreenUI", false))
|
||||
|
||||
// DrawStringListSetting dosn't have a callback for applying settings
|
||||
const SmallString swap_mode = bsi->GetSmallStringValue("UI", "SwapOKFullscreenUI", "auto");
|
||||
static constexpr const char* swap_names[] = {
|
||||
FSUI_NSTR("Automatic"),
|
||||
FSUI_NSTR("Enabled"),
|
||||
FSUI_NSTR("Disabled"),
|
||||
};
|
||||
static constexpr const char* swap_values[] = {
|
||||
"auto",
|
||||
"true",
|
||||
"false",
|
||||
};
|
||||
size_t swap_index = std::size(swap_values);
|
||||
for (size_t i = 0; i < std::size(swap_values); i++)
|
||||
{
|
||||
ImGui::GetIO().ConfigNavSwapGamepadButtons = bsi->GetBoolValue("UI", "SwapOKFullscreenUI", false);
|
||||
if (swap_mode == swap_values[i])
|
||||
{
|
||||
swap_index = i;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
SmallStackString<256> swap_summery;
|
||||
swap_summery.format(FSUI_FSTR("Uses {} as confirm when using a controller"), ICON_PF_BUTTON_CIRCLE);
|
||||
if (MenuButtonWithValue(FSUI_ICONSTR(ICON_FA_GAMEPAD, "Swap OK/Cancel in Big Picture Mode"), swap_summery.c_str(),
|
||||
(swap_index < std::size(swap_values)) ? Host::TranslateToCString(TR_CONTEXT, swap_names[swap_index]) : FSUI_CSTR("Unknown")))
|
||||
{
|
||||
ImGuiFullscreen::ChoiceDialogOptions cd_options;
|
||||
cd_options.reserve(std::size(swap_values));
|
||||
for (size_t i = 0; i < std::size(swap_values); i++)
|
||||
cd_options.emplace_back(Host::TranslateToString(TR_CONTEXT, swap_names[i]), i == static_cast<size_t>(swap_index));
|
||||
|
||||
OpenChoiceDialog(FSUI_ICONSTR(ICON_FA_GAMEPAD, "Swap OK/Cancel in Big Picture Mode"), false, std::move(cd_options), [](s32 index, const std::string& title, bool checked) {
|
||||
if (index >= 0)
|
||||
{
|
||||
auto lock = Host::GetSettingsLock();
|
||||
SettingsInterface* bsi = GetEditingSettingsInterface(false);
|
||||
bsi->SetStringValue("UI", "SwapOKFullscreenUI", swap_values[index]);
|
||||
SetSettingsChanged(bsi);
|
||||
ApplyConfirmSetting(bsi);
|
||||
}
|
||||
|
||||
CloseChoiceDialog();
|
||||
});
|
||||
}
|
||||
|
||||
MenuHeading(FSUI_CSTR("Game Display"));
|
||||
@@ -3306,6 +3407,7 @@ void FullscreenUI::DrawBIOSSettingsPage()
|
||||
SettingsInterface* bsi = GetEditingSettingsInterface(game_settings);
|
||||
bsi->SetStringValue("Filenames", "BIOS", values[index].c_str());
|
||||
SetSettingsChanged(bsi);
|
||||
ApplyConfirmSetting(bsi);
|
||||
CloseChoiceDialog();
|
||||
});
|
||||
}
|
||||
@@ -3824,7 +3926,8 @@ void FullscreenUI::DrawGraphicsSettingsPage(SettingsInterface* bsi, bool show_ad
|
||||
FSUI_NSTR("Normal (Vertex)"),
|
||||
FSUI_NSTR("Special (Texture)"),
|
||||
FSUI_NSTR("Special (Texture - Aggressive)"),
|
||||
FSUI_NSTR("Align To Native"),
|
||||
FSUI_NSTR("Align to Native"),
|
||||
FSUI_NSTR("Align to Native - with Texture Offset"),
|
||||
};
|
||||
static constexpr const char* s_native_scaling_options[] = {
|
||||
FSUI_NSTR("Normal (Default)"),
|
||||
@@ -3992,8 +4095,7 @@ void FullscreenUI::DrawGraphicsSettingsPage(SettingsInterface* bsi, bool show_ad
|
||||
static constexpr const char* s_gsdump_compression[] = {
|
||||
FSUI_NSTR("Uncompressed"),
|
||||
FSUI_NSTR("LZMA (xz)"),
|
||||
FSUI_NSTR("Zstandard (zst)")
|
||||
};
|
||||
FSUI_NSTR("Zstandard (zst)")};
|
||||
|
||||
if (show_advanced_settings)
|
||||
{
|
||||
@@ -4783,15 +4885,13 @@ void FullscreenUI::DrawAdvancedSettingsPage()
|
||||
FSUI_NSTR("Uncompressed"),
|
||||
FSUI_NSTR("Deflate64"),
|
||||
FSUI_NSTR("Zstandard"),
|
||||
FSUI_NSTR("LZMA2")
|
||||
};
|
||||
FSUI_NSTR("LZMA2")};
|
||||
|
||||
static constexpr const char* s_savestate_compression_ratio[] = {
|
||||
FSUI_NSTR("Low (Fast)"),
|
||||
FSUI_NSTR("Medium (Recommended)"),
|
||||
FSUI_NSTR("High"),
|
||||
FSUI_NSTR("Very High (Slow, Not Recommended)")
|
||||
};
|
||||
FSUI_NSTR("Very High (Slow, Not Recommended)")};
|
||||
|
||||
if (show_advanced_settings)
|
||||
{
|
||||
@@ -6996,7 +7096,6 @@ TRANSLATE_NOOP("FullscreenUI", "Automatically saves the emulator state when powe
|
||||
TRANSLATE_NOOP("FullscreenUI", "Creates a backup copy of a save state if it already exists when the save is created. The backup copy has a .backup suffix");
|
||||
TRANSLATE_NOOP("FullscreenUI", "Show a save state selector UI when switching slots instead of showing a notification bubble.");
|
||||
TRANSLATE_NOOP("FullscreenUI", "Uses a light coloured theme instead of the default dark theme.");
|
||||
TRANSLATE_NOOP("FullscreenUI", "Uses {} as confirm when using a controller");
|
||||
TRANSLATE_NOOP("FullscreenUI", "Game Display");
|
||||
TRANSLATE_NOOP("FullscreenUI", "Automatically switches to fullscreen mode when a game is started.");
|
||||
TRANSLATE_NOOP("FullscreenUI", "Switches between full screen and windowed when the window is double-clicked.");
|
||||
@@ -7403,6 +7502,7 @@ TRANSLATE_NOOP("FullscreenUI", "Automatic mapping completed for {}.");
|
||||
TRANSLATE_NOOP("FullscreenUI", "Automatic mapping failed for {}.");
|
||||
TRANSLATE_NOOP("FullscreenUI", "Game settings initialized with global settings for '{}'.");
|
||||
TRANSLATE_NOOP("FullscreenUI", "Game settings have been cleared for '{}'.");
|
||||
TRANSLATE_NOOP("FullscreenUI", "Uses {} as confirm when using a controller");
|
||||
TRANSLATE_NOOP("FullscreenUI", "Slot {}");
|
||||
TRANSLATE_NOOP("FullscreenUI", "{} (Current)");
|
||||
TRANSLATE_NOOP("FullscreenUI", "{} (Folder)");
|
||||
@@ -7575,7 +7675,8 @@ TRANSLATE_NOOP("FullscreenUI", "Merge Targets");
|
||||
TRANSLATE_NOOP("FullscreenUI", "Normal (Vertex)");
|
||||
TRANSLATE_NOOP("FullscreenUI", "Special (Texture)");
|
||||
TRANSLATE_NOOP("FullscreenUI", "Special (Texture - Aggressive)");
|
||||
TRANSLATE_NOOP("FullscreenUI", "Align To Native");
|
||||
TRANSLATE_NOOP("FullscreenUI", "Align to Native");
|
||||
TRANSLATE_NOOP("FullscreenUI", "Align to Native - with Texture Offset");
|
||||
TRANSLATE_NOOP("FullscreenUI", "Aggressive");
|
||||
TRANSLATE_NOOP("FullscreenUI", "Half");
|
||||
TRANSLATE_NOOP("FullscreenUI", "Force Bilinear");
|
||||
@@ -7660,6 +7761,7 @@ TRANSLATE_NOOP("FullscreenUI", "Save State On Shutdown");
|
||||
TRANSLATE_NOOP("FullscreenUI", "Create Save State Backups");
|
||||
TRANSLATE_NOOP("FullscreenUI", "Use Save State Selector");
|
||||
TRANSLATE_NOOP("FullscreenUI", "Use Light Theme");
|
||||
TRANSLATE_NOOP("FullscreenUI", "Swap OK/Cancel in Big Picture Mode");
|
||||
TRANSLATE_NOOP("FullscreenUI", "Start Fullscreen");
|
||||
TRANSLATE_NOOP("FullscreenUI", "Double-Click Toggles Fullscreen");
|
||||
TRANSLATE_NOOP("FullscreenUI", "Hide Cursor In Fullscreen");
|
||||
|
||||
@@ -32,6 +32,7 @@ namespace FullscreenUI
|
||||
void ReturnToPreviousWindow();
|
||||
void ReturnToMainWindow();
|
||||
void SetStandardSelectionFooterText(bool back_instead_of_cancel);
|
||||
void LocaleChanged();
|
||||
|
||||
void Shutdown(bool clear_state);
|
||||
void Render();
|
||||
@@ -51,4 +52,7 @@ namespace Host
|
||||
|
||||
void OnCoverDownloaderOpenRequested();
|
||||
void OnCreateMemoryCardOpenRequested();
|
||||
|
||||
/// Did Playstation in the currently selected locale use circle as confirm
|
||||
bool LocaleCircleConfirm();
|
||||
} // namespace Host
|
||||
|
||||
@@ -92,7 +92,6 @@ namespace InputManager
|
||||
static std::optional<InputBindingKey> ParseHostKeyboardKey(const std::string_view source, const std::string_view sub_binding);
|
||||
static std::optional<InputBindingKey> ParsePointerKey(const std::string_view source, const std::string_view sub_binding);
|
||||
|
||||
static std::vector<std::string_view> SplitChord(const std::string_view binding);
|
||||
static bool SplitBinding(const std::string_view binding, std::string_view* source, std::string_view* sub_binding);
|
||||
static void PrettifyInputBindingPart(const std::string_view binding, SmallString& ret, bool& changed);
|
||||
static void AddBinding(const std::string_view binding, const InputEventHandler& handler);
|
||||
@@ -752,7 +751,7 @@ void InputManager::AddPadBindings(SettingsInterface& si, u32 pad_index)
|
||||
const float sensitivity = si.GetFloatValue(section.c_str(), fmt::format("{}Scale", bi.name).c_str(), 1.0f);
|
||||
const float deadzone = si.GetFloatValue(section.c_str(), fmt::format("{}Deadzone", bi.name).c_str(), 0.0f);
|
||||
AddBindings(
|
||||
bindings, InputAxisEventHandler{[pad_index, bind_index = bi.bind_index, sensitivity, deadzone](float value) {
|
||||
bindings, InputAxisEventHandler{[pad_index, bind_index = bi.bind_index, sensitivity, deadzone](InputBindingKey key, float value) {
|
||||
Pad::SetControllerState(pad_index, bind_index, ApplySingleBindingScale(sensitivity, deadzone, value));
|
||||
}});
|
||||
}
|
||||
@@ -772,9 +771,9 @@ void InputManager::AddPadBindings(SettingsInterface& si, u32 pad_index)
|
||||
if (!bindings.empty())
|
||||
{
|
||||
const float deadzone = si.GetFloatValue(section.c_str(), fmt::format("Macro{}Deadzone", macro_button_index + 1).c_str(), 0.0f);
|
||||
AddBindings(bindings, InputAxisEventHandler{[pad_index, macro_button_index, deadzone](float value) {
|
||||
AddBindings(bindings, InputAxisEventHandler{[pad_index, macro_button_index, deadzone](InputBindingKey key, float value) {
|
||||
const bool state = (value > deadzone);
|
||||
Pad::SetMacroButtonState(pad_index, macro_button_index, state);
|
||||
Pad::SetMacroButtonState(key, pad_index, macro_button_index, state);
|
||||
}});
|
||||
}
|
||||
}
|
||||
@@ -836,7 +835,7 @@ void InputManager::AddUSBBindings(SettingsInterface& si, u32 port)
|
||||
{
|
||||
const float sensitivity = si.GetFloatValue(section.c_str(), fmt::format("{}Scale", bi.name).c_str(), 1.0f);
|
||||
const float deadzone = si.GetFloatValue(section.c_str(), fmt::format("{}Deadzone", bi.name).c_str(), 0.0f);
|
||||
AddBindings(bindings, InputAxisEventHandler{[port, bind_index = bi.bind_index, sensitivity, deadzone](float value) {
|
||||
AddBindings(bindings, InputAxisEventHandler{[port, bind_index = bi.bind_index, sensitivity, deadzone](InputBindingKey key, float value) {
|
||||
USB::SetDeviceBindValue(port, bind_index, ApplySingleBindingScale(sensitivity, deadzone, value));
|
||||
}});
|
||||
}
|
||||
@@ -977,7 +976,7 @@ bool InputManager::ProcessEvent(InputBindingKey key, float value, bool skip_butt
|
||||
if (IsAxisHandler(binding->handler))
|
||||
{
|
||||
if (value_to_pass >= 0.0f && (!skip_button_handlers || value_to_pass == 0.0f))
|
||||
std::get<InputAxisEventHandler>(binding->handler)(value_to_pass);
|
||||
std::get<InputAxisEventHandler>(binding->handler)(key, value_to_pass);
|
||||
}
|
||||
else if (binding->num_keys >= min_num_keys)
|
||||
{
|
||||
@@ -1056,7 +1055,7 @@ void InputManager::ClearBindStateFromSource(InputBindingKey key)
|
||||
if (binding->keys[i].MaskDirection() != match_key)
|
||||
continue;
|
||||
|
||||
std::get<InputAxisEventHandler>(binding->handler)(0.0f);
|
||||
std::get<InputAxisEventHandler>(binding->handler)(key, 0.0f);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -95,7 +95,7 @@ struct InputBindingKeyHash
|
||||
using InputButtonEventHandler = std::function<void(s32 value)>;
|
||||
|
||||
/// Callback types for a normalized event. Usually used for pads.
|
||||
using InputAxisEventHandler = std::function<void(float value)>;
|
||||
using InputAxisEventHandler = std::function<void(InputBindingKey key, float value)>;
|
||||
|
||||
/// Input monitoring for external access.
|
||||
struct InputInterceptHook
|
||||
@@ -211,6 +211,9 @@ namespace InputManager
|
||||
/// Represents a binding with icon fonts, if available.
|
||||
bool PrettifyInputBinding(SmallStringBase& binding);
|
||||
|
||||
/// Splits a chord into individual bindings.
|
||||
std::vector<std::string_view> SplitChord(const std::string_view binding);
|
||||
|
||||
/// Returns a list of all hotkeys.
|
||||
std::vector<const HotkeyInfo*> GetHotkeyList();
|
||||
|
||||
|
||||
@@ -28,11 +28,15 @@
|
||||
|
||||
#include <vector>
|
||||
|
||||
//Map of actively pressed keys so that chords work
|
||||
using KeyMap = std::unordered_multimap<u64, bool>;
|
||||
|
||||
namespace Pad
|
||||
{
|
||||
struct MacroButton
|
||||
{
|
||||
std::vector<u32> buttons; ///< Buttons to activate.
|
||||
KeyMap active_buttons; ///< Currently active buttons.
|
||||
float pressure; ///< Pressure to apply when macro is active.
|
||||
u16 toggle_frequency; ///< Interval at which the buttons will be toggled, if not 0.
|
||||
u16 toggle_counter; ///< When this counter reaches zero, buttons will be toggled.
|
||||
@@ -670,8 +674,12 @@ void Pad::LoadMacroButtonConfig(const SettingsInterface& si, u32 pad, const Cont
|
||||
}
|
||||
}
|
||||
|
||||
void Pad::SetMacroButtonState(u32 pad, u32 index, bool state)
|
||||
void Pad::SetMacroButtonState(InputBindingKey& key, u32 pad, u32 index, bool state)
|
||||
{
|
||||
//0 appears for some reason and breaks mb.active_buttons.size() != binding_count
|
||||
if (key.bits == 0)
|
||||
return;
|
||||
|
||||
if (pad >= Pad::NUM_CONTROLLER_PORTS || index >= NUM_MACRO_BUTTONS_PER_CONTROLLER)
|
||||
return;
|
||||
|
||||
@@ -679,6 +687,30 @@ void Pad::SetMacroButtonState(u32 pad, u32 index, bool state)
|
||||
if (mb.buttons.empty())
|
||||
return;
|
||||
|
||||
SettingsInterface& sif = *Host::GetSettingsInterface();
|
||||
std::vector<std::string> data = sif.GetStringList(fmt::format("Pad{}", pad+1).c_str(), fmt::format("Macro{}", index+1).c_str());
|
||||
size_t binding_count = 0;
|
||||
//just in case there's more than one index
|
||||
for (std::string bind : data)
|
||||
{
|
||||
binding_count += InputManager::SplitChord(bind).size();
|
||||
}
|
||||
if (mb.active_buttons.find(key.bits) != mb.active_buttons.end())
|
||||
mb.active_buttons.erase(key.bits);
|
||||
|
||||
mb.active_buttons.emplace(key.bits, state);
|
||||
|
||||
if (mb.active_buttons.size() != binding_count)
|
||||
return;
|
||||
|
||||
if (mb.active_buttons.size() > 1 && state)
|
||||
{
|
||||
for (auto it = mb.active_buttons.begin(); it != mb.active_buttons.end(); ++it)
|
||||
{
|
||||
if (!it->second)
|
||||
return;
|
||||
}
|
||||
}
|
||||
const bool trigger_state = (mb.trigger_toggle ? (state ? !mb.trigger_state : mb.trigger_state) : state);
|
||||
if (mb.trigger_state == trigger_state)
|
||||
return;
|
||||
|
||||
@@ -4,6 +4,7 @@
|
||||
#pragma once
|
||||
|
||||
#include "Config.h"
|
||||
#include "Input/InputManager.h"
|
||||
#include "SIO/Pad/PadTypes.h"
|
||||
|
||||
#include <memory>
|
||||
@@ -68,6 +69,6 @@ namespace Pad
|
||||
bool Freeze(StateWrapper& sw);
|
||||
|
||||
// Sets the state of the specified macro button.
|
||||
void SetMacroButtonState(u32 pad, u32 index, bool state);
|
||||
void SetMacroButtonState(InputBindingKey& key, u32 pad, u32 index, bool state);
|
||||
void UpdateMacroButtons();
|
||||
}; // namespace Pad
|
||||
|
||||
@@ -3610,7 +3610,7 @@ void VMManager::ReloadPINE()
|
||||
PINEServer::Deinitialize();
|
||||
|
||||
if (EmuConfig.EnablePINE)
|
||||
PINEServer::Initialize();
|
||||
PINEServer::Initialize(EmuConfig.PINESlot);
|
||||
}
|
||||
|
||||
void VMManager::InitializeDiscordPresence()
|
||||
|
||||
@@ -238,6 +238,11 @@ void Host::OnCreateMemoryCardOpenRequested()
|
||||
{
|
||||
}
|
||||
|
||||
bool Host::LocaleCircleConfirm()
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
bool Host::ShouldPreferHostFileSelector()
|
||||
{
|
||||
return false;
|
||||
|
||||
Reference in New Issue
Block a user