mirror of
https://github.com/libretro/RetroArch.git
synced 2026-11-08 08:10:30 -10:00
Compare commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
bc5d73dbdd | ||
|
|
c39cc503df | ||
|
|
5c564723df | ||
|
|
b6ca3e0e33 | ||
|
|
1b02235b8f | ||
|
|
d7c16c7b30 | ||
|
|
7a4ef581a4 | ||
|
|
ddb03333e3 | ||
|
|
e00edebc98 | ||
|
|
b2387e06bc | ||
|
|
b97644f52f | ||
|
|
a0ec6da2a8 | ||
|
|
02c77d3685 | ||
|
|
2c674ef8d1 | ||
|
|
e9cf861f7f | ||
|
|
3e6a10ffb6 | ||
|
|
3902bc19b3 | ||
|
|
10b0c2ee94 | ||
|
|
3fd10a723d | ||
|
|
f600bf437c | ||
|
|
2f8c4c10a9 | ||
|
|
502fd8ff54 | ||
|
|
6222329a7b | ||
|
|
8e37cd4d89 | ||
|
|
369e99efa8 | ||
|
|
841304619d | ||
|
|
fcdeed2a82 | ||
|
|
074ff4b2fc | ||
|
|
5f0991c052 | ||
|
|
321697f029 | ||
|
|
37140c1cd9 | ||
|
|
346745e24b | ||
|
|
4e6b50b8ee | ||
|
|
6c7e3ec571 | ||
|
|
67ffd5226a | ||
|
|
7ce9e4f9b0 | ||
|
|
f7bf8e9725 | ||
|
|
ef3adc7c42 | ||
|
|
0c4f14a14f | ||
|
|
27aa887fcb | ||
|
|
8f6c4f30c3 | ||
|
|
1597c5a2cf | ||
|
|
68af1626d9 | ||
|
|
b995f8da9f | ||
|
|
0473785f65 | ||
|
|
0555a703a7 | ||
|
|
7de2e41c32 | ||
|
|
9edeec41b7 | ||
|
|
ca2e20be84 | ||
|
|
b0cf650e97 | ||
|
|
4f662ff0e2 | ||
|
|
4bb5066691 | ||
|
|
487856c2c3 | ||
|
|
28e10c9ad4 | ||
|
|
396d57ae77 | ||
|
|
60165d4cd7 | ||
|
|
87d04b4bbd | ||
|
|
e49e23687a | ||
|
|
e0b85596f6 | ||
|
|
294e922ecc | ||
|
|
f6f101b6ab | ||
|
|
a133d2ebb5 | ||
|
|
6d1198bf55 | ||
|
|
a171f4c9fd | ||
|
|
6a48f1e187 | ||
|
|
705a0dd62e | ||
|
|
75c1e56edf | ||
|
|
82b7d4d046 | ||
|
|
472ac47344 | ||
|
|
148526a638 | ||
|
|
3e7b2b8fd4 | ||
|
|
cf77233896 | ||
|
|
b43d4a27b9 | ||
|
|
4a7f10c94a | ||
|
|
10ad19bf76 | ||
|
|
eca9b3ddc9 | ||
|
|
593376b9aa | ||
|
|
944ddc589b | ||
|
|
c4e0e45722 | ||
|
|
15b7e0fafc | ||
|
|
c9ce831e22 | ||
|
|
c1143f9e2e | ||
|
|
8889af2d19 | ||
|
|
79d508b05a | ||
|
|
70dbebcb5e | ||
|
|
232cf0d122 | ||
|
|
663bab2c14 | ||
|
|
dac3713454 | ||
|
|
c5735e0aec | ||
|
|
663268be24 | ||
|
|
7dccb123f3 | ||
|
|
ae4b8563c8 | ||
|
|
6e8e5ec89b | ||
|
|
ca9b6ac0e2 | ||
|
|
c1d8bf8bea | ||
|
|
463fdd9bdf | ||
|
|
85850ffba1 | ||
|
|
b7fce9a98e | ||
|
|
f8ad3dcc91 | ||
|
|
e871f9523f | ||
|
|
28f3e473e3 | ||
|
|
5989fa0405 | ||
|
|
ef0ab68c4b | ||
|
|
49e69a530d | ||
|
|
2d3fed35e7 | ||
|
|
fea9aa9e9c | ||
|
|
4e9a5a5360 | ||
|
|
6aa621a8f8 | ||
|
|
4ffecbb058 | ||
|
|
72310b6661 | ||
|
|
1d05161723 | ||
|
|
e88318e886 | ||
|
|
15e16728f2 | ||
|
|
b6131dfcd7 | ||
|
|
4f9b284c6d | ||
|
|
232a3850d1 | ||
|
|
0171023edc | ||
|
|
1c2c2e1a37 | ||
|
|
6ff8154d19 | ||
|
|
1f6efc65ca | ||
|
|
29ba19bc73 | ||
|
|
448bf2cdc8 | ||
|
|
e4367646c4 | ||
|
|
4c1c9cfff5 | ||
|
|
1a4c122310 | ||
|
|
336a805a5a | ||
|
|
1b01a00e3e | ||
|
|
9cd51921cb | ||
|
|
9ef37ca9d9 | ||
|
|
90d6aca1e1 | ||
|
|
f32bc9e017 | ||
|
|
754e36ea33 | ||
|
|
f3ea8aa051 | ||
|
|
dfb5678ce1 | ||
|
|
ac96bee03d | ||
|
|
d1db5abb99 | ||
|
|
d72751956e | ||
|
|
3dbc1a3e7f | ||
|
|
9aaf878908 | ||
|
|
a61e52b419 | ||
|
|
86295bf057 | ||
|
|
65b78348f0 | ||
|
|
20472ae36d | ||
|
|
b01fc8b4f7 | ||
|
|
0b729e1707 | ||
|
|
0375de48a2 | ||
|
|
e1a3bf48fd | ||
|
|
8e45e6bc4a | ||
|
|
8e17f8695e | ||
|
|
efa3bef528 | ||
|
|
7f13257d1b | ||
|
|
503f01867a | ||
|
|
ca0a5b9f76 | ||
|
|
4176ddeccc | ||
|
|
e53db23031 | ||
|
|
5d70568003 | ||
|
|
42bcc8ea59 | ||
|
|
dd101ff04a | ||
|
|
987d9c0b24 | ||
|
|
c40edf878c | ||
|
|
e34f6aa774 | ||
|
|
87e850ea08 | ||
|
|
9e50b0a8bb | ||
|
|
7ddad8ade9 | ||
|
|
7ec17f1437 | ||
|
|
f873960224 | ||
|
|
f121f8d2bc | ||
|
|
6000bd33e9 | ||
|
|
04f325dcc9 | ||
|
|
9040e3348f | ||
|
|
a10a5badcc | ||
|
|
15760c6a8b | ||
|
|
97b966ab59 | ||
|
|
8f74b1a555 | ||
|
|
7cfd0a3660 | ||
|
|
6583d8262b | ||
|
|
95a236ac61 | ||
|
|
69ffd1c7a7 | ||
|
|
426daa117c | ||
|
|
1386e2ee90 | ||
|
|
f29338580b | ||
|
|
c3cb3ba876 | ||
|
|
4fdfe6a935 | ||
|
|
a2e7805524 | ||
|
|
1e73ba4661 | ||
|
|
b2c7b766ae | ||
|
|
417cb55a6e | ||
|
|
3649376c03 | ||
|
|
f248d8b54a | ||
|
|
06bb45a856 | ||
|
|
8aafbf63b8 | ||
|
|
824d2923a5 | ||
|
|
1b4cb55846 | ||
|
|
c986eb3491 | ||
|
|
989731bbd0 | ||
|
|
1b962e1b0d | ||
|
|
83d6fd3cbb | ||
|
|
11a03290ce | ||
|
|
1bc5e338b9 | ||
|
|
0657fd8e1d | ||
|
|
cef6dcec66 | ||
|
|
45566c3663 | ||
|
|
37d3163f76 | ||
|
|
176e4b2cb3 | ||
|
|
b453bedcee | ||
|
|
802851ecf2 | ||
|
|
d2b55f38cd | ||
|
|
5185fb7baa | ||
|
|
1355f1204d | ||
|
|
d7f8f847e5 | ||
|
|
69209b5e2e | ||
|
|
3e10f615bd | ||
|
|
e8e9a71b60 | ||
|
|
f5c4a29584 | ||
|
|
f6839e58a1 | ||
|
|
03f081ace6 | ||
|
|
e7e0b9ca27 | ||
|
|
4ad1a6243e | ||
|
|
3ec196d9e2 | ||
|
|
62beb6f63d | ||
|
|
dd6ec8222f | ||
|
|
7137bfc10e | ||
|
|
2b712f5f46 | ||
|
|
6d0c569f0a | ||
|
|
56a9d359ba | ||
|
|
0a1cf3edba | ||
|
|
4e05524172 | ||
|
|
7064abded5 | ||
|
|
611dd9f34e | ||
|
|
81203de0a2 | ||
|
|
d51772dcb1 | ||
|
|
4ecdddb2cb | ||
|
|
74d12bf1a1 | ||
|
|
2103440c91 | ||
|
|
ad17453d5c | ||
|
|
025ea6608f | ||
|
|
8cb3172eea | ||
|
|
9cd3db85aa | ||
|
|
068b3b90f5 | ||
|
|
4ddc5a9912 | ||
|
|
4debf60bad | ||
|
|
bc604f5029 | ||
|
|
3878e81ce4 | ||
|
|
16e7355314 | ||
|
|
9272fdcdd6 | ||
|
|
318d7a85d6 | ||
|
|
da941b8c6c | ||
|
|
bdba331096 | ||
|
|
a9eaa86683 | ||
|
|
24d9f815ce | ||
|
|
9351ac9fd9 | ||
|
|
34553627b2 | ||
|
|
dd90a338d5 | ||
|
|
2e205f6a94 | ||
|
|
df650a5e64 | ||
|
|
ff9f07e23f | ||
|
|
be5695f802 | ||
|
|
b198fd1237 | ||
|
|
d50fb9ad06 | ||
|
|
e0f3522892 | ||
|
|
15d9af091e | ||
|
|
8f7ca9130a | ||
|
|
8e4d2f6feb | ||
|
|
0c5c3c4299 | ||
|
|
4b7b47fbf1 | ||
|
|
d40c1b3be6 | ||
|
|
549a6c1349 | ||
|
|
f73a8d9875 | ||
|
|
a5f1634dca | ||
|
|
43dbec58a3 | ||
|
|
51890d2609 | ||
|
|
3af750de3a | ||
|
|
959a0ea809 | ||
|
|
cfe5ce5286 | ||
|
|
b69ba24a05 | ||
|
|
2a704179ea | ||
|
|
5cce1f70e4 | ||
|
|
e6ef8a8682 | ||
|
|
419bfc17ef | ||
|
|
20a1d5df29 | ||
|
|
5107eb4fe3 | ||
|
|
77bfce7cc7 | ||
|
|
3c9d4cf73b | ||
|
|
1c172d7947 | ||
|
|
1e0ef3d08d | ||
|
|
81c4d29064 | ||
|
|
0b0da3c335 | ||
|
|
5cf8b6041b | ||
|
|
1a744d33d6 | ||
|
|
202ecbb701 | ||
|
|
16ef16c733 | ||
|
|
2c9eb8e840 | ||
|
|
8e85275418 | ||
|
|
7e850cd265 | ||
|
|
2453aaf513 | ||
|
|
6b6e1556f6 | ||
|
|
dbfd847a60 | ||
|
|
c26b372fa5 | ||
|
|
2f26017197 | ||
|
|
9845710e24 | ||
|
|
3db4a0da22 | ||
|
|
37bb784e70 | ||
|
|
cc95e3b66b | ||
|
|
7bcb82a25e | ||
|
|
58bf26caad | ||
|
|
5e032d2677 | ||
|
|
69496bc291 | ||
|
|
a00e8581e8 | ||
|
|
5219ecaf67 | ||
|
|
4893696e22 | ||
|
|
520f7a823a | ||
|
|
b34da9df49 | ||
|
|
676e4f6348 | ||
|
|
61d88fe42d | ||
|
|
7fa59c7f6a | ||
|
|
4514e67c6f | ||
|
|
61eb18fa8a | ||
|
|
7c462a1edc | ||
|
|
5672ac098b | ||
|
|
b93ca1653c | ||
|
|
161bed281f | ||
|
|
96fbb76345 | ||
|
|
19b2839eca | ||
|
|
959950d55e | ||
|
|
52e4f7ad58 | ||
|
|
b95b101a37 | ||
|
|
109dc7a64f | ||
|
|
ce740f8948 | ||
|
|
d000563d89 | ||
|
|
aab8fb6151 | ||
|
|
9ab51ad23a | ||
|
|
3a7ad61879 | ||
|
|
f74d5a03a9 | ||
|
|
2fb6e84018 | ||
|
|
8da73e0434 | ||
|
|
da4f176053 | ||
|
|
1eb1841c9b | ||
|
|
3851664399 | ||
|
|
c09fdcc14a | ||
|
|
3492d89147 | ||
|
|
808a7cee4a | ||
|
|
77b4b76db4 | ||
|
|
7bab422a44 | ||
|
|
9d5da1e9e0 | ||
|
|
97aba979c0 | ||
|
|
8fed2d1efb | ||
|
|
00fd46c0f6 | ||
|
|
f764808578 | ||
|
|
8e950ba5be | ||
|
|
1f10d2d18a | ||
|
|
9bd2a4256b | ||
|
|
23d05ea55d | ||
|
|
3a99b0602e | ||
|
|
3868f42687 | ||
|
|
ce7275393e | ||
|
|
6c5285c792 | ||
|
|
2f693ad7f2 | ||
|
|
0934d81a52 | ||
|
|
6824174397 | ||
|
|
d51cce764d | ||
|
|
731f3e7bba | ||
|
|
dcbd252c38 | ||
|
|
ac8ca5a526 | ||
|
|
a8af68217f | ||
|
|
f6ed5902c2 | ||
|
|
6a942e046a | ||
|
|
10c2e86d14 | ||
|
|
1cdaa652a9 | ||
|
|
48b8c78de2 | ||
|
|
17aa782223 | ||
|
|
abaa4f371d | ||
|
|
186ea8898b | ||
|
|
a725d2c506 | ||
|
|
f9ef9cd1f4 | ||
|
|
9f8f831450 | ||
|
|
7271f61da0 | ||
|
|
5932829fd8 | ||
|
|
dee9b69661 | ||
|
|
2a8ea913c0 | ||
|
|
f4f2ff386a | ||
|
|
a50a9a6ba1 | ||
|
|
6f56942d44 | ||
|
|
d95f5131c0 | ||
|
|
a853964755 | ||
|
|
fe38d090b3 | ||
|
|
3b4644cd16 | ||
|
|
00a20e80aa | ||
|
|
499a22df72 | ||
|
|
df5b772462 | ||
|
|
7273b9901d | ||
|
|
d1e7a96e2b | ||
|
|
233730d03b | ||
|
|
76493d26d4 | ||
|
|
089e97b942 | ||
|
|
80e2f61eab | ||
|
|
dd50c986ec | ||
|
|
0907eccc9c | ||
|
|
b0cc4a6f61 | ||
|
|
1bcb253ce7 | ||
|
|
1352c29f39 | ||
|
|
9be0365b0e | ||
|
|
6fb2f9b161 | ||
|
|
1193d41360 | ||
|
|
96c20550b5 | ||
|
|
ab8c3085a6 | ||
|
|
6ab12d1844 | ||
|
|
1bfba2f575 | ||
|
|
6691ca2c91 | ||
|
|
687d5a2b2b | ||
|
|
8c426ed49a | ||
|
|
10be750aa6 | ||
|
|
79737aecf3 | ||
|
|
782e8b8da9 | ||
|
|
38aa7da1ab | ||
|
|
ad03ce8b58 | ||
|
|
ccd160ac0d | ||
|
|
2ffffee571 | ||
|
|
add97b9ef5 | ||
|
|
5646140755 | ||
|
|
55d621e062 | ||
|
|
331d596940 | ||
|
|
77bab1ad2d | ||
|
|
9db2a51a81 | ||
|
|
3e2769d199 | ||
|
|
6c80cd81d0 | ||
|
|
0ec50e8bc4 | ||
|
|
9cb9597e8a | ||
|
|
49a4ba73e0 | ||
|
|
533d2683c5 | ||
|
|
cb387342ba | ||
|
|
c7e6a0de06 | ||
|
|
60cf4e569a | ||
|
|
16d123dfab | ||
|
|
d33e0250b6 | ||
|
|
24ecf1c4e5 | ||
|
|
f313d3c6bb | ||
|
|
61cea3f027 | ||
|
|
726fa479fa | ||
|
|
1cdba6b0c5 | ||
|
|
24ec735380 | ||
|
|
0f473ddc4e | ||
|
|
cd1d71120c | ||
|
|
063a736f4d | ||
|
|
cb9fa07ad9 | ||
|
|
2e92640d2b | ||
|
|
db00f689c8 | ||
|
|
867df49fcf | ||
|
|
55d09ee494 | ||
|
|
b22f122c93 | ||
|
|
eaaeda8c38 | ||
|
|
6c39e981a4 | ||
|
|
678fbaff3b | ||
|
|
5906754468 | ||
|
|
9d3d696b3e | ||
|
|
b2fcf5b281 | ||
|
|
7c5c04bf36 | ||
|
|
6c05eac2f5 | ||
|
|
a949c0ed37 | ||
|
|
0cf7e2811e | ||
|
|
1959f0d17b | ||
|
|
9f0211d9d7 | ||
|
|
0dff4dad52 | ||
|
|
ba2e913908 | ||
|
|
e3a71a8c5b | ||
|
|
0f8a47467c | ||
|
|
e012e290ae | ||
|
|
5d51942f69 | ||
|
|
cb3a65a358 | ||
|
|
cd3c9a548c | ||
|
|
9b57081097 | ||
|
|
fd5f495991 | ||
|
|
62c96ea937 | ||
|
|
9698cd7dbd | ||
|
|
84f40dab16 | ||
|
|
e18a9e1001 | ||
|
|
d617e50bbf | ||
|
|
3dee9662e2 | ||
|
|
eb59aa6028 | ||
|
|
755aeec226 | ||
|
|
29b2a560c3 | ||
|
|
da939a9986 | ||
|
|
fd44e0b9c6 | ||
|
|
ff7cbf5be2 | ||
|
|
7d2a00df4e | ||
|
|
55ddfb0dc6 | ||
|
|
113e3006fa | ||
|
|
13e22788c9 | ||
|
|
865229820a | ||
|
|
debba76dc4 | ||
|
|
163a7c2e87 | ||
|
|
fdcfd3fc71 | ||
|
|
2178a14952 | ||
|
|
34bdea0f1c | ||
|
|
2815d5f5cb | ||
|
|
562b28caa7 | ||
|
|
38a4141eef | ||
|
|
525d9b3cf5 | ||
|
|
0eb49deaa8 | ||
|
|
239e491382 | ||
|
|
ed75cb8031 | ||
|
|
ba0e7d5f2a | ||
|
|
0308d3fe2b | ||
|
|
a2013276d5 | ||
|
|
eca337ee55 | ||
|
|
996d6d25b7 | ||
|
|
35a9123bf8 | ||
|
|
5d4e32ef9d | ||
|
|
29ccd1a5a1 | ||
|
|
8ff9ae6b32 | ||
|
|
b52110f642 | ||
|
|
a7b486cef1 | ||
|
|
a33c610149 | ||
|
|
1cc8a24b3c | ||
|
|
75661e7527 | ||
|
|
765ba65188 | ||
|
|
db7be5736b | ||
|
|
23f9cf8618 | ||
|
|
cf5fb8baaa | ||
|
|
6b88330540 | ||
|
|
9653e1f028 | ||
|
|
a860a71016 | ||
|
|
07c839f003 | ||
|
|
dc1616b7ce | ||
|
|
5553774f6f | ||
|
|
eee0233abb | ||
|
|
f8509ff325 | ||
|
|
a3e504ec49 | ||
|
|
105b6dbddc | ||
|
|
24f5b2675b | ||
|
|
da075bb261 | ||
|
|
3ae401a2a4 | ||
|
|
104c92fa5d | ||
|
|
29f1138ec6 | ||
|
|
e7419d2fa5 | ||
|
|
6d0b8d1129 | ||
|
|
6332ba3025 | ||
|
|
45021bda3f | ||
|
|
64fa27cdad | ||
|
|
e75c1e9923 | ||
|
|
a63968377a | ||
|
|
066e9608a1 | ||
|
|
b273de1e99 | ||
|
|
739bbe3aa6 | ||
|
|
1ed6a622f1 | ||
|
|
5d535f6d54 | ||
|
|
c79e536b17 | ||
|
|
d73ec9b645 | ||
|
|
0726204505 | ||
|
|
a0a27658bd | ||
|
|
db6b9ba4a3 | ||
|
|
38ae16f425 | ||
|
|
a569625ce9 | ||
|
|
42b756480b | ||
|
|
4a5104bfcf | ||
|
|
6e24901d95 | ||
|
|
e5a38bbd51 | ||
|
|
7ffc9db413 | ||
|
|
63274f6f61 | ||
|
|
b907cb667a | ||
|
|
5272008f54 | ||
|
|
4e772003c8 | ||
|
|
48cddde84a | ||
|
|
acdc6179bb | ||
|
|
fadd954618 | ||
|
|
e0295a726a | ||
|
|
f442c8ab5f | ||
|
|
885c165716 | ||
|
|
bd90e1c1a3 | ||
|
|
1b995917ce | ||
|
|
4e3359ec19 | ||
|
|
8ab536a968 | ||
|
|
ca25e51812 | ||
|
|
56e5c9fcec | ||
|
|
cd0973d213 | ||
|
|
72efdbd916 | ||
|
|
13373f4873 | ||
|
|
edad44c950 | ||
|
|
6cd800f6ae | ||
|
|
0ee6aa948e | ||
|
|
7974533452 | ||
|
|
6c8dd72cd8 | ||
|
|
6b45efa7bc | ||
|
|
224db6a4c8 | ||
|
|
ef72584568 | ||
|
|
2a6551a62a | ||
|
|
9ab02b12be | ||
|
|
e6b3b96400 | ||
|
|
47dcb54c1f | ||
|
|
6cd4989651 | ||
|
|
dd9f4be2aa | ||
|
|
36885e35d7 | ||
|
|
49f27c68ff | ||
|
|
5d6c5af8be | ||
|
|
0a2b3ede59 | ||
|
|
07a4619a70 | ||
|
|
37b8585df4 | ||
|
|
71189737de | ||
|
|
8781b5c7d3 | ||
|
|
ed4a81e497 | ||
|
|
e1bbaee64c | ||
|
|
d7afd20346 | ||
|
|
fe0a6c8d07 | ||
|
|
a328bd578e | ||
|
|
7f4d701b19 | ||
|
|
06a951ef7f | ||
|
|
51b3cafed7 | ||
|
|
81988fc1ef | ||
|
|
1f00ce1812 | ||
|
|
2295c4abd8 | ||
|
|
48230ba533 | ||
|
|
4737d28644 | ||
|
|
5c4ad2884e | ||
|
|
e30966bfd0 | ||
|
|
c5d8e1a75c | ||
|
|
c2cc7a278f | ||
|
|
5cad1e4c39 | ||
|
|
8a6b628bee | ||
|
|
f78df09c38 | ||
|
|
40035908f3 | ||
|
|
b0de19f3e0 | ||
|
|
a47bcf6cc1 | ||
|
|
bc307d4b63 | ||
|
|
bdb8b3f0fe | ||
|
|
6053b61b5b | ||
|
|
7489f387c1 | ||
|
|
31be6766c6 | ||
|
|
6b552cfba1 | ||
|
|
848a67252f | ||
|
|
8d5385d1d7 | ||
|
|
7d8d8f39f7 | ||
|
|
760d3bbecf | ||
|
|
ac070a6b2b | ||
|
|
94f09d2093 | ||
|
|
b8e6443710 | ||
|
|
8823b47a05 | ||
|
|
a3351e17f1 | ||
|
|
c1544e88aa | ||
|
|
4e68eb12ab | ||
|
|
428050904c | ||
|
|
ee806a0e2c | ||
|
|
e318a1d5a7 | ||
|
|
ca0986064d | ||
|
|
057846e45b | ||
|
|
d4c1cf4853 | ||
|
|
9708536cd8 | ||
|
|
f61348e53f | ||
|
|
556e158020 | ||
|
|
d9337a2589 | ||
|
|
cc476af1fe | ||
|
|
4365b77577 | ||
|
|
f7c2bfe530 | ||
|
|
44b873af5b | ||
|
|
4ff4957a45 | ||
|
|
3239edccb9 | ||
|
|
fe0da105b5 | ||
|
|
4c361bc648 | ||
|
|
9d17ccf4f3 | ||
|
|
25a97b1d8c | ||
|
|
cd9dd6511d | ||
|
|
37c29144d8 | ||
|
|
3c2591f71f | ||
|
|
6ef7eae423 | ||
|
|
4959b8e20e | ||
|
|
7e1e293547 | ||
|
|
4bd53c0b96 | ||
|
|
47f95020f0 | ||
|
|
e4506d5a3e | ||
|
|
b612bb5290 | ||
|
|
f453ee7954 | ||
|
|
0b3f0de625 | ||
|
|
80a680a7ee | ||
|
|
762c2cb170 | ||
|
|
7b4d48a69f | ||
|
|
bd500ae249 | ||
|
|
ad5c890603 | ||
|
|
f46889daae | ||
|
|
b82d9be0ae | ||
|
|
449b08e9d5 | ||
|
|
a2fe0330eb | ||
|
|
e3c5ebd937 | ||
|
|
afdcae3ee8 | ||
|
|
d2e3d8db28 | ||
|
|
10ac66e734 | ||
|
|
5ebd0b4ed1 | ||
|
|
227ae4ca74 | ||
|
|
379614ca1c | ||
|
|
24e807f520 | ||
|
|
2463924d69 | ||
|
|
6e0da33c60 | ||
|
|
fd54b26532 | ||
|
|
ea0233716e | ||
|
|
d891230800 | ||
|
|
1bf564955c | ||
|
|
f548ebb1a2 | ||
|
|
6e1d48a625 | ||
|
|
b73d8bb569 | ||
|
|
ed5e67425c | ||
|
|
d76d8a7d9c | ||
|
|
8ef9e99960 | ||
|
|
cd08339051 | ||
|
|
85ee49b2cd | ||
|
|
5f3453bc38 | ||
|
|
d8720ab9d8 | ||
|
|
04a1388640 | ||
|
|
db87f664b8 | ||
|
|
ae5900aaa1 | ||
|
|
4b67a3c59e | ||
|
|
c6fa39fde0 | ||
|
|
051c82daed | ||
|
|
de9db9bcea | ||
|
|
9a1cf7525e | ||
|
|
90984ce3cc | ||
|
|
dc1d9b674a | ||
|
|
47c9fda3c9 | ||
|
|
452f3f4c43 | ||
|
|
6c64a024eb | ||
|
|
59dbc4727b | ||
|
|
57e17d9b14 | ||
|
|
7b0b1a7004 | ||
|
|
fd99d9f3bc | ||
|
|
1386c97ad2 | ||
|
|
9d19ef4969 | ||
|
|
ffc6fc5e24 | ||
|
|
11720b8113 | ||
|
|
308d89ead7 | ||
|
|
c5cee1f945 | ||
|
|
ee99acfd71 | ||
|
|
08414d1f5c | ||
|
|
18aebfedc2 | ||
|
|
c8173aaf62 | ||
|
|
c975145914 | ||
|
|
2fecfc7fca | ||
|
|
a4b3fbcebe | ||
|
|
f01663550c | ||
|
|
24817543e0 | ||
|
|
b50ddfc87a | ||
|
|
302dc9460f | ||
|
|
351e58b856 | ||
|
|
8aa2eb9741 | ||
|
|
90165492a1 | ||
|
|
afa6776b1d | ||
|
|
60edff831a | ||
|
|
98bd071fd3 | ||
|
|
ac5fb991a2 | ||
|
|
2e5e5f3c35 | ||
|
|
9d0a55285d | ||
|
|
9b4a91fd29 | ||
|
|
b4fe5198b3 | ||
|
|
c20df730e3 | ||
|
|
37ed625bab | ||
|
|
3446774547 | ||
|
|
a5c47a568e | ||
|
|
e70ea21a3a | ||
|
|
c310e32dd0 | ||
|
|
248f5efbd6 | ||
|
|
a03c11d7d0 | ||
|
|
2e9fade00a | ||
|
|
3dc5b21b78 | ||
|
|
dd57e0ae63 | ||
|
|
bdc8cd1cb1 | ||
|
|
cacf15a065 | ||
|
|
989962f5a9 | ||
|
|
7c15f5a537 | ||
|
|
6643bf3e1c | ||
|
|
60256eb52f | ||
|
|
74de5350d2 | ||
|
|
cd54cc6822 | ||
|
|
2fba62867f | ||
|
|
5f330cbfa5 | ||
|
|
9bad6f2bba | ||
|
|
0496ffc007 | ||
|
|
bb824b5679 | ||
|
|
1ea4b5ce7c | ||
|
|
f5a4ea55f5 | ||
|
|
aecd9a1ecb | ||
|
|
a797e1dbf4 | ||
|
|
9c664b875a | ||
|
|
375d05ed13 | ||
|
|
a13684c80c | ||
|
|
678269039b | ||
|
|
ece5935ef9 | ||
|
|
341baf6918 | ||
|
|
4acf66edfd | ||
|
|
10cfe3daa8 | ||
|
|
be3839a9df | ||
|
|
0023b4b2ce | ||
|
|
17e0f19859 | ||
|
|
383b2abe58 | ||
|
|
5ce54cbbab | ||
|
|
2c2dcd58f2 | ||
|
|
ee76898cab | ||
|
|
a41e84749a | ||
|
|
d68658b7fb | ||
|
|
c833a71d2c | ||
|
|
f1b135978c | ||
|
|
6f04c38fda | ||
|
|
cc979581eb | ||
|
|
fe0ce2b78b | ||
|
|
b8382416ee | ||
|
|
9bcbd27988 | ||
|
|
3845844b83 | ||
|
|
d7a29a66b4 | ||
|
|
6a7144d41c | ||
|
|
12cf639dfe | ||
|
|
4604a995e9 | ||
|
|
0b9ee6055f | ||
|
|
acd51a7dad | ||
|
|
6d98da16b0 | ||
|
|
3407e765c3 | ||
|
|
2ef54a7e01 | ||
|
|
aac2533075 | ||
|
|
fd2be071f8 | ||
|
|
947d2a3514 | ||
|
|
3fd630e062 | ||
|
|
471dfcd478 | ||
|
|
8e8f56b5e8 | ||
|
|
744a433595 | ||
|
|
f9ab3711eb | ||
|
|
96cb22dbaa | ||
|
|
f2f09ce2ed | ||
|
|
6d1ab7ebfd | ||
|
|
356d565ce6 | ||
|
|
8ec0cb4f6c | ||
|
|
fd9f020afa | ||
|
|
52402d02c5 | ||
|
|
1373ba167d | ||
|
|
668aa9a9ac | ||
|
|
3585e046de | ||
|
|
2760b5b0c2 | ||
|
|
441cd2b82a | ||
|
|
fe2134cb8c | ||
|
|
04e2541694 | ||
|
|
878e612584 | ||
|
|
8dcf132b0c | ||
|
|
da7cf7e01d | ||
|
|
317f255eae | ||
|
|
b87e1c4f48 | ||
|
|
3cc042e2a6 | ||
|
|
2cb946ec8b | ||
|
|
8459f39933 | ||
|
|
56e57d15bc | ||
|
|
975536ddbf | ||
|
|
df997f6d23 | ||
|
|
cb3064201e | ||
|
|
48d589ffce | ||
|
|
16c740ffd8 | ||
|
|
80372f54a6 | ||
|
|
a6a068e09e | ||
|
|
227f347e70 | ||
|
|
438ac4ca4b | ||
|
|
69a5faaaab | ||
|
|
1b28ea4945 | ||
|
|
55a400f521 | ||
|
|
d77560f1ea | ||
|
|
786adb23ac | ||
|
|
a03dd57166 | ||
|
|
bb642d3010 | ||
|
|
21e39eea2b | ||
|
|
761f5d7a5c | ||
|
|
e0408c30ae | ||
|
|
78136e0191 | ||
|
|
77e55bb577 | ||
|
|
89b99428f9 | ||
|
|
beeb660103 | ||
|
|
9969474326 | ||
|
|
1307648d08 | ||
|
|
eeafd335fa | ||
|
|
32a52f5d01 | ||
|
|
08f3313a3b | ||
|
|
98f30469eb | ||
|
|
36309050c4 | ||
|
|
5a3b88bdd6 | ||
|
|
000d863ae0 | ||
|
|
38d73e9da2 | ||
|
|
5f649bf2be | ||
|
|
9609eca940 | ||
|
|
5f71f48973 | ||
|
|
5aa6acf031 | ||
|
|
ccfa448a66 | ||
|
|
1090eeb159 | ||
|
|
3a66829933 | ||
|
|
045e72661a | ||
|
|
b9ef2ff133 | ||
|
|
80136435d2 | ||
|
|
9c861f13be | ||
|
|
1cff87c758 | ||
|
|
ffc0c1d77e | ||
|
|
2148ce9dec | ||
|
|
390628b1e3 | ||
|
|
6e753d7d99 | ||
|
|
c07bcbea53 | ||
|
|
c0cba36dec | ||
|
|
34b85e115b | ||
|
|
40c3158d7e | ||
|
|
64728e38a4 | ||
|
|
979b54178e | ||
|
|
3a33c5e1ec | ||
|
|
aeeb491a49 | ||
|
|
38fb6f0a62 | ||
|
|
b094151abb | ||
|
|
e5e19edc65 | ||
|
|
2cd7349cac | ||
|
|
dc1a32f7f7 | ||
|
|
315b28862a | ||
|
|
f6edb9a607 | ||
|
|
93072b926e | ||
|
|
c161e3bc35 | ||
|
|
3bda32d6f1 | ||
|
|
fea632b0e9 | ||
|
|
d959bc968a | ||
|
|
e33221b52a | ||
|
|
c32d321b06 | ||
|
|
18d6d58a2b | ||
|
|
996794134f | ||
|
|
02996fbe2e | ||
|
|
e85471a239 | ||
|
|
0e2de25f85 | ||
|
|
402be572ea | ||
|
|
1317ce1aea | ||
|
|
884e39c58d | ||
|
|
0bb0b96623 | ||
|
|
61c1b2bb1b | ||
|
|
979b7e6479 | ||
|
|
862082915b | ||
|
|
fba6f36cb8 | ||
|
|
0cb2436a59 | ||
|
|
18c259e19a | ||
|
|
e3a2ab0347 | ||
|
|
15bc0e0813 | ||
|
|
a328dbd213 | ||
|
|
09a6566be0 | ||
|
|
3eaa942e58 | ||
|
|
40ce42c87c | ||
|
|
a14bdb82b1 | ||
|
|
ee5d43486c | ||
|
|
02c3977e9d | ||
|
|
a509d40bf6 | ||
|
|
4501832997 | ||
|
|
56e862edf8 | ||
|
|
945a086edf | ||
|
|
72f5748b28 | ||
|
|
79f29a3966 | ||
|
|
6843514f86 | ||
|
|
ff6b9bd0bf | ||
|
|
3576613f52 | ||
|
|
02cfa3f651 | ||
|
|
87a0d3f413 | ||
|
|
407205a4e5 | ||
|
|
6f368200b9 | ||
|
|
f669f02407 | ||
|
|
e7d3e524bb | ||
|
|
d3d97bf11e | ||
|
|
766bdf727c | ||
|
|
f2264ebb3e | ||
|
|
2c61f2b1e7 | ||
|
|
cab8fd2a80 | ||
|
|
56a1877d15 | ||
|
|
3096e154c9 | ||
|
|
accb011196 | ||
|
|
93068a376a | ||
|
|
5be17933e9 | ||
|
|
f4183d2c8f | ||
|
|
576855de4f | ||
|
|
35b386df0d | ||
|
|
2702299e7b | ||
|
|
65e4357af7 | ||
|
|
904cdd3fb4 | ||
|
|
e48ec1ea20 | ||
|
|
467023692f | ||
|
|
b861c11253 | ||
|
|
e538fe4364 | ||
|
|
e0aa65efc3 | ||
|
|
c569d9e179 | ||
|
|
ef280919d3 | ||
|
|
734afe2058 | ||
|
|
b4e3786aa1 | ||
|
|
feec19940a | ||
|
|
ec97970206 | ||
|
|
4a9e7f7b7e | ||
|
|
73fa4ea199 | ||
|
|
ce08251f53 | ||
|
|
bbd6e16bbe | ||
|
|
959411c094 | ||
|
|
a64ae92d9d | ||
|
|
bad72987d0 | ||
|
|
8deab9ea35 | ||
|
|
35e5f2dbc6 | ||
|
|
cd11f65956 | ||
|
|
08686bcd06 | ||
|
|
5b0a948797 | ||
|
|
b060c71de4 | ||
|
|
fac78083ca | ||
|
|
230f47d00c | ||
|
|
1cfc4c6cc0 | ||
|
|
f89060e7ff | ||
|
|
16faee9ae2 | ||
|
|
352b8e4cef | ||
|
|
2c40567030 | ||
|
|
ac3f80d738 | ||
|
|
2721ccb52a | ||
|
|
0fc36bfe0a | ||
|
|
559fc5b67f | ||
|
|
bd15206599 | ||
|
|
e5d3894bc4 | ||
|
|
0bc0ae40a5 | ||
|
|
3c15bb06db | ||
|
|
9ce3331f04 | ||
|
|
9508cc4eb3 | ||
|
|
0bb1f7292c | ||
|
|
b56b09af35 | ||
|
|
a685701805 | ||
|
|
d207eb0b1e | ||
|
|
e8b2cde4cf | ||
|
|
bedd5a691b | ||
|
|
57fbad1a54 | ||
|
|
12deb9c54a | ||
|
|
8b1be981d3 | ||
|
|
30d229c30b | ||
|
|
f3d9588e37 | ||
|
|
b5f77bf65e | ||
|
|
5bfc7be450 | ||
|
|
fcab353201 | ||
|
|
e968d26ba8 | ||
|
|
db1765e788 | ||
|
|
6e4277d9a6 | ||
|
|
be56e901bb | ||
|
|
f803b5fbd3 | ||
|
|
be62e537c6 | ||
|
|
7af7d55068 | ||
|
|
15c5c69241 | ||
|
|
b89554d11a | ||
|
|
60760d69db | ||
|
|
ab687190a9 | ||
|
|
a07514c88b | ||
|
|
f9de1a8831 | ||
|
|
badf807ae9 | ||
|
|
36e2b51827 | ||
|
|
afae4a5cb4 | ||
|
|
e9fb18f594 | ||
|
|
a061fa081c | ||
|
|
88b819ffff | ||
|
|
730fb03c07 | ||
|
|
a571cf5e92 | ||
|
|
7ce5733a45 | ||
|
|
e73df5e6a9 | ||
|
|
c2cb9fead0 | ||
|
|
01fb168f51 | ||
|
|
f16b269685 | ||
|
|
1bfabea14a | ||
|
|
1160aeed3d | ||
|
|
61019ac48c | ||
|
|
4642e0ce96 | ||
|
|
0a81b47932 | ||
|
|
0faa8c3855 | ||
|
|
388e2bb5fc | ||
|
|
14ffd07b70 | ||
|
|
9cb5eea20b | ||
|
|
be03b8ac95 | ||
|
|
b9ce2d4142 | ||
|
|
422c13242f | ||
|
|
9e917d4835 | ||
|
|
1cc8a8a121 | ||
|
|
05e49db12a | ||
|
|
2acc30e1a4 | ||
|
|
dd1d83768b | ||
|
|
1451ba9610 | ||
|
|
3d8c50a768 | ||
|
|
f5f8a71af2 | ||
|
|
5368d0d148 | ||
|
|
c9fc51fe2a | ||
|
|
0e5a9a7772 | ||
|
|
6ff762f088 | ||
|
|
bda70a9168 | ||
|
|
03a892c7f2 | ||
|
|
e6f2aa81f7 | ||
|
|
42b101b024 | ||
|
|
38845d6ad5 | ||
|
|
a5db76d7db | ||
|
|
5181463606 | ||
|
|
a9ffab7854 | ||
|
|
2797ec3a79 | ||
|
|
8c672bc613 | ||
|
|
458abe3611 | ||
|
|
08a9525508 | ||
|
|
730983bf59 | ||
|
|
c7692e7a72 | ||
|
|
8da940d0e5 | ||
|
|
05607880f8 | ||
|
|
94ff302111 | ||
|
|
aa32810151 | ||
|
|
6614e4ef92 | ||
|
|
7374480126 | ||
|
|
d5dc910e5b | ||
|
|
367d554fff | ||
|
|
ea49b02380 | ||
|
|
b0ddf78db0 | ||
|
|
d4d97bfae1 | ||
|
|
5706713905 | ||
|
|
2fd7c1bb9f | ||
|
|
e46f09c3b1 | ||
|
|
a4dd8bdf30 | ||
|
|
2be040a8a7 | ||
|
|
e14f5e9ea5 | ||
|
|
f9870dfb24 | ||
|
|
ec5612a12b | ||
|
|
d12532aef1 | ||
|
|
7082561e21 | ||
|
|
763f257d92 | ||
|
|
d55c86bc41 | ||
|
|
3695cf78b9 | ||
|
|
26cb567bb9 | ||
|
|
fabceb0e84 | ||
|
|
0a3dc05c27 | ||
|
|
8f0a47e6c3 | ||
|
|
20528b9d1f | ||
|
|
d262049f6b | ||
|
|
75408b689d | ||
|
|
d551d93ce4 | ||
|
|
99f622de0e | ||
|
|
64cbfd0183 | ||
|
|
64de1a3260 | ||
|
|
4d95765cb5 | ||
|
|
e90b7e6a03 | ||
|
|
e044275c3e | ||
|
|
c5e8eb0283 | ||
|
|
8e74333ef4 | ||
|
|
2089521856 | ||
|
|
057d29bea1 | ||
|
|
026fd10bd4 | ||
|
|
c492195ab1 | ||
|
|
d9a72ea076 | ||
|
|
955c0e85c8 | ||
|
|
3c99021b60 | ||
|
|
5453cc0448 | ||
|
|
c7e32cbbd2 | ||
|
|
5edf67bba8 | ||
|
|
d109c22b49 | ||
|
|
98f2f1c23d | ||
|
|
94bc6ff3a2 | ||
|
|
62dc63542c | ||
|
|
dd8acd5872 | ||
|
|
d1113a5af0 | ||
|
|
024e10b5a9 | ||
|
|
c4b2492872 | ||
|
|
44bc9fe291 | ||
|
|
ee7bacd2bc | ||
|
|
90a2070718 | ||
|
|
abf34c06c1 | ||
|
|
661836fd77 | ||
|
|
260f3ac7ce | ||
|
|
f57ab1ccd8 | ||
|
|
ef206b3a27 | ||
|
|
2dce493240 | ||
|
|
83c3d7be57 | ||
|
|
7b0e1e8022 | ||
|
|
86950b4d2a | ||
|
|
fe02783fc7 | ||
|
|
072406e3c3 | ||
|
|
751761d99c | ||
|
|
fe993fafd5 | ||
|
|
057785539b | ||
|
|
048d2f65e0 | ||
|
|
c305f4347d | ||
|
|
3ca62fbbbc | ||
|
|
225699f545 | ||
|
|
35ae61fbc7 | ||
|
|
86dac8c979 | ||
|
|
95431414ae | ||
|
|
b3f7224ea1 | ||
|
|
e583546778 | ||
|
|
a39c37e1ee | ||
|
|
67fb35b645 | ||
|
|
3c1e4c879a | ||
|
|
83a11be669 | ||
|
|
08e35a62d4 | ||
|
|
5461c0d86e | ||
|
|
4eab7c4387 | ||
|
|
59aeb77744 | ||
|
|
c6fc8e45ff | ||
|
|
4dde927c12 | ||
|
|
6325b4cd2e | ||
|
|
4beec3870f | ||
|
|
36a2c96cb7 | ||
|
|
a4a68a2ad5 | ||
|
|
13a2010ed6 | ||
|
|
e37fd21424 | ||
|
|
a2698061a6 | ||
|
|
d00257382a | ||
|
|
51ab2f2509 | ||
|
|
61f9ceccab | ||
|
|
f836a291a0 | ||
|
|
97725e69eb | ||
|
|
d186e14eeb | ||
|
|
08aaa1021c | ||
|
|
b4248038fb | ||
|
|
ca587ab92e | ||
|
|
6f5c33848e | ||
|
|
17d380400e | ||
|
|
2e456b2570 | ||
|
|
fe17a42e62 | ||
|
|
c46866c6e5 | ||
|
|
3117633adf | ||
|
|
8a49321648 | ||
|
|
18f027ed41 | ||
|
|
79b9c68cb5 | ||
|
|
2b1344c3cf | ||
|
|
da26925118 | ||
|
|
f2a152f7c9 | ||
|
|
1953ea7312 | ||
|
|
e55dbe944d | ||
|
|
f5ad906e7b | ||
|
|
7cad2bcd6e | ||
|
|
cc921f25ed | ||
|
|
435109ceae | ||
|
|
ca375f65d5 | ||
|
|
76212f47bf | ||
|
|
6efb904919 | ||
|
|
072342cdab | ||
|
|
09761c0786 | ||
|
|
c48fab00e8 | ||
|
|
d1c562ce4e | ||
|
|
45cae81d51 | ||
|
|
30e28acfb3 | ||
|
|
00459365c4 | ||
|
|
649884bc05 | ||
|
|
e1af420b2d | ||
|
|
613f50dd14 | ||
|
|
a18c0b2b14 | ||
|
|
d7f8500b3a | ||
|
|
7ecf9681c5 | ||
|
|
e9ca7acce9 | ||
|
|
ea68de8070 | ||
|
|
0fa0bfeb74 | ||
|
|
4a5d0d8dfb | ||
|
|
af35a18515 | ||
|
|
5560babc11 | ||
|
|
3e76201d80 | ||
|
|
5b15d8626c | ||
|
|
f8a03a7d5d | ||
|
|
b7b9acb336 | ||
|
|
44e2d66cf5 | ||
|
|
9747767474 | ||
|
|
cee33327f8 | ||
|
|
f70b52a0df | ||
|
|
0b62771b54 | ||
|
|
b168109672 | ||
|
|
d8b6aebe9a | ||
|
|
4812b632c3 | ||
|
|
8320d0a0e9 | ||
|
|
a287ebe736 | ||
|
|
ebea0220cd | ||
|
|
2b01f36fc0 | ||
|
|
7e3092dc93 | ||
|
|
114c723d59 | ||
|
|
da39f8d3d6 | ||
|
|
33b76628aa | ||
|
|
94162f452d | ||
|
|
318d875981 | ||
|
|
520878272c | ||
|
|
fc87336c45 | ||
|
|
d66e039536 | ||
|
|
eeebc2d06b | ||
|
|
7d1ebdf94a | ||
|
|
3d1b0ef35b | ||
|
|
c2ba0d474c | ||
|
|
793c00e614 | ||
|
|
d4093dc31c | ||
|
|
bc66841a29 | ||
|
|
f4cc8a4bca | ||
|
|
539563f0f4 | ||
|
|
8c5d86a6eb | ||
|
|
884c113645 | ||
|
|
70587bc0df | ||
|
|
df4e0bb1e4 | ||
|
|
cdc92af959 | ||
|
|
763a5bf2c0 | ||
|
|
8301cf8a2f | ||
|
|
44da8a6749 | ||
|
|
06309ba1e0 | ||
|
|
004ca0fe89 | ||
|
|
40cce7c9d6 | ||
|
|
1c29d31859 | ||
|
|
d3af29fa1f | ||
|
|
c5d1fd32d5 | ||
|
|
a4767d3d43 | ||
|
|
c26f527c20 | ||
|
|
0c8d85d589 | ||
|
|
0c16e1a134 | ||
|
|
0a887395eb | ||
|
|
9118976c49 | ||
|
|
7f1e599186 | ||
|
|
672102d377 | ||
|
|
fe7f05e717 | ||
|
|
0724ab2ca1 | ||
|
|
c272ba56ad | ||
|
|
381498e945 | ||
|
|
70f07196ea | ||
|
|
c8dee57278 | ||
|
|
0ab305156b | ||
|
|
eac468ba19 | ||
|
|
18f407110b | ||
|
|
ceee10b56c | ||
|
|
9805bcc5f9 | ||
|
|
d5fca50a2f | ||
|
|
4ca72bd7e6 | ||
|
|
62ead00f0f | ||
|
|
5dc573ed38 | ||
|
|
fa053ffc2b | ||
|
|
be6c7bad24 | ||
|
|
2680971bb3 | ||
|
|
630f19f248 | ||
|
|
ef4bee2e4e | ||
|
|
f182a2ad24 | ||
|
|
3eb98951f7 | ||
|
|
f9d4bbf4d3 | ||
|
|
eff4fcecae | ||
|
|
cbfdc9cf97 | ||
|
|
034c7c70fb | ||
|
|
44ad016b91 | ||
|
|
5ed0d00249 | ||
|
|
6336fb4a1b | ||
|
|
99497e21cf | ||
|
|
0181d97cae | ||
|
|
968c73a748 | ||
|
|
13f9e94f61 | ||
|
|
8c1018d573 | ||
|
|
d4d00a35d7 | ||
|
|
e3177fd489 | ||
|
|
dd1300f1cc | ||
|
|
7f03af2b2b | ||
|
|
f431f77834 | ||
|
|
7c28a62b40 | ||
|
|
a360042f77 | ||
|
|
82af27cf33 | ||
|
|
0b78abb31d | ||
|
|
2fd8ffbf22 | ||
|
|
83f7be0cbb | ||
|
|
7f5db4d70f | ||
|
|
4f04c1288b | ||
|
|
8a2c5bf9e1 | ||
|
|
5c05e309c1 | ||
|
|
bd147270eb | ||
|
|
528cf8d472 | ||
|
|
0fce2f409f | ||
|
|
fd7b0b05b8 | ||
|
|
9abc7c00c9 | ||
|
|
ebc5f433cd | ||
|
|
aa4f79f236 | ||
|
|
62f5c53b72 | ||
|
|
534163a57f | ||
|
|
325a9fb48e | ||
|
|
ee43531a99 | ||
|
|
757fa71469 | ||
|
|
bfee7986bd | ||
|
|
9aaad17c1a | ||
|
|
93874bba83 | ||
|
|
9c67452f10 | ||
|
|
0416a2ae61 | ||
|
|
8bbde14019 | ||
|
|
0e8f2339d8 | ||
|
|
9f37427d7a | ||
|
|
6ad4b1f15a | ||
|
|
a39c0f01f9 | ||
|
|
1136820124 | ||
|
|
2a3f3bad23 | ||
|
|
74def91a53 | ||
|
|
bc62e1be08 | ||
|
|
25aea134ef | ||
|
|
e488c3081d | ||
|
|
331f46fb24 | ||
|
|
e88662cab0 | ||
|
|
395f6d1d3c | ||
|
|
94bd78b3e1 | ||
|
|
dc373fb7d0 | ||
|
|
140812d64a | ||
|
|
a91c4e556f | ||
|
|
372c622166 | ||
|
|
d961d68e9c | ||
|
|
33a325a730 | ||
|
|
909b25c7ac | ||
|
|
77f110c23e | ||
|
|
9dc9416ef9 | ||
|
|
0b20f11617 | ||
|
|
c9594776f8 | ||
|
|
8f55b9904d | ||
|
|
093ba1c33d | ||
|
|
67a434d563 | ||
|
|
ff0c3f047a | ||
|
|
2934ba301b | ||
|
|
f3627aaf59 | ||
|
|
dc8a2dea72 | ||
|
|
329969eb05 | ||
|
|
71923af675 | ||
|
|
18e58ca5f4 | ||
|
|
8c3aebbbc8 | ||
|
|
7f40c11eb7 | ||
|
|
0ed668d1b5 | ||
|
|
1c8632cac9 | ||
|
|
e7324989fc | ||
|
|
a7fc3807b9 | ||
|
|
99ad7bcc51 | ||
|
|
5b88e338df | ||
|
|
425af71450 | ||
|
|
19c5eab07a | ||
|
|
e5286cbe39 | ||
|
|
02d40aa212 | ||
|
|
8a5c537e15 | ||
|
|
c6c4f2f4d1 | ||
|
|
5bc7ea4045 | ||
|
|
077acf7894 | ||
|
|
c5f86f12c0 | ||
|
|
243e941d81 | ||
|
|
d67e6b7c15 | ||
|
|
f76bf59fed | ||
|
|
1c4d88eb04 | ||
|
|
ad04db8365 | ||
|
|
a63ccbbdab | ||
|
|
278f314c03 | ||
|
|
a3abda7e7b | ||
|
|
c0a9db111d | ||
|
|
676ce10119 | ||
|
|
c18dce4783 | ||
|
|
088b01b52e | ||
|
|
c0f436b8ab | ||
|
|
3377020242 | ||
|
|
6db58fe1dd | ||
|
|
67c7cd8de9 | ||
|
|
457a3d458a | ||
|
|
6538312d86 | ||
|
|
7f1a5075b1 | ||
|
|
e412ecdefe | ||
|
|
67b89d6f42 | ||
|
|
c8d3278dbc | ||
|
|
3556445660 | ||
|
|
f28fc0cabb | ||
|
|
e0bc548400 | ||
|
|
011a4c8a89 | ||
|
|
87bc5220eb | ||
|
|
673d0ed1a2 | ||
|
|
a5079bdda1 | ||
|
|
fc43e7155e | ||
|
|
4935333b63 | ||
|
|
5a3232adff | ||
|
|
d03f351f33 | ||
|
|
8d5bf997a9 | ||
|
|
0738480439 | ||
|
|
9a5e1a31ad | ||
|
|
5ab7664f49 | ||
|
|
1cb2c60ccc | ||
|
|
1356d0ab4c | ||
|
|
b4c4a65f2d | ||
|
|
ab3cf8daca | ||
|
|
2b6c252747 | ||
|
|
ec9a6ac90a | ||
|
|
a207549f18 | ||
|
|
efbf9354f9 | ||
|
|
216ddc9fd6 | ||
|
|
3b668cccd3 | ||
|
|
30a86a2845 | ||
|
|
a7870aa888 | ||
|
|
271b99981c | ||
|
|
08ef01bb13 | ||
|
|
e778af462a | ||
|
|
9d124b2380 | ||
|
|
f24e7cd665 | ||
|
|
e7f1526942 | ||
|
|
647b1ba53c | ||
|
|
eac8d9f191 | ||
|
|
50babe8432 | ||
|
|
8171977ed7 | ||
|
|
f8aaf1df1e | ||
|
|
04d0d84d01 | ||
|
|
f4aa9fa865 | ||
|
|
40ef7d6f00 | ||
|
|
66b7b1691c | ||
|
|
43972d4c35 | ||
|
|
632545c409 | ||
|
|
3a47e2cd63 | ||
|
|
a221e3e4cd | ||
|
|
b87f50dc9d | ||
|
|
a5b3f421d1 | ||
|
|
182525afa9 | ||
|
|
419afbcb83 | ||
|
|
12ca70a308 | ||
|
|
1fa7663d3b | ||
|
|
2e34c6fc5c | ||
|
|
cb7002559d | ||
|
|
36ec92793f | ||
|
|
4187d70b30 | ||
|
|
5969655c3c | ||
|
|
09d2ec7d3a | ||
|
|
27b975d0fc | ||
|
|
6da64013fa | ||
|
|
d8eb5de380 | ||
|
|
23aa8bbe7a | ||
|
|
3b5472dbac | ||
|
|
3b4e60aada | ||
|
|
8d8fb44c18 | ||
|
|
b46fb60a6e | ||
|
|
f7399bbc8b | ||
|
|
7f7d47b120 | ||
|
|
e7aa3ed0cc | ||
|
|
0ece8b1319 | ||
|
|
557e05dd12 | ||
|
|
08a1496501 | ||
|
|
5a24037c61 | ||
|
|
5dbd1ea35c | ||
|
|
2476e3dee3 | ||
|
|
c05a5c9fdd | ||
|
|
503c51d633 | ||
|
|
46054de4f8 | ||
|
|
604eb9b973 | ||
|
|
0e72120bdc | ||
|
|
b8064f5d42 | ||
|
|
379b14a0f3 | ||
|
|
2a598c0b97 | ||
|
|
aa124b4c40 | ||
|
|
bb5e31df0d | ||
|
|
e49d216884 | ||
|
|
598d06fcb5 | ||
|
|
7f13ec88e6 | ||
|
|
c5c60c6f53 | ||
|
|
81b0e6d0a3 | ||
|
|
da97b29d0b | ||
|
|
69b7f92285 | ||
|
|
3a9dbbc8b7 | ||
|
|
bf5db10459 | ||
|
|
4fa27a5f0f | ||
|
|
3e7c412738 | ||
|
|
88c870dcfa | ||
|
|
66e1179503 | ||
|
|
4ecea5d0a4 | ||
|
|
57816edfd3 | ||
|
|
17cf0985c5 | ||
|
|
776b0a1e2d | ||
|
|
4a6392aefa | ||
|
|
29dd4727b8 | ||
|
|
face42a888 | ||
|
|
45fa6795c3 | ||
|
|
a9d339efb4 | ||
|
|
60841b01a5 | ||
|
|
ad67511483 | ||
|
|
104fb4fb16 | ||
|
|
816ef095ed | ||
|
|
48e8472f9c | ||
|
|
1755500b19 | ||
|
|
4bfc827eb2 | ||
|
|
ddfeacbd83 | ||
|
|
79353f861c | ||
|
|
f3f4efe304 | ||
|
|
51721b4cb6 | ||
|
|
477091ce8f | ||
|
|
2707b87767 | ||
|
|
b3d422b5cd | ||
|
|
d1dc65f202 | ||
|
|
7815940a97 | ||
|
|
4f841c208d | ||
|
|
b4f0d9b8f8 | ||
|
|
b96ab2982c | ||
|
|
825c1de7d1 | ||
|
|
6ada4d87d3 | ||
|
|
53abc92322 | ||
|
|
a816082ac3 | ||
|
|
47e63f1c6b | ||
|
|
cdf3d05c8e | ||
|
|
389e9ba0dc | ||
|
|
a6f7a2311f | ||
|
|
f19d99d523 | ||
|
|
e7082fd6ea | ||
|
|
4806d2fe88 | ||
|
|
f85ff7124b | ||
|
|
0f010cf3d2 | ||
|
|
95636d4f04 | ||
|
|
43905e410e | ||
|
|
d23a7e3ddf | ||
|
|
652f4c5856 | ||
|
|
90febc4ecf | ||
|
|
34b5994842 | ||
|
|
0c3f6ed66b | ||
|
|
f3e487557e | ||
|
|
ee12266a2b | ||
|
|
1981b14de9 | ||
|
|
65665f36cc | ||
|
|
a48dc55c41 | ||
|
|
202a458524 | ||
|
|
b4de704a09 | ||
|
|
fef5edfac8 | ||
|
|
a6e74775b1 | ||
|
|
ee66a28d05 | ||
|
|
5e28d82af2 | ||
|
|
c2a06bfa09 | ||
|
|
66510e21aa | ||
|
|
ec5e3355b9 | ||
|
|
0522a2d6a0 | ||
|
|
fad89f9d2d | ||
|
|
97f937ec6d | ||
|
|
9647006a2b | ||
|
|
418ba455f8 | ||
|
|
197d62860b | ||
|
|
402451626f | ||
|
|
3739cbfc70 | ||
|
|
235355ffc7 | ||
|
|
4856d0cac3 | ||
|
|
77a2723bb0 | ||
|
|
41cd6e21c3 | ||
|
|
1fc99c7123 | ||
|
|
fddcc3447c | ||
|
|
70e9f084b7 | ||
|
|
824790a80d | ||
|
|
23d23983bc | ||
|
|
c42655ed91 | ||
|
|
f46ee78c76 | ||
|
|
5d1d188231 | ||
|
|
c55ce543c2 | ||
|
|
de8bc62474 | ||
|
|
397da887a7 | ||
|
|
f44733d7f6 | ||
|
|
5faa28a1a2 | ||
|
|
efaa85ff9b | ||
|
|
8f5580be10 | ||
|
|
c7acd99548 | ||
|
|
64ee13e6f4 | ||
|
|
e134f8afc7 | ||
|
|
dd89e6fbe0 | ||
|
|
a79a1b46f7 | ||
|
|
6467f51ea8 | ||
|
|
141eefb03b | ||
|
|
068c224d83 | ||
|
|
5bc8090ea7 | ||
|
|
466ab1ef8d | ||
|
|
a1c19ed1f5 | ||
|
|
cce4b7d20c | ||
|
|
80925ffc11 | ||
|
|
9eb14e328d | ||
|
|
5ae0cb1821 | ||
|
|
fc594f7f0f | ||
|
|
0c4e406ee7 | ||
|
|
a082ec5251 | ||
|
|
953b5daf0a | ||
|
|
b4ff622f32 | ||
|
|
f26b54c998 | ||
|
|
d7b3f39136 | ||
|
|
5bcf601a40 | ||
|
|
e91ebdac97 | ||
|
|
b2dd12d186 | ||
|
|
9c79bf0ba2 | ||
|
|
f48247a18b | ||
|
|
48e015558e | ||
|
|
0ff3cbc93b | ||
|
|
25f0e162a4 | ||
|
|
0810812cd9 | ||
|
|
15e0b721e6 | ||
|
|
9d12c3ac87 | ||
|
|
a7c3d8d17a | ||
|
|
8fbfdee011 | ||
|
|
bc999e72fa | ||
|
|
c7f8110670 | ||
|
|
b0dbc67281 | ||
|
|
4916f7b08b | ||
|
|
1058d94ec1 | ||
|
|
340dca3c6d | ||
|
|
4ae0f3da22 | ||
|
|
7d2d1ce49e | ||
|
|
fa26f6a10c | ||
|
|
db71a5cdba | ||
|
|
5058fdcd1a | ||
|
|
ef04f199d5 | ||
|
|
d26dd9d9e7 | ||
|
|
d2bc4096de | ||
|
|
08ca1a54d3 | ||
|
|
869eddfc1a | ||
|
|
fbced43f11 | ||
|
|
c996f816b8 | ||
|
|
33ecedb462 | ||
|
|
a58676c9e1 | ||
|
|
1ee9722e5f | ||
|
|
81250657f0 | ||
|
|
7d33cccc8e | ||
|
|
3db79ab2f0 | ||
|
|
ea0f6813d2 | ||
|
|
f6d4d32c03 | ||
|
|
892e82141f | ||
|
|
65ec7fae9c | ||
|
|
a0acb75a19 | ||
|
|
bcae973d82 | ||
|
|
d01a4fe61b | ||
|
|
8d4620b680 | ||
|
|
c2cedb1b6f | ||
|
|
157dcad87b | ||
|
|
8ea5ba171a | ||
|
|
fa876b10a3 | ||
|
|
3c58d10eae | ||
|
|
a3ee8c8849 | ||
|
|
5e14b302bc | ||
|
|
efe3f943d5 | ||
|
|
38e7fc6659 | ||
|
|
a1ceb534de | ||
|
|
0d897dd65d | ||
|
|
721d73f451 | ||
|
|
e8bd64e898 | ||
|
|
7da7ab2ce7 | ||
|
|
3f6183ff15 | ||
|
|
642316a1e2 | ||
|
|
21c6b75839 | ||
|
|
87d34deb0c | ||
|
|
1b3408919c | ||
|
|
23516572b7 | ||
|
|
924848fdad | ||
|
|
4c40e56060 | ||
|
|
cf34444505 | ||
|
|
9ca5e4e470 | ||
|
|
32f2689b6a | ||
|
|
13ae61031f | ||
|
|
1ced96c5e9 | ||
|
|
0d905eb3f6 | ||
|
|
32a5460ea7 | ||
|
|
be5acff69c | ||
|
|
1b0ef5793e | ||
|
|
2bd0caae2e | ||
|
|
3045f2c478 | ||
|
|
1282a142d6 | ||
|
|
ac1a539d22 | ||
|
|
6f47775239 | ||
|
|
0823d72dee | ||
|
|
407ad94f58 | ||
|
|
b2b103362d | ||
|
|
231680944f | ||
|
|
ec7dab05e8 | ||
|
|
9588f6061f | ||
|
|
57c25dcb0b | ||
|
|
38763c4554 | ||
|
|
fac2ea00dd | ||
|
|
74782a1bea | ||
|
|
c1265e7227 | ||
|
|
f0841256e8 | ||
|
|
600efab1bd | ||
|
|
dc9dd2e6bf | ||
|
|
de8fe0e88c | ||
|
|
338432c35f | ||
|
|
11aeb05a6e | ||
|
|
e28a32d922 | ||
|
|
edac39cb2b | ||
|
|
c1954aa4a6 | ||
|
|
ef048fcfd5 | ||
|
|
48a1531d7c | ||
|
|
4b4686ae04 | ||
|
|
cb4a54fefe | ||
|
|
131b2386cd | ||
|
|
4d6d01228c | ||
|
|
a050955113 | ||
|
|
b02789d280 | ||
|
|
6f92d0588d | ||
|
|
45df48ab67 | ||
|
|
aba5c7722e | ||
|
|
07a1a1ee2f | ||
|
|
3b952973de | ||
|
|
ac4adebdf6 | ||
|
|
1bfd9716c5 | ||
|
|
702cf9c804 | ||
|
|
5993fffb64 | ||
|
|
58758d2818 | ||
|
|
21f88fcf39 | ||
|
|
e3f029a446 | ||
|
|
0694d8884f | ||
|
|
0730a34a5b | ||
|
|
f827bb4cbd | ||
|
|
eafd8d91d7 | ||
|
|
56a4d1ddac | ||
|
|
8d3f15602c | ||
|
|
7877c7939d | ||
|
|
c55263b956 | ||
|
|
96ce288120 | ||
|
|
e5326467a1 | ||
|
|
596d8d9985 | ||
|
|
b4b0be9118 | ||
|
|
00e5f0fe97 | ||
|
|
cb140c3691 | ||
|
|
ad85ccb42f | ||
|
|
97e50f15de | ||
|
|
071c03e194 | ||
|
|
6f47c21ce9 | ||
|
|
68bfda24ff | ||
|
|
4f2fbcb9bc | ||
|
|
90ab5dfc2f | ||
|
|
362cbe5deb | ||
|
|
e133662346 | ||
|
|
1fe83ab25a | ||
|
|
1d95b5ee22 | ||
|
|
9dc603d405 | ||
|
|
5cb2863e6e | ||
|
|
98cf4223ab | ||
|
|
ff7843cbe9 | ||
|
|
c4d6b0b7c1 | ||
|
|
fb739621ac | ||
|
|
24e8ca6856 | ||
|
|
1ff9b6a375 | ||
|
|
cb6086635c | ||
|
|
bce679df78 | ||
|
|
22e8c3d895 | ||
|
|
d2b06a92c5 | ||
|
|
3901934d97 | ||
|
|
a76b25aff9 | ||
|
|
343852af26 | ||
|
|
4395f124ca | ||
|
|
b16ff3024c | ||
|
|
bc23b421e1 | ||
|
|
d9cb85a8d5 | ||
|
|
7d1cc23d16 | ||
|
|
4496ed3c13 | ||
|
|
3f5b6a450e | ||
|
|
9e24474047 | ||
|
|
7c17ede1ef | ||
|
|
5d9805c3e5 | ||
|
|
b17617bed5 | ||
|
|
a405708f1c | ||
|
|
594e66704d | ||
|
|
50579aaeea | ||
|
|
38eb855b48 | ||
|
|
12cc85c8a5 | ||
|
|
5b12595c85 | ||
|
|
3753f0bfca | ||
|
|
14ae5e397a | ||
|
|
657b4ce8c7 | ||
|
|
777e6a5334 | ||
|
|
a2ec78320b | ||
|
|
1fb53627ac | ||
|
|
fc2a39cd58 | ||
|
|
7425e1f879 | ||
|
|
6a260a57dd | ||
|
|
dadd794ece | ||
|
|
706a3738b5 | ||
|
|
9aef33aabd | ||
|
|
ac4219bcde | ||
|
|
b337856f80 | ||
|
|
079a0100c0 | ||
|
|
014c3c90e0 | ||
|
|
4759e3411f | ||
|
|
4a05e50636 | ||
|
|
72c070f338 | ||
|
|
776291a137 | ||
|
|
f3cdb95b04 | ||
|
|
033860ceb9 | ||
|
|
ab601ee3dc | ||
|
|
783ab7acd5 | ||
|
|
19a46b1f8b | ||
|
|
508cfdbda7 | ||
|
|
d81b9ee0a7 | ||
|
|
36c6c21194 | ||
|
|
1631e940f6 | ||
|
|
2eeb1fa6d1 | ||
|
|
26ac00ad76 | ||
|
|
bafc4f596f | ||
|
|
eee89dddb1 | ||
|
|
089b4fbba0 | ||
|
|
80727cef5a | ||
|
|
346a9f2b4e | ||
|
|
363d8ca5b4 | ||
|
|
06a574225d | ||
|
|
fa777b8356 | ||
|
|
7cf01318cb | ||
|
|
7c538274b4 | ||
|
|
72fb694e97 | ||
|
|
59c92dddc3 | ||
|
|
3f60fdd106 | ||
|
|
d221c480e6 | ||
|
|
59d9ff0d29 | ||
|
|
d279ea79e8 | ||
|
|
77cf9423cc | ||
|
|
60b94bbe43 | ||
|
|
b6272f9653 | ||
|
|
25fce1a6c6 | ||
|
|
59229f99c5 | ||
|
|
db3e1ae053 | ||
|
|
ec1401e657 | ||
|
|
f85fd50fa1 | ||
|
|
c39b0ab09b | ||
|
|
4b5ed0fa41 | ||
|
|
75d1155a23 | ||
|
|
753d2057bb | ||
|
|
b06d814d9c | ||
|
|
eb085a8068 | ||
|
|
45904ccd73 | ||
|
|
3b0606bbd6 | ||
|
|
0f1a76f932 | ||
|
|
d3e0140f01 | ||
|
|
ea7dded915 | ||
|
|
f187f3db29 | ||
|
|
3099a79bac | ||
|
|
7cdea39c95 | ||
|
|
95f6a5116a | ||
|
|
da94877155 | ||
|
|
b1feed9d2b | ||
|
|
a3816bffa1 | ||
|
|
612270ec9b | ||
|
|
54bc0a8d96 | ||
|
|
f761811189 | ||
|
|
0e964c5cc2 | ||
|
|
c34a944fcf | ||
|
|
3feade6b6e | ||
|
|
f79eafe449 | ||
|
|
111b159373 | ||
|
|
d744167865 | ||
|
|
a2fea86c92 | ||
|
|
5385806e74 | ||
|
|
99e85684db | ||
|
|
45727bf9f5 | ||
|
|
2a0abb0618 | ||
|
|
192e3303a1 | ||
|
|
b6051add6a | ||
|
|
24d0cda5fd | ||
|
|
d0ba59f8b5 | ||
|
|
99a1784aaf | ||
|
|
b6ff98cf18 | ||
|
|
2dcccc7cda | ||
|
|
d03855c655 | ||
|
|
69227bc1ca | ||
|
|
851debf1e4 | ||
|
|
8c1db1c407 | ||
|
|
576894e0e8 | ||
|
|
631c3ca393 | ||
|
|
fd70a1c875 | ||
|
|
30cb2e4c07 | ||
|
|
7d87cc2d24 | ||
|
|
0342dcb169 | ||
|
|
f339560550 | ||
|
|
11b58d8c69 | ||
|
|
3717f7442c | ||
|
|
e02d9f41e8 | ||
|
|
f62120861a | ||
|
|
884e2881a0 | ||
|
|
a605628dff | ||
|
|
4d96fbba6a | ||
|
|
9bfeb88e24 | ||
|
|
712f463022 | ||
|
|
713e8624a0 | ||
|
|
5c8a549125 | ||
|
|
c3e7a35b62 | ||
|
|
5bc9ca216e | ||
|
|
838a85a719 | ||
|
|
b880039541 | ||
|
|
c646166fe1 | ||
|
|
44c52ca4f8 | ||
|
|
9c9eee5d01 | ||
|
|
7bbaa6ee31 | ||
|
|
f24aed9358 | ||
|
|
02344f9048 | ||
|
|
200d2b598b | ||
|
|
3213bb13ea | ||
|
|
53fd0b3751 | ||
|
|
9b6e6a1215 | ||
|
|
e5a9d78b70 | ||
|
|
f22e964cc0 | ||
|
|
9fb827d238 | ||
|
|
24f802023a | ||
|
|
ef2b755e17 | ||
|
|
7cc8c01a1e | ||
|
|
ca509c5b9f | ||
|
|
12a39e160b | ||
|
|
7c5f36be61 | ||
|
|
aec44b093e | ||
|
|
ee83c31183 | ||
|
|
f2ad94f1c3 | ||
|
|
3aed471d57 | ||
|
|
3ee19ec75f | ||
|
|
b0d1a98cd1 | ||
|
|
94ff67ee15 | ||
|
|
8d2a7e4593 | ||
|
|
4e7a003497 | ||
|
|
380384654c | ||
|
|
2144ef84fd | ||
|
|
83d913b6d2 | ||
|
|
2782c9da91 | ||
|
|
2f539cd326 | ||
|
|
f4af518fb4 | ||
|
|
eebe0ae5d0 | ||
|
|
f9c5c7c8a5 | ||
|
|
8bc3d3ac5c | ||
|
|
6a3386ad1a | ||
|
|
5dced40c98 | ||
|
|
3f58932c2b | ||
|
|
373b9dcc37 | ||
|
|
993bdfb75f | ||
|
|
70000607a2 | ||
|
|
1b64e4b902 | ||
|
|
2166db91e2 | ||
|
|
4f50b6a749 | ||
|
|
676f659306 | ||
|
|
2f858b7948 | ||
|
|
36d9adbc0f | ||
|
|
9473b392df | ||
|
|
3bf050d5aa | ||
|
|
8a0ccc99df | ||
|
|
c938f3d8de | ||
|
|
d1c7b774f0 | ||
|
|
6b6877afc1 | ||
|
|
c370cba5b5 | ||
|
|
05d62a93c9 | ||
|
|
24cb2e6844 | ||
|
|
7f1cd62c8a | ||
|
|
5f5013871a | ||
|
|
aebe6bcd23 | ||
|
|
ac21fb81e2 | ||
|
|
74afe7f95b | ||
|
|
c8161a31d6 | ||
|
|
628217c6ae | ||
|
|
efed98d5b6 | ||
|
|
29addd605e | ||
|
|
0c121571b3 | ||
|
|
6244671b04 | ||
|
|
21b046cdd1 | ||
|
|
b32224d406 | ||
|
|
5d5865cfd8 | ||
|
|
4a78f2fef1 | ||
|
|
b521becd3c | ||
|
|
f10ed12b74 | ||
|
|
8d051ab413 | ||
|
|
4cc17a74f7 | ||
|
|
5ae4235545 | ||
|
|
8ceb8225ad | ||
|
|
20a3087d1c | ||
|
|
1f45dc512b | ||
|
|
13dee59fc8 | ||
|
|
5f78063449 | ||
|
|
ea6bd8c5c5 | ||
|
|
bdc85f2def | ||
|
|
efa731fc6d | ||
|
|
80d50b046d | ||
|
|
1855a7ea0d | ||
|
|
f5c11071be | ||
|
|
4b9e46ff06 | ||
|
|
75d618140b | ||
|
|
59c6de69b0 | ||
|
|
dc20c58189 | ||
|
|
c6eecf706a | ||
|
|
f2ee22d259 | ||
|
|
b48322222a | ||
|
|
bbf5a1ee72 | ||
|
|
c0851877bf | ||
|
|
51d96676af | ||
|
|
9f3b86e893 | ||
|
|
ac85037fc1 | ||
|
|
fa8e948e3e | ||
|
|
252cce07a6 | ||
|
|
17581106ba | ||
|
|
1bd8424fb4 | ||
|
|
23db525296 | ||
|
|
d679f8b24f | ||
|
|
d2f2ab6a9d | ||
|
|
3e1e08ca9a | ||
|
|
bb93f20be9 | ||
|
|
54dc289cde | ||
|
|
fcebad2589 | ||
|
|
4b60f98603 | ||
|
|
d304960c21 | ||
|
|
8da13b716a | ||
|
|
a6c08a24d7 | ||
|
|
6713272809 | ||
|
|
8d7cf23b40 | ||
|
|
d317a9773f | ||
|
|
e8806c48c9 | ||
|
|
abd7bab43a | ||
|
|
66464c2cce | ||
|
|
092fa9d531 | ||
|
|
1005d7fa9b | ||
|
|
079549cbd2 | ||
|
|
0f0a4d0a5e | ||
|
|
f0bbeb901d | ||
|
|
8027a25016 | ||
|
|
a1426c96f8 | ||
|
|
a4c901df57 | ||
|
|
f2cc19d1a7 | ||
|
|
ad55829890 | ||
|
|
6b8eea6363 | ||
|
|
b2d214ee79 | ||
|
|
f5fb113563 | ||
|
|
844a523706 | ||
|
|
d05379b340 | ||
|
|
006948b973 | ||
|
|
e5196026a1 | ||
|
|
66d18e4ad7 | ||
|
|
b539df1ccd | ||
|
|
c0117bfbb6 | ||
|
|
074234f182 | ||
|
|
bab03ba8c5 | ||
|
|
4878a283ed | ||
|
|
d3eed4f8c4 | ||
|
|
647db4d5de | ||
|
|
3455f83fa7 | ||
|
|
f730ba4043 | ||
|
|
caf87b1198 | ||
|
|
1706763a4c | ||
|
|
c1b8cdb35b | ||
|
|
936b7f5395 | ||
|
|
a01e3347f7 | ||
|
|
142411c08c | ||
|
|
29808c4421 | ||
|
|
48dcd174a7 | ||
|
|
6c85e6e702 | ||
|
|
e484e22e2f | ||
|
|
8ef54de812 | ||
|
|
c1d5a6e140 | ||
|
|
ea153f9df2 | ||
|
|
1ba9854070 | ||
|
|
012e955a05 | ||
|
|
37c0b49a99 | ||
|
|
de30ce9ef5 | ||
|
|
027a21278e | ||
|
|
f77fe62ab0 | ||
|
|
d42c35e1aa | ||
|
|
d5761b6385 | ||
|
|
bb3ab3b49c | ||
|
|
0441725045 | ||
|
|
ac4e6e89a4 | ||
|
|
12d21cf7a6 | ||
|
|
3fda3effda | ||
|
|
7e07b821aa | ||
|
|
e502a8b566 | ||
|
|
ec51ceb010 | ||
|
|
3fa037daee | ||
|
|
46c6955cfe | ||
|
|
252425c35c | ||
|
|
d309d472e1 | ||
|
|
898c4e8c6c | ||
|
|
56ac7b4649 | ||
|
|
9dd05b7101 | ||
|
|
e2daab9ce9 | ||
|
|
ef19ea7a85 | ||
|
|
01cf24f15f | ||
|
|
f870080497 | ||
|
|
c5942ec5a2 | ||
|
|
50d78fb804 | ||
|
|
8053aca3c3 | ||
|
|
0f3171edea | ||
|
|
6b478b9dda | ||
|
|
caaa9cea40 | ||
|
|
ea7f8f5552 | ||
|
|
69caca6017 | ||
|
|
703cfadf63 | ||
|
|
adfd461c3e | ||
|
|
bb79dbaa98 | ||
|
|
394de09907 | ||
|
|
560cafccaf | ||
|
|
0b09032164 | ||
|
|
1ee7162784 | ||
|
|
4949a131f8 | ||
|
|
8b241c3deb | ||
|
|
78c457b996 | ||
|
|
0be1b0b88b | ||
|
|
3ef0276b2a | ||
|
|
42d19f1a35 | ||
|
|
1cf9381cb0 | ||
|
|
f94dc125e5 | ||
|
|
96b978d55a | ||
|
|
ec367d333d | ||
|
|
9535097894 | ||
|
|
b541c27226 | ||
|
|
41b2af66d5 | ||
|
|
84b2b9c7a5 | ||
|
|
52c8d96dca | ||
|
|
8c6519a53b | ||
|
|
336adb9f85 | ||
|
|
7053006e77 | ||
|
|
bbf4804d12 | ||
|
|
7c16424ba3 | ||
|
|
de9dc686ac | ||
|
|
069e9b574f | ||
|
|
d5319a879a | ||
|
|
f64880aee1 | ||
|
|
fed1857918 | ||
|
|
9aeb40155e | ||
|
|
e49aeb1071 | ||
|
|
13f8ec6f3b | ||
|
|
f75c6df270 | ||
|
|
60b0afce95 | ||
|
|
f24653768f | ||
|
|
f135972a6b | ||
|
|
42c68e21a2 | ||
|
|
e8865060ca | ||
|
|
b07827a856 | ||
|
|
0735398e64 | ||
|
|
ec2d10e069 | ||
|
|
4cdb6151e5 | ||
|
|
e482b1bd18 | ||
|
|
9be3c13a07 | ||
|
|
8a4bcacf88 | ||
|
|
6b9b37b528 | ||
|
|
8e87c1ff19 | ||
|
|
aa648c1a49 | ||
|
|
056a590671 | ||
|
|
97f2503794 | ||
|
|
143079efbe | ||
|
|
7bcc173c5f | ||
|
|
0485f783b3 | ||
|
|
f3c07325bd | ||
|
|
e8eabb0102 | ||
|
|
b73f5e77ff | ||
|
|
d07712b308 | ||
|
|
89ba64d27f | ||
|
|
1a6f112d8a | ||
|
|
70e8681487 | ||
|
|
17ae0f72df | ||
|
|
466485e62e | ||
|
|
f6ee0845f2 | ||
|
|
df1eee1a74 | ||
|
|
46b46ba0b1 | ||
|
|
a763848644 | ||
|
|
9ba2d6c9fa | ||
|
|
fd1367e257 | ||
|
|
85dbc05ded | ||
|
|
1eea7786bc | ||
|
|
d039bedad4 | ||
|
|
ad6719426c | ||
|
|
719e4942ce | ||
|
|
ad9a08aea6 | ||
|
|
604fe709d5 | ||
|
|
81e8368099 | ||
|
|
2137ca8e3f | ||
|
|
672824539c | ||
|
|
1915be5aea | ||
|
|
bdea56370d | ||
|
|
e5e0c33ed6 | ||
|
|
d0c10e7523 | ||
|
|
91d2cea259 | ||
|
|
d9e2072733 | ||
|
|
820b124165 | ||
|
|
caf3eb7b05 | ||
|
|
1b5e63f024 | ||
|
|
93202f191c | ||
|
|
3033fb6791 | ||
|
|
87589609bf | ||
|
|
757514242d | ||
|
|
359d228632 | ||
|
|
24dda40863 | ||
|
|
6c0eebd4bf | ||
|
|
31db2a30bb | ||
|
|
5e241d79c8 | ||
|
|
96389ef83b | ||
|
|
af010712f3 | ||
|
|
c2896db558 | ||
|
|
57eebebcdd | ||
|
|
9ad9cbd7de | ||
|
|
1b5adde885 | ||
|
|
ca35dd79d2 | ||
|
|
491f2e3e76 | ||
|
|
b6591e21cd | ||
|
|
67ed89729d | ||
|
|
6033e75dc4 | ||
|
|
5f8993cb83 | ||
|
|
2446300dd9 | ||
|
|
b97c45df78 | ||
|
|
9034e82298 | ||
|
|
ae395f05e1 | ||
|
|
0c1d359091 | ||
|
|
dd8a9c67c9 | ||
|
|
de331bcd9e | ||
|
|
a81d6bc247 | ||
|
|
47d0b12d40 | ||
|
|
849e9aa734 | ||
|
|
351e098da1 | ||
|
|
c5f825eaa5 | ||
|
|
d0a4102efa | ||
|
|
3aa4181380 | ||
|
|
43dc30c3a5 | ||
|
|
98e6613df0 | ||
|
|
3ce07891e4 | ||
|
|
2ff47ab7c4 | ||
|
|
8ba639c7d5 | ||
|
|
e0403e4dae | ||
|
|
7776525c96 | ||
|
|
25fe9b7f58 | ||
|
|
fff7aba8ec | ||
|
|
e83f3ed444 | ||
|
|
334f11d5bc | ||
|
|
5bcde44684 | ||
|
|
2459793f9c | ||
|
|
cadd7b9728 | ||
|
|
644f247026 | ||
|
|
8c1ef3051d | ||
|
|
d296e15f26 | ||
|
|
5a5cd46f9b | ||
|
|
20d9345a4e |
No files matched your search
+13
-1
@@ -1,3 +1,15 @@
|
||||
*.o
|
||||
ssnes
|
||||
*.bmpobj
|
||||
*.so
|
||||
*.dll
|
||||
/ssnes
|
||||
/config.h
|
||||
/config.mk
|
||||
/tools/ssnes-joyconfig
|
||||
*.sdf
|
||||
*.opensdf
|
||||
*.suo
|
||||
Debug
|
||||
Release
|
||||
ipch
|
||||
*.user
|
||||
+802
@@ -0,0 +1,802 @@
|
||||
/* RetroArch - A frontend for libretro.
|
||||
* Copyright (C) 2010-2012 - Hans-Kristian Arntzen
|
||||
* Copyright (C) 2011-2012 - Daniel De Matteis
|
||||
*
|
||||
* RetroArch is free software: you can redistribute it and/or modify it under the terms
|
||||
* of the GNU General Public License as published by the Free Software Found-
|
||||
* ation, either version 3 of the License, or (at your option) any later version.
|
||||
*
|
||||
* RetroArch is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
|
||||
* without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
|
||||
* PURPOSE. See the GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along with RetroArch.
|
||||
* If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#define NONET
|
||||
#include <xtl.h>
|
||||
#include "xdk360_video.h"
|
||||
#include "fonts.h"
|
||||
#include "../general.h"
|
||||
|
||||
static video_console_t video_console;
|
||||
static xdk360_video_font_t m_Font;
|
||||
|
||||
static PackedResource m_xprResource;
|
||||
|
||||
#define CALCFONTFILEHEADERSIZE(x) ( sizeof(unsigned long) + (sizeof(float)* 4) + sizeof(unsigned short) + (sizeof(wchar_t)*(x)) )
|
||||
#define FONTFILEVERSION 5
|
||||
|
||||
typedef struct {
|
||||
unsigned long m_dwFileVersion; // Version of the font file (Must match FONTFILEVERSION)
|
||||
float m_fFontHeight; // Height of the font strike in pixels
|
||||
float m_fFontTopPadding; // Padding above the strike zone
|
||||
float m_fFontBottomPadding; // Padding below the strike zone
|
||||
float m_fFontYAdvance; // Number of pixels to move the cursor for a line feed
|
||||
unsigned short m_cMaxGlyph; // Number of font characters (Should be an odd number to maintain DWORD Alignment)
|
||||
wchar_t m_TranslatorTable[1]; // ASCII to Glyph lookup table, NOTE: It's m_cMaxGlyph+1 in size.
|
||||
} FontFileHeaderImage_t;
|
||||
|
||||
// Font strike array. Immediately follows the FontFileHeaderImage_t
|
||||
// structure image
|
||||
|
||||
typedef struct {
|
||||
unsigned long m_dwNumGlyphs; // Size of font strike array (First entry is the unknown glyph)
|
||||
GLYPH_ATTR m_Glyphs[1]; // Array of font strike uv's etc... NOTE: It's m_dwNumGlyphs in size
|
||||
} FontFileStrikesImage_t;
|
||||
|
||||
static const char g_strFontShader[] =
|
||||
"struct VS_IN\n"
|
||||
"{\n"
|
||||
"float2 Pos : POSITION;\n"
|
||||
"float2 Tex : TEXCOORD0;\n"
|
||||
"};\n"
|
||||
"struct VS_OUT\n"
|
||||
"{\n"
|
||||
"float4 Position : POSITION;\n"
|
||||
"float2 TexCoord0 : TEXCOORD0;\n"
|
||||
"};\n"
|
||||
"uniform float4 Color : register(c1);\n"
|
||||
"uniform float2 TexScale : register(c2);\n"
|
||||
"sampler FontTexture : register(s0);\n"
|
||||
"VS_OUT main_vertex( VS_IN In )\n"
|
||||
"{\n"
|
||||
"VS_OUT Out;\n"
|
||||
"Out.Position.x = (In.Pos.x-0.5);\n"
|
||||
"Out.Position.y = (In.Pos.y-0.5);\n"
|
||||
"Out.Position.z = ( 0.0 );\n"
|
||||
"Out.Position.w = ( 1.0 );\n"
|
||||
"Out.TexCoord0.x = In.Tex.x * TexScale.x;\n"
|
||||
"Out.TexCoord0.y = In.Tex.y * TexScale.y;\n"
|
||||
"return Out;\n"
|
||||
"}\n"
|
||||
"float4 main_fragment( VS_OUT In ) : COLOR0\n"
|
||||
"{\n"
|
||||
"float4 FontTexel = tex2D( FontTexture, In.TexCoord0 );\n"
|
||||
"return FontTexel;\n"
|
||||
"}\n";
|
||||
|
||||
typedef struct {
|
||||
D3DVertexDeclaration* m_pFontVertexDecl; // Shared vertex buffer
|
||||
D3DVertexShader* m_pFontVertexShader; // Created vertex shader
|
||||
D3DPixelShader* m_pFontPixelShader; // Created pixel shader
|
||||
} Font_Locals_t;
|
||||
|
||||
// All elements are defaulted to NULL
|
||||
static Font_Locals_t s_FontLocals; // Global static instance
|
||||
|
||||
static void xdk360_video_font_draw_text(xdk360_video_font_t * font,
|
||||
float fOriginX, float fOriginY, unsigned long dwColor,
|
||||
const wchar_t * strText, float fMaxPixelWidth )
|
||||
{
|
||||
if( strText == NULL || strText[0] == L'\0')
|
||||
return;
|
||||
|
||||
xdk360_video_t *vid = (xdk360_video_t*)driver.video_data;
|
||||
D3DDevice *pd3dDevice = vid->d3d_render_device;
|
||||
|
||||
// Set the color as a vertex shader constant
|
||||
float vColor[4];
|
||||
vColor[0] = ( ( dwColor & 0x00ff0000 ) >> 16L ) / 255.0F;
|
||||
vColor[1] = ( ( dwColor & 0x0000ff00 ) >> 8L ) / 255.0F;
|
||||
vColor[2] = ( ( dwColor & 0x000000ff ) >> 0L ) / 255.0F;
|
||||
vColor[3] = ( ( dwColor & 0xff000000 ) >> 24L ) / 255.0F;
|
||||
|
||||
// Set up stuff to prepare for drawing text
|
||||
xdk360_video_font_begin(font);
|
||||
|
||||
// Perform the actual storing of the color constant here to prevent
|
||||
// a load-hit-store by inserting work between the store and the use of
|
||||
// the vColor array.
|
||||
pd3dDevice->SetVertexShaderConstantF( 1, vColor, 1 );
|
||||
|
||||
// Set the starting screen position
|
||||
if((fOriginX < 0.0f))
|
||||
fOriginX += font->m_rcWindow.x2;
|
||||
if( fOriginY < 0.0f )
|
||||
fOriginY += font->m_rcWindow.y2;
|
||||
|
||||
font->m_fCursorX = floorf( fOriginX );
|
||||
font->m_fCursorY = floorf( fOriginY );
|
||||
|
||||
// Adjust for padding
|
||||
fOriginY -= font->m_fFontTopPadding;
|
||||
|
||||
// Add window offsets
|
||||
float Winx = 0.0f;
|
||||
float Winy = 0.0f;
|
||||
fOriginX += Winx;
|
||||
fOriginY += Winy;
|
||||
font->m_fCursorX += Winx;
|
||||
font->m_fCursorY += Winy;
|
||||
|
||||
// Begin drawing the vertices
|
||||
|
||||
// Declared as volatile to force writing in ascending
|
||||
// address order. It prevents out of sequence writing in write combined
|
||||
// memory.
|
||||
|
||||
volatile float * pVertex;
|
||||
|
||||
unsigned long dwNumChars = wcslen(strText);
|
||||
HRESULT hr = pd3dDevice->BeginVertices( D3DPT_QUADLIST, 4 * dwNumChars, sizeof( XMFLOAT4 ) ,
|
||||
( VOID** )&pVertex );
|
||||
|
||||
// The ring buffer may run out of space when tiling, doing z-prepasses,
|
||||
// or using BeginCommandBuffer. If so, make the buffer larger.
|
||||
if( hr < 0 )
|
||||
RARCH_ERR( "Ring buffer out of memory.\n" );
|
||||
|
||||
// Draw four vertices for each glyph
|
||||
while( *strText )
|
||||
{
|
||||
wchar_t letter;
|
||||
|
||||
// Get the current letter in the string
|
||||
letter = *strText++;
|
||||
|
||||
// Handle the newline character
|
||||
if( letter == L'\n' )
|
||||
{
|
||||
font->m_fCursorX = fOriginX;
|
||||
font->m_fCursorY += font->m_fFontYAdvance * font->m_fYScaleFactor;
|
||||
continue;
|
||||
}
|
||||
|
||||
// Translate unprintable characters
|
||||
const GLYPH_ATTR * pGlyph = &font->m_Glyphs[ ( letter <= font->m_cMaxGlyph )
|
||||
? font->m_TranslatorTable[letter] : 0 ];
|
||||
|
||||
float fOffset = font->m_fXScaleFactor * (float)pGlyph->wOffset;
|
||||
float fAdvance = font->m_fXScaleFactor * (float)pGlyph->wAdvance;
|
||||
float fWidth = font->m_fXScaleFactor * (float)pGlyph->wWidth;
|
||||
float fHeight = font->m_fYScaleFactor * font->m_fFontHeight;
|
||||
|
||||
// Setup the screen coordinates
|
||||
font->m_fCursorX += fOffset;
|
||||
float X4 = font->m_fCursorX;
|
||||
float X1 = X4;
|
||||
float X3 = X4 + fWidth;
|
||||
float X2 = X1 + fWidth;
|
||||
float Y1 = font->m_fCursorY;
|
||||
float Y3 = Y1 + fHeight;
|
||||
float Y2 = Y1;
|
||||
float Y4 = Y3;
|
||||
|
||||
font->m_fCursorX += fAdvance;
|
||||
|
||||
// Select the RGBA channel that the compressed glyph is stored in
|
||||
// Takes a 4 bit per pixel ARGB value and expand it to an 8 bit per pixel ARGB value
|
||||
|
||||
unsigned long dwChannelSelector = pGlyph->wMask; // Convert to 32 bit
|
||||
// Perform the conversion without branching
|
||||
|
||||
// Splat the 4 bit per pixels from 0x1234 to 0x01020304
|
||||
dwChannelSelector = ((dwChannelSelector&0xF000)<<(24-12))|((dwChannelSelector&0xF00)<<(16-8))|
|
||||
((dwChannelSelector&0xF0)<<(8-4))|(dwChannelSelector&0xF);
|
||||
|
||||
// Perform a vectorized multiply to make 0x01020304 into 0x11223344
|
||||
dwChannelSelector *= 0x11;
|
||||
|
||||
// Add the vertices to draw this glyph
|
||||
|
||||
unsigned long tu1 = pGlyph->tu1; // Convert shorts to 32 bit longs for in register merging
|
||||
unsigned long tv1 = pGlyph->tv1;
|
||||
unsigned long tu2 = pGlyph->tu2;
|
||||
unsigned long tv2 = pGlyph->tv2;
|
||||
|
||||
// NOTE: The vertexs are 2 floats for the screen coordinates,
|
||||
// followed by two USHORTS for the u/vs of the character,
|
||||
// terminated with the ARGB 32 bit color.
|
||||
// This makes for 16 bytes per vertex data (Easier to read)
|
||||
// Second NOTE: The uvs are merged and written using a DWORD due
|
||||
// to the write combining hardware being only able to handle 32,
|
||||
// 64 and 128 writes. Never store to write combined memory with
|
||||
// 8 or 16 bit instructions. You've been warned.
|
||||
|
||||
pVertex[0] = X1;
|
||||
pVertex[1] = Y1;
|
||||
reinterpret_cast<volatile unsigned long *>(pVertex)[2] = (tu1<<16)|tv1; // Merged using big endian rules
|
||||
reinterpret_cast<volatile unsigned long *>(pVertex)[3] = dwChannelSelector;
|
||||
pVertex[4] = X2;
|
||||
pVertex[5] = Y2;
|
||||
reinterpret_cast<volatile unsigned long *>(pVertex)[6] = (tu2<<16)|tv1; // Merged using big endian rules
|
||||
reinterpret_cast<volatile unsigned long *>(pVertex)[7] = dwChannelSelector;
|
||||
pVertex[8] = X3;
|
||||
pVertex[9] = Y3;
|
||||
reinterpret_cast<volatile unsigned long *>(pVertex)[10] = (tu2<<16)|tv2; // Merged using big endian rules
|
||||
reinterpret_cast<volatile unsigned long *>(pVertex)[11] = dwChannelSelector;
|
||||
pVertex[12] = X4;
|
||||
pVertex[13] = Y4;
|
||||
reinterpret_cast<volatile unsigned long *>(pVertex)[14] = (tu1<<16)|tv2; // Merged using big endian rules
|
||||
reinterpret_cast<volatile unsigned long *>(pVertex)[15] = dwChannelSelector;
|
||||
pVertex+=16;
|
||||
|
||||
dwNumChars--;
|
||||
}
|
||||
|
||||
// Since we allocated vertex data space based on the string length, we now need to
|
||||
// add some dummy verts for any skipped characters (like newlines, etc.)
|
||||
while( dwNumChars )
|
||||
{
|
||||
pVertex[0] = 0;
|
||||
pVertex[1] = 0;
|
||||
pVertex[2] = 0;
|
||||
pVertex[3] = 0;
|
||||
pVertex[4] = 0;
|
||||
pVertex[5] = 0;
|
||||
pVertex[6] = 0;
|
||||
pVertex[7] = 0;
|
||||
pVertex[8] = 0;
|
||||
pVertex[9] = 0;
|
||||
pVertex[10] = 0;
|
||||
pVertex[11] = 0;
|
||||
pVertex[12] = 0;
|
||||
pVertex[13] = 0;
|
||||
pVertex[14] = 0;
|
||||
pVertex[15] = 0;
|
||||
pVertex+=16;
|
||||
dwNumChars--;
|
||||
}
|
||||
|
||||
// Stop drawing vertices
|
||||
D3DDevice_EndVertices(pd3dDevice);
|
||||
|
||||
// Undo window offsets
|
||||
font->m_fCursorX -= Winx;
|
||||
font->m_fCursorY -= Winy;
|
||||
|
||||
// Call End() to complete the begin/end pair for drawing text
|
||||
xdk360_video_font_end(font);
|
||||
}
|
||||
|
||||
void xdk360_console_draw(void)
|
||||
{
|
||||
xdk360_video_t *vid = (xdk360_video_t*)driver.video_data;
|
||||
D3DDevice *m_pd3dDevice = vid->d3d_render_device;
|
||||
|
||||
// The top line
|
||||
unsigned int nTextLine = ( video_console.m_nCurLine -
|
||||
video_console.m_cScreenHeight + video_console.m_cScreenHeightVirtual -
|
||||
video_console.m_nScrollOffset + 1 )
|
||||
% video_console.m_cScreenHeightVirtual;
|
||||
|
||||
xdk360_video_font_begin(&m_Font);
|
||||
|
||||
for( unsigned int nScreenLine = 0; nScreenLine < video_console.m_cScreenHeight; nScreenLine++ )
|
||||
{
|
||||
xdk360_video_font_draw_text(&m_Font, (float)( video_console.m_cxSafeAreaOffset ),
|
||||
(float)( video_console.m_cySafeAreaOffset +
|
||||
video_console.m_fLineHeight * nScreenLine ),
|
||||
video_console.m_colTextColor,
|
||||
video_console.m_Lines[nTextLine], 0.0f );
|
||||
|
||||
nTextLine = ( nTextLine + 1 ) % video_console.m_cScreenHeightVirtual;
|
||||
}
|
||||
|
||||
xdk360_video_font_end(&m_Font);
|
||||
}
|
||||
|
||||
static void xdk360_video_font_get_text_width(xdk360_video_font_t * font, const wchar_t * strText, float * pWidth, float * pHeight)
|
||||
{
|
||||
// Set default text extent in output parameters
|
||||
int iWidth = 0;
|
||||
float fHeight = 0.0f;
|
||||
|
||||
if( strText )
|
||||
{
|
||||
// Initialize counters that keep track of text extent
|
||||
int ix = 0;
|
||||
float fy = font->m_fFontHeight; // One character high to start
|
||||
if( fy > fHeight )
|
||||
fHeight = fy;
|
||||
|
||||
// Loop through each character and update text extent
|
||||
unsigned long letter;
|
||||
while( (letter = *strText) != 0 )
|
||||
{
|
||||
++strText;
|
||||
|
||||
// Handle newline character
|
||||
if (letter == L'\n')
|
||||
break;
|
||||
|
||||
// Handle carriage return characters by ignoring them. This helps when
|
||||
// displaying text from a file.
|
||||
if( letter == L'\r' )
|
||||
continue;
|
||||
|
||||
// Translate unprintable characters
|
||||
const GLYPH_ATTR* pGlyph;
|
||||
|
||||
if( letter > font->m_cMaxGlyph )
|
||||
letter = 0; // Out of bounds?
|
||||
else
|
||||
letter = font->m_TranslatorTable[letter]; // Remap ASCII to glyph
|
||||
|
||||
pGlyph = &font->m_Glyphs[letter]; // Get the requested glyph
|
||||
|
||||
// Get text extent for this character's glyph
|
||||
ix += pGlyph->wOffset;
|
||||
ix += pGlyph->wAdvance;
|
||||
|
||||
// Since the x widened, test against the x extent
|
||||
|
||||
if( ix > iWidth )
|
||||
iWidth = ix;
|
||||
}
|
||||
}
|
||||
|
||||
float fWidth = (float)iWidth;
|
||||
fHeight *= font->m_fYScaleFactor; // Apply the scale factor to the result
|
||||
*pHeight = fHeight; // Store the final results
|
||||
|
||||
fWidth *= font->m_fXScaleFactor;
|
||||
*pWidth = fWidth;
|
||||
}
|
||||
|
||||
static HRESULT xdk360_video_font_create_shaders (xdk360_video_font_t * font)
|
||||
{
|
||||
HRESULT hr;
|
||||
|
||||
if (!s_FontLocals.m_pFontVertexDecl)
|
||||
{
|
||||
do
|
||||
{
|
||||
static const D3DVERTEXELEMENT9 decl[] =
|
||||
{
|
||||
{ 0, 0, D3DDECLTYPE_FLOAT2, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0 },
|
||||
{ 0, 8, D3DDECLTYPE_USHORT2, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 0 },
|
||||
{ 0, 12, D3DDECLTYPE_D3DCOLOR, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 1 },
|
||||
D3DDECL_END()
|
||||
};
|
||||
|
||||
xdk360_video_t *vid = (xdk360_video_t*)driver.video_data;
|
||||
D3DDevice *pd3dDevice = vid->d3d_render_device;
|
||||
|
||||
hr = pd3dDevice->CreateVertexDeclaration( decl, &s_FontLocals.m_pFontVertexDecl );
|
||||
|
||||
if (hr >= 0)
|
||||
{
|
||||
ID3DXBuffer* pShaderCode;
|
||||
|
||||
hr = D3DXCompileShader( g_strFontShader, sizeof(g_strFontShader)-1 ,
|
||||
NULL, NULL, "main_vertex", "vs.2.0", 0,&pShaderCode, NULL, NULL );
|
||||
|
||||
if (hr >= 0)
|
||||
{
|
||||
hr = pd3dDevice->CreateVertexShader( ( unsigned long * )pShaderCode->GetBufferPointer(),
|
||||
&s_FontLocals.m_pFontVertexShader );
|
||||
pShaderCode->Release();
|
||||
|
||||
if (hr >= 0)
|
||||
{
|
||||
hr = D3DXCompileShader( g_strFontShader, sizeof(g_strFontShader)-1 ,
|
||||
NULL, NULL, "main_fragment", "ps.2.0", 0,&pShaderCode, NULL, NULL );
|
||||
|
||||
if (hr >= 0)
|
||||
{
|
||||
hr = pd3dDevice->CreatePixelShader( ( DWORD* )pShaderCode->GetBufferPointer(),
|
||||
&s_FontLocals.m_pFontPixelShader );
|
||||
pShaderCode->Release();
|
||||
|
||||
if (hr >= 0)
|
||||
{
|
||||
hr = 0;
|
||||
break;
|
||||
}
|
||||
}
|
||||
D3DResource_Release((D3DResource *)s_FontLocals.m_pFontVertexShader);
|
||||
}
|
||||
|
||||
s_FontLocals.m_pFontVertexShader = NULL;
|
||||
}
|
||||
|
||||
D3DResource_Release((D3DResource *)s_FontLocals.m_pFontVertexDecl);
|
||||
}
|
||||
s_FontLocals.m_pFontVertexDecl = NULL;
|
||||
}while(0);
|
||||
return hr;
|
||||
}
|
||||
else
|
||||
{
|
||||
D3DResource_AddRef((D3DResource *)s_FontLocals.m_pFontVertexDecl);
|
||||
D3DResource_AddRef((D3DResource *)s_FontLocals.m_pFontVertexShader);
|
||||
D3DResource_AddRef((D3DResource *)s_FontLocals.m_pFontPixelShader);
|
||||
hr = 0;
|
||||
}
|
||||
return hr;
|
||||
}
|
||||
|
||||
static HRESULT xdk360_video_font_init(xdk360_video_font_t * font, const char * strFontFileName)
|
||||
{
|
||||
font->m_pFontTexture = NULL;
|
||||
font->m_dwNumGlyphs = 0L;
|
||||
font->m_Glyphs = NULL;
|
||||
font->m_fCursorX = 0.0f;
|
||||
font->m_fCursorY = 0.0f;
|
||||
font->m_fXScaleFactor = 2.0f;
|
||||
font->m_fYScaleFactor = 2.0f;
|
||||
font->m_cMaxGlyph = 0;
|
||||
font->m_TranslatorTable = NULL;
|
||||
font->m_dwNestedBeginCount = 0L;
|
||||
|
||||
// Create the font
|
||||
if( FAILED( m_xprResource.Create( strFontFileName ) ) )
|
||||
return E_FAIL;
|
||||
|
||||
D3DTexture * pFontTexture = m_xprResource.GetTexture( "FontTexture" );
|
||||
const void * pFontData = m_xprResource.GetData( "FontData");
|
||||
|
||||
// Save a copy of the texture
|
||||
font->m_pFontTexture = pFontTexture;
|
||||
|
||||
// Check version of file (to make sure it matches up with the FontMaker tool)
|
||||
const unsigned char * pData = static_cast<const unsigned char *>(pFontData);
|
||||
unsigned long dwFileVersion = reinterpret_cast<const FontFileHeaderImage_t *>(pData)->m_dwFileVersion;
|
||||
|
||||
if( dwFileVersion == FONTFILEVERSION )
|
||||
{
|
||||
font->m_fFontHeight = reinterpret_cast<const FontFileHeaderImage_t *>(pData)->m_fFontHeight;
|
||||
font->m_fFontTopPadding = reinterpret_cast<const FontFileHeaderImage_t *>(pData)->m_fFontTopPadding;
|
||||
font->m_fFontBottomPadding = reinterpret_cast<const FontFileHeaderImage_t *>(pData)->m_fFontBottomPadding;
|
||||
font->m_fFontYAdvance = reinterpret_cast<const FontFileHeaderImage_t *>(pData)->m_fFontYAdvance;
|
||||
|
||||
// Point to the translator string which immediately follows the 4 floats
|
||||
font->m_cMaxGlyph = reinterpret_cast<const FontFileHeaderImage_t *>(pData)->m_cMaxGlyph;
|
||||
|
||||
font->m_TranslatorTable = const_cast<FontFileHeaderImage_t*>(reinterpret_cast<const FontFileHeaderImage_t *>(pData))->m_TranslatorTable;
|
||||
|
||||
pData += CALCFONTFILEHEADERSIZE( font->m_cMaxGlyph + 1 );
|
||||
|
||||
// Read the glyph attributes from the file
|
||||
font->m_dwNumGlyphs = reinterpret_cast<const FontFileStrikesImage_t *>(pData)->m_dwNumGlyphs;
|
||||
font->m_Glyphs = reinterpret_cast<const FontFileStrikesImage_t *>(pData)->m_Glyphs; // Pointer
|
||||
}
|
||||
else
|
||||
{
|
||||
RARCH_ERR( "Incorrect version number on font file.\n" );
|
||||
return E_FAIL;
|
||||
}
|
||||
|
||||
// Create the vertex and pixel shaders for rendering the font
|
||||
if( FAILED( xdk360_video_font_create_shaders(font) ) )
|
||||
{
|
||||
RARCH_ERR( "Could not create font shaders.\n" );
|
||||
return E_FAIL;
|
||||
}
|
||||
|
||||
xdk360_video_t *vid = (xdk360_video_t*)driver.video_data;
|
||||
D3DDevice *pd3dDevice = vid->d3d_render_device;
|
||||
|
||||
// Initialize the window
|
||||
D3DDISPLAYMODE DisplayMode;
|
||||
pd3dDevice->GetDisplayMode( 0, &DisplayMode );
|
||||
font->m_rcWindow.x1 = 0;
|
||||
font->m_rcWindow.y1 = 0;
|
||||
font->m_rcWindow.x2 = DisplayMode.Width;
|
||||
font->m_rcWindow.y2 = DisplayMode.Height;
|
||||
|
||||
// Determine whether we should save/restore state
|
||||
font->m_bSaveState = TRUE;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
HRESULT xdk360_console_init( LPCSTR strFontFileName, unsigned long colBackColor,
|
||||
unsigned long colTextColor)
|
||||
{
|
||||
xdk360_video_t *vid = (xdk360_video_t*)driver.video_data;
|
||||
D3DDevice *m_pd3dDevice = vid->d3d_render_device;
|
||||
|
||||
video_console.first_message = true;
|
||||
video_console.m_Buffer = NULL;
|
||||
video_console.m_Lines = NULL;
|
||||
video_console.m_nScrollOffset = 0;
|
||||
|
||||
// Calculate the safe area
|
||||
unsigned int uiSafeAreaPct = vid->video_mode.fIsHiDef ? SAFE_AREA_PCT_HDTV
|
||||
: SAFE_AREA_PCT_4x3;
|
||||
|
||||
video_console.m_cxSafeArea = ( vid->d3dpp.BackBufferWidth * uiSafeAreaPct ) / 100;
|
||||
video_console.m_cySafeArea = ( vid->d3dpp.BackBufferHeight * uiSafeAreaPct ) / 100;
|
||||
|
||||
video_console.m_cxSafeAreaOffset = ( vid->d3dpp.BackBufferWidth - video_console.m_cxSafeArea ) / 2;
|
||||
video_console.m_cySafeAreaOffset = ( vid->d3dpp.BackBufferHeight - video_console.m_cySafeArea ) / 2;
|
||||
|
||||
// Create the font
|
||||
HRESULT hr = xdk360_video_font_init(&m_Font, strFontFileName );
|
||||
if (hr < 0)
|
||||
{
|
||||
RARCH_ERR( "Could not create font.\n" );
|
||||
return -1;
|
||||
}
|
||||
|
||||
// Save the colors
|
||||
video_console.m_colBackColor = colBackColor;
|
||||
video_console.m_colTextColor = colTextColor;
|
||||
|
||||
// Calculate the number of lines on the screen
|
||||
float fCharWidth, fCharHeight;
|
||||
xdk360_video_font_get_text_width(&m_Font, L"i", &fCharWidth, &fCharHeight);
|
||||
|
||||
video_console.m_cScreenHeight = (unsigned int)( video_console.m_cySafeArea / fCharHeight );
|
||||
video_console.m_cScreenWidth = (unsigned int)( video_console.m_cxSafeArea / fCharWidth );
|
||||
|
||||
video_console.m_cScreenHeightVirtual = video_console.m_cScreenHeight;
|
||||
|
||||
video_console.m_fLineHeight = fCharHeight;
|
||||
|
||||
// Allocate memory to hold the lines
|
||||
video_console.m_Buffer = (wchar_t*)malloc(sizeof(wchar_t*) * video_console.m_cScreenHeightVirtual * ( video_console.m_cScreenWidth + 1 ));
|
||||
video_console.m_Lines = new wchar_t *[ video_console.m_cScreenHeightVirtual ];
|
||||
|
||||
// Set the line pointers as indexes into the buffer
|
||||
for( unsigned int i = 0; i < video_console.m_cScreenHeightVirtual; i++ )
|
||||
video_console.m_Lines[ i ] = video_console.m_Buffer + ( video_console.m_cScreenWidth + 1 ) * i;
|
||||
|
||||
video_console.m_nCurLine = 0;
|
||||
video_console.m_cCurLineLength = 0;
|
||||
memset( video_console.m_Buffer, 0, video_console.m_cScreenHeightVirtual * ( video_console.m_cScreenWidth + 1 ) * sizeof( wchar_t ) );
|
||||
xdk360_console_draw();
|
||||
|
||||
return hr;
|
||||
}
|
||||
|
||||
static void xdk360_video_font_deinit(xdk360_video_font_t * font)
|
||||
{
|
||||
font->m_pFontTexture = NULL;
|
||||
font->m_dwNumGlyphs = 0L;
|
||||
font->m_Glyphs = NULL;
|
||||
font->m_cMaxGlyph = 0;
|
||||
font->m_TranslatorTable = NULL;
|
||||
font->m_dwNestedBeginCount = 0L;
|
||||
|
||||
// Safely release shaders
|
||||
// NOTE: They are released in reverse order of creation
|
||||
// to make sure any interdependencies are dealt with
|
||||
|
||||
if( ( s_FontLocals.m_pFontPixelShader != NULL ) && ( s_FontLocals.m_pFontPixelShader->Release() == 0 ) )
|
||||
s_FontLocals.m_pFontPixelShader = NULL;
|
||||
if( ( s_FontLocals.m_pFontVertexShader != NULL ) && ( s_FontLocals.m_pFontVertexShader->Release() == 0 ) )
|
||||
s_FontLocals.m_pFontVertexShader = NULL;
|
||||
if( ( s_FontLocals.m_pFontVertexDecl != NULL ) && ( s_FontLocals.m_pFontVertexDecl->Release() == 0 ) )
|
||||
s_FontLocals.m_pFontVertexDecl = NULL;
|
||||
|
||||
if( m_xprResource.m_bInitialized)
|
||||
m_xprResource.Destroy();
|
||||
}
|
||||
|
||||
void xdk360_console_deinit()
|
||||
{
|
||||
// Delete the memory we've allocated
|
||||
if(video_console.m_Lines)
|
||||
{
|
||||
delete[] video_console.m_Lines;
|
||||
video_console.m_Lines = NULL;
|
||||
}
|
||||
|
||||
if(video_console.m_Buffer)
|
||||
{
|
||||
free(video_console.m_Buffer);
|
||||
video_console.m_Buffer = NULL;
|
||||
}
|
||||
|
||||
// Destroy the font
|
||||
xdk360_video_font_deinit(&m_Font);
|
||||
}
|
||||
|
||||
static void xdk360_console_add( wchar_t wch )
|
||||
{
|
||||
// If this is a newline, just increment lines and move on
|
||||
if( wch == L'\n' )
|
||||
{
|
||||
video_console.m_nCurLine = ( video_console.m_nCurLine + 1 )
|
||||
% video_console.m_cScreenHeightVirtual;
|
||||
video_console.m_cCurLineLength = 0;
|
||||
memset(video_console.m_Lines[video_console.m_nCurLine], 0,
|
||||
( video_console.m_cScreenWidth + 1 ) * sizeof( wchar_t ) );
|
||||
return;
|
||||
}
|
||||
|
||||
int bIncrementLine = FALSE; // Whether to wrap to the next line
|
||||
|
||||
if( video_console.m_cCurLineLength == video_console.m_cScreenWidth )
|
||||
bIncrementLine = TRUE;
|
||||
else
|
||||
{
|
||||
// Try to append the character to the line
|
||||
video_console.m_Lines[ video_console.m_nCurLine ][ video_console.m_cCurLineLength ] = wch;
|
||||
|
||||
float fTextWidth, fTextHeight;
|
||||
|
||||
xdk360_video_font_get_text_width(&m_Font, video_console.m_Lines[ video_console.m_nCurLine ], &fTextWidth,
|
||||
&fTextHeight);
|
||||
|
||||
if( fTextHeight > video_console.m_cxSafeArea )
|
||||
{
|
||||
// The line is too long, we need to wrap the character to the next line
|
||||
video_console.m_Lines[video_console.m_nCurLine][ video_console.m_cCurLineLength ] = L'\0';
|
||||
bIncrementLine = TRUE;
|
||||
}
|
||||
}
|
||||
|
||||
// If we need to skip to the next line, do so
|
||||
if( bIncrementLine )
|
||||
{
|
||||
video_console.m_nCurLine = ( video_console.m_nCurLine + 1 )
|
||||
% video_console.m_cScreenHeightVirtual;
|
||||
video_console.m_cCurLineLength = 0;
|
||||
memset( video_console.m_Lines[video_console.m_nCurLine],
|
||||
0, ( video_console.m_cScreenWidth + 1 ) * sizeof( wchar_t ) );
|
||||
video_console.m_Lines[video_console.m_nCurLine ][0] = wch;
|
||||
}
|
||||
|
||||
video_console.m_cCurLineLength++;
|
||||
}
|
||||
|
||||
void xdk360_console_format(LPCSTR strFormat, ... )
|
||||
{
|
||||
video_console.m_nCurLine = 0;
|
||||
video_console.m_cCurLineLength = 0;
|
||||
|
||||
memset( video_console.m_Buffer, 0,
|
||||
video_console.m_cScreenHeightVirtual *
|
||||
( video_console.m_cScreenWidth + 1 ) * sizeof( wchar_t ) );
|
||||
|
||||
va_list pArgList;
|
||||
va_start( pArgList, strFormat );
|
||||
|
||||
// Count the required length of the string
|
||||
unsigned long dwStrLen = _vscprintf( strFormat, pArgList ) + 1;
|
||||
// +1 = null terminator
|
||||
char * strMessage = ( char * )malloc( dwStrLen );
|
||||
vsprintf_s( strMessage, dwStrLen, strFormat, pArgList );
|
||||
|
||||
// Output the string to the console
|
||||
unsigned long uStringLength = strlen( strMessage );
|
||||
for( unsigned long i = 0; i < uStringLength; i++ )
|
||||
{
|
||||
wchar_t wch;
|
||||
int ret = MultiByteToWideChar(
|
||||
CP_ACP, // ANSI code page
|
||||
0, // No flags
|
||||
&strMessage[i], // Character to convert
|
||||
1, // Convert one byte
|
||||
&wch, // Target wide character buffer
|
||||
1 ); // One wide character
|
||||
xdk360_console_add( wch );
|
||||
}
|
||||
|
||||
free(strMessage);
|
||||
|
||||
va_end( pArgList );
|
||||
}
|
||||
|
||||
void xdk360_video_font_begin (xdk360_video_font_t * font)
|
||||
{
|
||||
// Set state on the first call
|
||||
if( font->m_dwNestedBeginCount == 0 )
|
||||
{
|
||||
// Cache the global pointer into a register
|
||||
xdk360_video_t *vid = (xdk360_video_t*)driver.video_data;
|
||||
D3DDevice *pD3dDevice = vid->d3d_render_device;
|
||||
|
||||
// Save state
|
||||
if( font->m_bSaveState )
|
||||
{
|
||||
// Note, we are not saving the texture, vertex, or pixel shader,
|
||||
// since it's not worth the performance. We're more interested
|
||||
// in saving state that would cause hard to find problems.
|
||||
pD3dDevice->GetRenderState( D3DRS_ALPHABLENDENABLE,
|
||||
&font->m_dwSavedState[ SAVEDSTATE_D3DRS_ALPHABLENDENABLE ] );
|
||||
pD3dDevice->GetRenderState( D3DRS_SRCBLEND, &font->m_dwSavedState[ SAVEDSTATE_D3DRS_SRCBLEND ] );
|
||||
pD3dDevice->GetRenderState( D3DRS_DESTBLEND, &font->m_dwSavedState[ SAVEDSTATE_D3DRS_DESTBLEND ] );
|
||||
pD3dDevice->GetRenderState( D3DRS_BLENDOP, &font->m_dwSavedState[ SAVEDSTATE_D3DRS_BLENDOP ] );
|
||||
pD3dDevice->GetRenderState( D3DRS_ALPHATESTENABLE, &font->m_dwSavedState[ SAVEDSTATE_D3DRS_ALPHATESTENABLE ] );
|
||||
pD3dDevice->GetRenderState( D3DRS_ALPHAREF, &font->m_dwSavedState[ SAVEDSTATE_D3DRS_ALPHAREF ] );
|
||||
pD3dDevice->GetRenderState( D3DRS_ALPHAFUNC, &font->m_dwSavedState[ SAVEDSTATE_D3DRS_ALPHAFUNC ] );
|
||||
pD3dDevice->GetRenderState( D3DRS_FILLMODE, &font->m_dwSavedState[ SAVEDSTATE_D3DRS_FILLMODE ] );
|
||||
pD3dDevice->GetRenderState( D3DRS_CULLMODE, &font->m_dwSavedState[ SAVEDSTATE_D3DRS_CULLMODE ] );
|
||||
pD3dDevice->GetRenderState( D3DRS_VIEWPORTENABLE, &font->m_dwSavedState[ SAVEDSTATE_D3DRS_VIEWPORTENABLE ] );
|
||||
font->m_dwSavedState[ SAVEDSTATE_D3DSAMP_MINFILTER ] = D3DDevice_GetSamplerState_MinFilter( pD3dDevice, 0 );
|
||||
font->m_dwSavedState[ SAVEDSTATE_D3DSAMP_MAGFILTER ] = D3DDevice_GetSamplerState_MagFilter( pD3dDevice, 0 );
|
||||
font->m_dwSavedState[ SAVEDSTATE_D3DSAMP_ADDRESSU ] = D3DDevice_GetSamplerState_AddressU( pD3dDevice, 0);
|
||||
font->m_dwSavedState[ SAVEDSTATE_D3DSAMP_ADDRESSV ] = D3DDevice_GetSamplerState_AddressV( pD3dDevice, 0);
|
||||
}
|
||||
|
||||
// Set the texture scaling factor as a vertex shader constant
|
||||
D3DSURFACE_DESC TextureDesc;
|
||||
D3DTexture_GetLevelDesc(font->m_pFontTexture, 0, &TextureDesc); // Get the description
|
||||
|
||||
// Set render state
|
||||
D3DDevice_SetTexture_Inline(pD3dDevice, 0, font->m_pFontTexture);
|
||||
|
||||
// Read the TextureDesc here to ensure no load/hit/store from GetLevelDesc()
|
||||
float vTexScale[4];
|
||||
vTexScale[0] = 1.0f / TextureDesc.Width; // LHS due to int->float conversion
|
||||
vTexScale[1] = 1.0f / TextureDesc.Height;
|
||||
vTexScale[2] = 0.0f;
|
||||
vTexScale[3] = 0.0f;
|
||||
|
||||
D3DDevice_SetRenderState_AlphaBlendEnable( pD3dDevice, TRUE );
|
||||
D3DDevice_SetRenderState_SrcBlend(pD3dDevice, D3DBLEND_SRCALPHA );
|
||||
D3DDevice_SetRenderState_DestBlend( pD3dDevice, D3DBLEND_INVSRCALPHA );
|
||||
D3DDevice_SetRenderState_BlendOp( pD3dDevice, D3DBLENDOP_ADD );
|
||||
pD3dDevice->SetRenderState( D3DRS_ALPHATESTENABLE, TRUE );
|
||||
pD3dDevice->SetRenderState( D3DRS_ALPHAREF, 0x08 );
|
||||
pD3dDevice->SetRenderState( D3DRS_ALPHAFUNC, D3DCMP_GREATEREQUAL );
|
||||
pD3dDevice->SetRenderState( D3DRS_FILLMODE, D3DFILL_SOLID );
|
||||
pD3dDevice->SetRenderState( D3DRS_CULLMODE, D3DCULL_CCW );
|
||||
pD3dDevice->SetRenderState( D3DRS_VIEWPORTENABLE, FALSE );
|
||||
D3DDevice_SetSamplerState_MinFilter(pD3dDevice, 0, D3DTEXF_LINEAR );
|
||||
D3DDevice_SetSamplerState_MagFilter(pD3dDevice, 0, D3DTEXF_LINEAR );
|
||||
D3DDevice_SetSamplerState_AddressU_Inline(pD3dDevice, 0, D3DTADDRESS_CLAMP );
|
||||
D3DDevice_SetSamplerState_AddressV_Inline(pD3dDevice, 0, D3DTADDRESS_CLAMP );
|
||||
|
||||
D3DDevice_SetVertexDeclaration(pD3dDevice, s_FontLocals.m_pFontVertexDecl );
|
||||
D3DDevice_SetVertexShader(pD3dDevice, s_FontLocals.m_pFontVertexShader );
|
||||
D3DDevice_SetPixelShader(pD3dDevice, s_FontLocals.m_pFontPixelShader );
|
||||
|
||||
// Set the texture scaling factor as a vertex shader constant
|
||||
// Call here to avoid load hit store from writing to vTexScale above
|
||||
pD3dDevice->SetVertexShaderConstantF( 2, vTexScale, 1 );
|
||||
}
|
||||
|
||||
// Keep track of the nested begin/end calls.
|
||||
font->m_dwNestedBeginCount++;
|
||||
}
|
||||
|
||||
void xdk360_video_font_end(xdk360_video_font_t * font)
|
||||
{
|
||||
if( --font->m_dwNestedBeginCount > 0 )
|
||||
return;
|
||||
|
||||
// Restore state
|
||||
if( font->m_bSaveState )
|
||||
{
|
||||
// Cache the global pointer into a register
|
||||
xdk360_video_t *vid = (xdk360_video_t*)driver.video_data;
|
||||
D3DDevice *pD3dDevice = vid->d3d_render_device;
|
||||
|
||||
D3DDevice_SetTexture_Inline(pD3dDevice, 0, NULL);
|
||||
D3DDevice_SetVertexDeclaration(pD3dDevice, NULL);
|
||||
D3DDevice_SetVertexShader(pD3dDevice, NULL );
|
||||
D3DDevice_SetPixelShader(pD3dDevice, NULL );
|
||||
D3DDevice_SetRenderState_AlphaBlendEnable(pD3dDevice, font->m_dwSavedState[ SAVEDSTATE_D3DRS_ALPHABLENDENABLE ]);
|
||||
D3DDevice_SetRenderState_SrcBlend(pD3dDevice, font->m_dwSavedState[ SAVEDSTATE_D3DRS_SRCBLEND ] );
|
||||
D3DDevice_SetRenderState_DestBlend( pD3dDevice, font->m_dwSavedState[ SAVEDSTATE_D3DRS_DESTBLEND ] );
|
||||
D3DDevice_SetRenderState_BlendOp( pD3dDevice, font->m_dwSavedState[ SAVEDSTATE_D3DRS_BLENDOP ] );
|
||||
pD3dDevice->SetRenderState( D3DRS_ALPHATESTENABLE, font->m_dwSavedState[ SAVEDSTATE_D3DRS_ALPHATESTENABLE ] );
|
||||
pD3dDevice->SetRenderState( D3DRS_ALPHAREF, font->m_dwSavedState[ SAVEDSTATE_D3DRS_ALPHAREF ] );
|
||||
pD3dDevice->SetRenderState( D3DRS_ALPHAFUNC, font->m_dwSavedState[ SAVEDSTATE_D3DRS_ALPHAFUNC ] );
|
||||
pD3dDevice->SetRenderState( D3DRS_FILLMODE, font->m_dwSavedState[ SAVEDSTATE_D3DRS_FILLMODE ] );
|
||||
pD3dDevice->SetRenderState( D3DRS_CULLMODE, font->m_dwSavedState[ SAVEDSTATE_D3DRS_CULLMODE ] );
|
||||
pD3dDevice->SetRenderState( D3DRS_VIEWPORTENABLE, font->m_dwSavedState[ SAVEDSTATE_D3DRS_VIEWPORTENABLE ] );
|
||||
D3DDevice_SetSamplerState_MinFilter(pD3dDevice, 0, font->m_dwSavedState[ SAVEDSTATE_D3DSAMP_MINFILTER ] );
|
||||
D3DDevice_SetSamplerState_MagFilter(pD3dDevice, 0, font->m_dwSavedState[ SAVEDSTATE_D3DSAMP_MAGFILTER ] );
|
||||
D3DDevice_SetSamplerState_AddressU_Inline(pD3dDevice, 0, font->m_dwSavedState[ SAVEDSTATE_D3DSAMP_ADDRESSU ] );
|
||||
D3DDevice_SetSamplerState_AddressV_Inline(pD3dDevice, 0, font->m_dwSavedState[ SAVEDSTATE_D3DSAMP_ADDRESSV ] );
|
||||
}
|
||||
}
|
||||
+111
@@ -0,0 +1,111 @@
|
||||
/* RetroArch - A frontend for libretro.
|
||||
* Copyright (C) 2010-2012 - Hans-Kristian Arntzen
|
||||
* Copyright (C) 2011-2012 - Daniel De Matteis
|
||||
*
|
||||
* RetroArch is free software: you can redistribute it and/or modify it under the terms
|
||||
* of the GNU General Public License as published by the Free Software Found-
|
||||
* ation, either version 3 of the License, or (at your option) any later version.
|
||||
*
|
||||
* RetroArch is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
|
||||
* without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
|
||||
* PURPOSE. See the GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along with RetroArch.
|
||||
* If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifndef RARCH_360_FONTS_H
|
||||
#define RARCH_360_FONTS_H
|
||||
|
||||
#include "xdk360_video_resources.h"
|
||||
|
||||
#define PAGE_UP (255)
|
||||
#define PAGE_DOWN (-255)
|
||||
|
||||
#define SCREEN_SIZE_X_DEFAULT 640
|
||||
#define SCREEN_SIZE_Y_DEFAULT 480
|
||||
|
||||
#define SAFE_AREA_PCT_4x3 85
|
||||
#define SAFE_AREA_PCT_HDTV 90
|
||||
|
||||
typedef struct
|
||||
{
|
||||
float m_fLineHeight; // height of a single line in pixels
|
||||
unsigned int m_nScrollOffset; // offset to display text (in lines)
|
||||
unsigned int first_message;
|
||||
unsigned int m_cxSafeArea;
|
||||
unsigned int m_cySafeArea;
|
||||
unsigned int m_cxSafeAreaOffset;
|
||||
unsigned int m_cySafeAreaOffset;
|
||||
unsigned int m_nCurLine; // index of current line being written to
|
||||
unsigned int m_cCurLineLength; // length of the current line
|
||||
unsigned long m_colBackColor;
|
||||
unsigned long m_colTextColor;
|
||||
unsigned int m_cScreenHeight; // height in lines of screen area
|
||||
unsigned int m_cScreenHeightVirtual; // height in lines of text storage buffer
|
||||
unsigned int m_cScreenWidth; // width in characters
|
||||
wchar_t * m_Buffer; // buffer big enough to hold a full screen
|
||||
wchar_t ** m_Lines; // pointers to individual lines
|
||||
} video_console_t;
|
||||
|
||||
typedef struct GLYPH_ATTR
|
||||
{
|
||||
unsigned short tu1, tv1, tu2, tv2; // Texture coordinates for the image
|
||||
short wOffset; // Pixel offset for glyph start
|
||||
short wWidth; // Pixel width of the glyph
|
||||
short wAdvance; // Pixels to advance after the glyph
|
||||
unsigned short wMask; // Channel mask
|
||||
} GLYPH_ATTR;
|
||||
|
||||
enum SavedStates
|
||||
{
|
||||
SAVEDSTATE_D3DRS_ALPHABLENDENABLE,
|
||||
SAVEDSTATE_D3DRS_SRCBLEND,
|
||||
SAVEDSTATE_D3DRS_DESTBLEND,
|
||||
SAVEDSTATE_D3DRS_BLENDOP,
|
||||
SAVEDSTATE_D3DRS_ALPHATESTENABLE,
|
||||
SAVEDSTATE_D3DRS_ALPHAREF,
|
||||
SAVEDSTATE_D3DRS_ALPHAFUNC,
|
||||
SAVEDSTATE_D3DRS_FILLMODE,
|
||||
SAVEDSTATE_D3DRS_CULLMODE,
|
||||
SAVEDSTATE_D3DRS_ZENABLE,
|
||||
SAVEDSTATE_D3DRS_STENCILENABLE,
|
||||
SAVEDSTATE_D3DRS_VIEWPORTENABLE,
|
||||
SAVEDSTATE_D3DSAMP_MINFILTER,
|
||||
SAVEDSTATE_D3DSAMP_MAGFILTER,
|
||||
SAVEDSTATE_D3DSAMP_ADDRESSU,
|
||||
SAVEDSTATE_D3DSAMP_ADDRESSV,
|
||||
|
||||
SAVEDSTATE_COUNT
|
||||
};
|
||||
|
||||
typedef struct
|
||||
{
|
||||
unsigned int m_bSaveState;
|
||||
unsigned long m_dwSavedState[ SAVEDSTATE_COUNT ];
|
||||
unsigned long m_dwNestedBeginCount;
|
||||
unsigned long m_cMaxGlyph; // Number of entries in the translator table
|
||||
unsigned long m_dwNumGlyphs; // Number of valid glyphs
|
||||
float m_fFontHeight; // Height of the font strike in pixels
|
||||
float m_fFontTopPadding; // Padding above the strike zone
|
||||
float m_fFontBottomPadding; // Padding below the strike zone
|
||||
float m_fFontYAdvance; // Number of pixels to move the cursor for a line feed
|
||||
float m_fXScaleFactor; // Scaling constants
|
||||
float m_fYScaleFactor;
|
||||
float m_fCursorX; // Current text cursor
|
||||
float m_fCursorY;
|
||||
D3DRECT m_rcWindow; // Bounds rect of the text window, modify via accessors only!
|
||||
wchar_t * m_TranslatorTable; // ASCII to glyph lookup table
|
||||
D3DTexture* m_pFontTexture;
|
||||
const GLYPH_ATTR* m_Glyphs; // Array of glyphs
|
||||
} xdk360_video_font_t;
|
||||
|
||||
HRESULT xdk360_console_init ( LPCSTR strFontFileName, D3DCOLOR colBackColor, D3DCOLOR colTextColor);
|
||||
void xdk360_console_deinit (void);
|
||||
void xdk360_console_format (LPCSTR strFormat, ... );
|
||||
void xdk360_console_draw (void);
|
||||
|
||||
void xdk360_video_font_begin (xdk360_video_font_t * font);
|
||||
void xdk360_video_font_end (xdk360_video_font_t * font);
|
||||
|
||||
#endif
|
||||
+330
@@ -0,0 +1,330 @@
|
||||
/* RetroArch - A frontend for libretro.
|
||||
* Copyright (C) 2010-2012 - Hans-Kristian Arntzen
|
||||
* Copyright (C) 2011-2012 - Daniel De Matteis
|
||||
*
|
||||
* RetroArch is free software: you can redistribute it and/or modify it under the terms
|
||||
* of the GNU General Public License as published by the Free Software Found-
|
||||
* ation, either version 3 of the License, or (at your option) any later version.
|
||||
*
|
||||
* RetroArch is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
|
||||
* without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
|
||||
* PURPOSE. See the GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along with RetroArch.
|
||||
* If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include <xtl.h>
|
||||
#include <xfilecache.h>
|
||||
#include <stddef.h>
|
||||
#include <stdint.h>
|
||||
#include <string>
|
||||
#include <xbdm.h>
|
||||
#include "menu.h"
|
||||
#include "xdk360_input.h"
|
||||
#include "xdk360_video.h"
|
||||
|
||||
#include "../console/console_ext.h"
|
||||
#include "../conf/config_file.h"
|
||||
#include "../conf/config_file_macros.h"
|
||||
#include "../file.h"
|
||||
#include "../general.h"
|
||||
|
||||
#define DEVICE_MEMORY_UNIT0 1
|
||||
#define DEVICE_MEMORY_UNIT1 2
|
||||
#define DEVICE_MEMORY_ONBOARD 3
|
||||
#define DEVICE_CDROM0 4
|
||||
#define DEVICE_HARDISK0_PART1 5
|
||||
#define DEVICE_HARDISK0_SYSPART 6
|
||||
#define DEVICE_USB0 7
|
||||
#define DEVICE_USB1 8
|
||||
#define DEVICE_USB2 9
|
||||
#define DEVICE_TEST 10
|
||||
#define DEVICE_CACHE 11
|
||||
|
||||
typedef struct _STRING {
|
||||
unsigned short Length;
|
||||
unsigned short MaximumLength;
|
||||
char * Buffer;
|
||||
} STRING;
|
||||
|
||||
char DEFAULT_SHADER_FILE[PATH_MAX];
|
||||
char SYS_CONFIG_FILE[PATH_MAX];
|
||||
|
||||
extern "C" int __stdcall ObCreateSymbolicLink( STRING*, STRING*);
|
||||
|
||||
int Mounted[20];
|
||||
|
||||
int rarch_main(int argc, char *argv[]);
|
||||
|
||||
#undef main
|
||||
|
||||
static int DriveMounted(std::string path)
|
||||
{
|
||||
WIN32_FIND_DATA findFileData;
|
||||
memset(&findFileData,0,sizeof(WIN32_FIND_DATA));
|
||||
std::string searchcmd = path + "\\*.*";
|
||||
HANDLE hFind = FindFirstFile(searchcmd.c_str(), &findFileData);
|
||||
|
||||
if (hFind == INVALID_HANDLE_VALUE)
|
||||
return 0;
|
||||
|
||||
FindClose(hFind);
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
static int Mount( int Device, char* MountPoint )
|
||||
{
|
||||
char MountConv[260];
|
||||
char * SysPath = NULL;
|
||||
|
||||
snprintf( MountConv, sizeof(MountConv), "\\??\\%s", MountPoint );
|
||||
|
||||
switch( Device )
|
||||
{
|
||||
case DEVICE_MEMORY_UNIT0:
|
||||
SysPath = "\\Device\\Mu0";
|
||||
break;
|
||||
case DEVICE_MEMORY_UNIT1:
|
||||
SysPath = "\\Device\\Mu1";
|
||||
break;
|
||||
case DEVICE_MEMORY_ONBOARD:
|
||||
SysPath = "\\Device\\BuiltInMuSfc";
|
||||
break;
|
||||
case DEVICE_CDROM0:
|
||||
SysPath = "\\Device\\Cdrom0";
|
||||
break;
|
||||
case DEVICE_HARDISK0_PART1:
|
||||
SysPath = "\\Device\\Harddisk0\\Partition1";
|
||||
break;
|
||||
case DEVICE_HARDISK0_SYSPART:
|
||||
SysPath = "\\Device\\Harddisk0\\SystemPartition";
|
||||
break;
|
||||
case DEVICE_USB0:
|
||||
SysPath = "\\Device\\Mass0";
|
||||
break;
|
||||
case DEVICE_USB1:
|
||||
SysPath = "\\Device\\Mass1";
|
||||
break;
|
||||
case DEVICE_USB2:
|
||||
SysPath = "\\Device\\Mass2";
|
||||
break;
|
||||
case DEVICE_CACHE:
|
||||
SysPath = "\\Device\\Harddisk0\\Cache0";
|
||||
break;
|
||||
}
|
||||
|
||||
STRING sSysPath = { (USHORT)strlen( SysPath ), (USHORT)strlen( SysPath ) + 1, SysPath };
|
||||
STRING sMountConv = { (USHORT)strlen( MountConv ), (USHORT)strlen( MountConv ) + 1, MountConv };
|
||||
int res = ObCreateSymbolicLink( &sMountConv, &sSysPath );
|
||||
|
||||
if (res != 0)
|
||||
return res;
|
||||
|
||||
return DriveMounted(MountPoint);
|
||||
}
|
||||
|
||||
static void set_default_settings (void)
|
||||
{
|
||||
//g_settings
|
||||
g_settings.rewind_enable = false;
|
||||
strlcpy(g_settings.video.cg_shader_path, DEFAULT_SHADER_FILE, sizeof(g_settings.video.cg_shader_path));
|
||||
g_settings.video.fbo_scale_x = 2.0f;
|
||||
g_settings.video.fbo_scale_y = 2.0f;
|
||||
g_settings.video.render_to_texture = true;
|
||||
strlcpy(g_settings.video.second_pass_shader, DEFAULT_SHADER_FILE, sizeof(g_settings.video.second_pass_shader));
|
||||
g_settings.video.second_pass_smooth = true;
|
||||
g_settings.video.smooth = true;
|
||||
g_settings.video.vsync = true;
|
||||
g_settings.video.aspect_ratio = -1.0f;
|
||||
|
||||
rarch_default_keybind_lut[RETRO_DEVICE_ID_JOYPAD_B] = platform_keys[XDK360_DEVICE_ID_JOYPAD_A].joykey;
|
||||
rarch_default_keybind_lut[RETRO_DEVICE_ID_JOYPAD_Y] = platform_keys[XDK360_DEVICE_ID_JOYPAD_X].joykey;
|
||||
rarch_default_keybind_lut[RETRO_DEVICE_ID_JOYPAD_SELECT] = platform_keys[XDK360_DEVICE_ID_JOYPAD_BACK].joykey;
|
||||
rarch_default_keybind_lut[RETRO_DEVICE_ID_JOYPAD_START] = platform_keys[XDK360_DEVICE_ID_JOYPAD_START].joykey;
|
||||
rarch_default_keybind_lut[RETRO_DEVICE_ID_JOYPAD_UP] = platform_keys[XDK360_DEVICE_ID_JOYPAD_UP].joykey;
|
||||
rarch_default_keybind_lut[RETRO_DEVICE_ID_JOYPAD_DOWN] = platform_keys[XDK360_DEVICE_ID_JOYPAD_DOWN].joykey;
|
||||
rarch_default_keybind_lut[RETRO_DEVICE_ID_JOYPAD_LEFT] = platform_keys[XDK360_DEVICE_ID_JOYPAD_LEFT].joykey;
|
||||
rarch_default_keybind_lut[RETRO_DEVICE_ID_JOYPAD_RIGHT] = platform_keys[XDK360_DEVICE_ID_JOYPAD_RIGHT].joykey;
|
||||
rarch_default_keybind_lut[RETRO_DEVICE_ID_JOYPAD_A] = platform_keys[XDK360_DEVICE_ID_JOYPAD_B].joykey;
|
||||
rarch_default_keybind_lut[RETRO_DEVICE_ID_JOYPAD_X] = platform_keys[XDK360_DEVICE_ID_JOYPAD_Y].joykey;
|
||||
rarch_default_keybind_lut[RETRO_DEVICE_ID_JOYPAD_L] = platform_keys[XDK360_DEVICE_ID_JOYPAD_LB].joykey;
|
||||
rarch_default_keybind_lut[RETRO_DEVICE_ID_JOYPAD_R] = platform_keys[XDK360_DEVICE_ID_JOYPAD_RB].joykey;
|
||||
rarch_default_keybind_lut[RETRO_DEVICE_ID_JOYPAD_L2] = platform_keys[XDK360_DEVICE_ID_JOYPAD_LEFT_TRIGGER].joykey;
|
||||
rarch_default_keybind_lut[RETRO_DEVICE_ID_JOYPAD_R2] = platform_keys[XDK360_DEVICE_ID_JOYPAD_RIGHT_TRIGGER].joykey;
|
||||
rarch_default_keybind_lut[RETRO_DEVICE_ID_JOYPAD_L3] = platform_keys[XDK360_DEVICE_ID_LSTICK_THUMB].joykey;
|
||||
rarch_default_keybind_lut[RETRO_DEVICE_ID_JOYPAD_R3] = platform_keys[XDK360_DEVICE_ID_RSTICK_THUMB].joykey;
|
||||
|
||||
for(uint32_t x = 0; x < MAX_PLAYERS; x++)
|
||||
rarch_input_set_default_keybinds(x);
|
||||
|
||||
//g_console
|
||||
g_console.block_config_read = true;
|
||||
g_console.frame_advance_enable = false;
|
||||
g_console.emulator_initialized = 0;
|
||||
g_console.gamma_correction_enable = true;
|
||||
g_console.initialize_rarch_enable = false;
|
||||
g_console.fbo_enabled = true;
|
||||
g_console.mode_switch = MODE_MENU;
|
||||
g_console.screen_orientation = ORIENTATION_NORMAL;
|
||||
g_console.throttle_enable = true;
|
||||
g_console.aspect_ratio_index = 0;
|
||||
strlcpy(g_console.default_rom_startup_dir, "game:", sizeof(g_console.default_rom_startup_dir));
|
||||
g_console.viewports.custom_vp.width = 0;
|
||||
g_console.viewports.custom_vp.height = 0;
|
||||
g_console.viewports.custom_vp.x = 0;
|
||||
g_console.viewports.custom_vp.y = 0;
|
||||
g_console.color_format = 0;
|
||||
g_console.info_msg_enable = true;
|
||||
|
||||
//g_extern
|
||||
g_extern.state_slot = 0;
|
||||
g_extern.audio_data.mute = 0;
|
||||
g_extern.verbose = true;
|
||||
}
|
||||
|
||||
static void get_environment_settings (void)
|
||||
{
|
||||
DWORD ret;
|
||||
|
||||
//for devkits only, we will need to mount all partitions for retail
|
||||
//in a different way
|
||||
//DmMapDevkitDrive();
|
||||
|
||||
memset(&Mounted, 0, 20);
|
||||
|
||||
Mounted[DEVICE_USB0] = Mount(DEVICE_USB0,"Usb0:");
|
||||
Mounted[DEVICE_USB1] = Mount(DEVICE_USB1,"Usb1:");
|
||||
Mounted[DEVICE_USB2] = Mount(DEVICE_USB2,"Usb2:");
|
||||
Mounted[DEVICE_HARDISK0_PART1] = Mount(DEVICE_HARDISK0_PART1,"Hdd1:");
|
||||
Mounted[DEVICE_HARDISK0_SYSPART] = Mount(DEVICE_HARDISK0_SYSPART,"HddX:");
|
||||
Mounted[DEVICE_MEMORY_UNIT0] = Mount(DEVICE_MEMORY_UNIT0,"Memunit0:");
|
||||
Mounted[DEVICE_MEMORY_UNIT1] = Mount(DEVICE_MEMORY_UNIT1,"Memunit1:");
|
||||
Mounted[DEVICE_MEMORY_ONBOARD] = Mount(DEVICE_MEMORY_ONBOARD,"OnBoardMU:");
|
||||
Mounted[DEVICE_CDROM0] = Mount(DEVICE_CDROM0,"Dvd:");
|
||||
|
||||
ret = XSetFileCacheSize(0x100000);
|
||||
|
||||
if(ret != TRUE)
|
||||
{
|
||||
RARCH_ERR("Couldn't change number of bytes reserved for file system cache.\n");
|
||||
}
|
||||
|
||||
ret = XFileCacheInit(XFILECACHE_CLEAR_ALL, 0x100000, XFILECACHE_DEFAULT_THREAD, 0, 1);
|
||||
|
||||
if(ret != ERROR_SUCCESS)
|
||||
{
|
||||
RARCH_ERR("File cache could not be initialized.\n");
|
||||
}
|
||||
|
||||
XFlushUtilityDrive();
|
||||
//unsigned long result = XMountUtilityDriveEx(XMOUNTUTILITYDRIVE_FORMAT0,8192, 0);
|
||||
|
||||
//if(result != ERROR_SUCCESS)
|
||||
//{
|
||||
// RARCH_ERR("Couldn't mount/format utility drive.\n");
|
||||
//}
|
||||
|
||||
// detect install environment
|
||||
unsigned long license_mask;
|
||||
|
||||
if (XContentGetLicenseMask(&license_mask, NULL) != ERROR_SUCCESS)
|
||||
{
|
||||
printf("RetroArch was launched as a standalone DVD, or using DVD emulation, or from the development area of the HDD.\n");
|
||||
}
|
||||
else
|
||||
{
|
||||
XContentQueryVolumeDeviceType("GAME",&g_console.volume_device_type, NULL);
|
||||
|
||||
switch(g_console.volume_device_type)
|
||||
{
|
||||
case XCONTENTDEVICETYPE_HDD:
|
||||
printf("RetroArch was launched from a content package on HDD.\n");
|
||||
break;
|
||||
case XCONTENTDEVICETYPE_MU:
|
||||
printf("RetroArch was launched from a content package on USB or Memory Unit.\n");
|
||||
break;
|
||||
case XCONTENTDEVICETYPE_ODD:
|
||||
printf("RetroArch was launched from a content package on Optical Disc Drive.\n");
|
||||
break;
|
||||
default:
|
||||
printf("RetroArch was launched from a content package on an unknown device type.\n");
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
strlcpy(DEFAULT_SHADER_FILE, "game:\\media\\shaders\\stock.cg", sizeof(DEFAULT_SHADER_FILE));
|
||||
strlcpy(SYS_CONFIG_FILE, "game:\\retroarch.cfg", sizeof(SYS_CONFIG_FILE));
|
||||
}
|
||||
|
||||
int main(int argc, char *argv[])
|
||||
{
|
||||
get_environment_settings();
|
||||
|
||||
rarch_main_clear_state();
|
||||
config_set_defaults();
|
||||
|
||||
char full_path[1024];
|
||||
snprintf(full_path, sizeof(full_path), "game:\\CORE.xex");
|
||||
|
||||
g_extern.verbose = true;
|
||||
|
||||
const char *libretro_core_installed = rarch_manage_libretro_install(full_path, "game:\\", ".xex");
|
||||
|
||||
g_extern.verbose = false;
|
||||
|
||||
bool find_libretro_file = false;
|
||||
|
||||
if(libretro_core_installed != NULL)
|
||||
strlcpy(g_settings.libretro, libretro_core_installed, sizeof(g_settings.libretro));
|
||||
else
|
||||
find_libretro_file = true;
|
||||
|
||||
set_default_settings();
|
||||
rarch_config_load(SYS_CONFIG_FILE, "game:\\", ".xex", find_libretro_file);
|
||||
init_libretro_sym();
|
||||
|
||||
video_xdk360.start();
|
||||
input_xdk360.init();
|
||||
|
||||
rarch_input_set_default_keybind_names_for_emulator();
|
||||
|
||||
menu_init();
|
||||
|
||||
begin_loop:
|
||||
if(g_console.mode_switch == MODE_EMULATION)
|
||||
{
|
||||
bool repeat = false;
|
||||
|
||||
input_xdk360.poll(NULL);
|
||||
|
||||
rarch_set_auto_viewport(g_extern.frame_cache.width, g_extern.frame_cache.height);
|
||||
|
||||
do{
|
||||
repeat = rarch_main_iterate();
|
||||
}while(repeat && !g_console.frame_advance_enable);
|
||||
}
|
||||
else if(g_console.mode_switch == MODE_MENU)
|
||||
{
|
||||
menu_loop();
|
||||
rarch_startup(SYS_CONFIG_FILE);
|
||||
}
|
||||
else
|
||||
goto begin_shutdown;
|
||||
|
||||
goto begin_loop;
|
||||
|
||||
begin_shutdown:
|
||||
if(path_file_exists(SYS_CONFIG_FILE))
|
||||
rarch_config_save(SYS_CONFIG_FILE);
|
||||
|
||||
menu_deinit();
|
||||
video_xdk360.stop();
|
||||
input_xdk360.free(NULL);
|
||||
rarch_exec();
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
Binary file not shown.
@@ -0,0 +1,18 @@
|
||||
<?xml version="1.0" encoding="utf-8" ?>
|
||||
|
||||
<RDF Version="XPR2">
|
||||
|
||||
<Texture
|
||||
Name = "FontTexture"
|
||||
Source = "Arial_12.tga"
|
||||
Format = "D3DFMT_LIN_A4R4G4B4"
|
||||
Levels = "1"
|
||||
/>
|
||||
|
||||
<UserData
|
||||
Name = "FontData"
|
||||
DataFile = "Arial_12.abc"
|
||||
/>
|
||||
|
||||
</RDF>
|
||||
|
||||
Binary file not shown.
|
After Width: | Height: | Size: 256 KiB |
Binary file not shown.
|
After Width: | Height: | Size: 2.3 KiB |
Binary file not shown.
|
After Width: | Height: | Size: 2.3 KiB |
@@ -0,0 +1,303 @@
|
||||
<XuiCanvas version="000c">
|
||||
<Properties>
|
||||
<Width>1280.000000</Width>
|
||||
<Height>720.000000</Height>
|
||||
</Properties>
|
||||
<XuiScene>
|
||||
<Properties>
|
||||
<Id>XuiScene1</Id>
|
||||
<Width>776.000061</Width>
|
||||
<Height>512.000061</Height>
|
||||
<Position>200.000015,112.000008,0.000000</Position>
|
||||
<ClassOverride>RetroArchControls</ClassOverride>
|
||||
</Properties>
|
||||
<XuiText>
|
||||
<Properties>
|
||||
<Id>XuiTxtTitle</Id>
|
||||
<Width>121.056023</Width>
|
||||
<Height>40.000000</Height>
|
||||
<Position>43.581604,21.159988,0.000000</Position>
|
||||
<Text>Controls</Text>
|
||||
<TextColor>0xff0f0f0f</TextColor>
|
||||
<DropShadowColor>0x800f0f0f</DropShadowColor>
|
||||
<Font>Arial Unicode MS</Font>
|
||||
<TextStyle>21</TextStyle>
|
||||
</Properties>
|
||||
</XuiText>
|
||||
<XuiCommonList>
|
||||
<Properties>
|
||||
<Id>XuiControlsList</Id>
|
||||
<Width>683.120056</Width>
|
||||
<Height>360.000000</Height>
|
||||
<Position>44.880005,88.000015,0.000000</Position>
|
||||
<NavUp>XuiControlNoSlider</NavUp>
|
||||
<ItemsText>RetroPad Button B:
|
||||
RetroPad Button Y:
|
||||
RetroPad Button Select:
|
||||
RetroPad Button Start:
|
||||
RetroPad D-Pad Up:
|
||||
RetroPad D-Pad Down:
|
||||
RetroPad D-Pad Left:
|
||||
RetroPad D-Pad Right:
|
||||
RetroPad Button A:
|
||||
RetroPad Button X:
|
||||
RetroPad Button L1:
|
||||
RetroPad Button R1:
|
||||
RetroPad Button L2:
|
||||
RetroPad Button R2:
|
||||
RetroPad Button L3:
|
||||
RetroPad Button R3:
|
||||
Reset all buttons to default
|
||||
</ItemsText>
|
||||
</Properties>
|
||||
<XuiListItem>
|
||||
<Properties>
|
||||
<Id>control_ListItem</Id>
|
||||
<Width>226.000000</Width>
|
||||
<Height>45.000000</Height>
|
||||
<Position>7.000000,22.000000,0.000000</Position>
|
||||
<Anchor>5</Anchor>
|
||||
<Show>false</Show>
|
||||
<Visual>XuiButton</Visual>
|
||||
<InterItemSpacing>0.000000,10.000000,0.000000</InterItemSpacing>
|
||||
</Properties>
|
||||
</XuiListItem>
|
||||
<XuiListItem>
|
||||
<Properties>
|
||||
<Id>control_ListItem</Id>
|
||||
<Width>226.000000</Width>
|
||||
<Height>45.000000</Height>
|
||||
<Position>7.000000,22.000000,0.000000</Position>
|
||||
<Anchor>5</Anchor>
|
||||
<Show>false</Show>
|
||||
<Visual>XuiButton</Visual>
|
||||
<InterItemSpacing>0.000000,10.000000,0.000000</InterItemSpacing>
|
||||
</Properties>
|
||||
</XuiListItem>
|
||||
<XuiListItem>
|
||||
<Properties>
|
||||
<Id>control_ListItem</Id>
|
||||
<Width>226.000000</Width>
|
||||
<Height>45.000000</Height>
|
||||
<Position>7.000000,22.000000,0.000000</Position>
|
||||
<Anchor>5</Anchor>
|
||||
<Show>false</Show>
|
||||
<Visual>XuiButton</Visual>
|
||||
<InterItemSpacing>0.000000,10.000000,0.000000</InterItemSpacing>
|
||||
</Properties>
|
||||
</XuiListItem>
|
||||
<XuiListItem>
|
||||
<Properties>
|
||||
<Id>control_ListItem</Id>
|
||||
<Width>226.000000</Width>
|
||||
<Height>45.000000</Height>
|
||||
<Position>7.000000,22.000000,0.000000</Position>
|
||||
<Anchor>5</Anchor>
|
||||
<Show>false</Show>
|
||||
<Visual>XuiButton</Visual>
|
||||
<InterItemSpacing>0.000000,10.000000,0.000000</InterItemSpacing>
|
||||
</Properties>
|
||||
</XuiListItem>
|
||||
<XuiListItem>
|
||||
<Properties>
|
||||
<Id>control_ListItem</Id>
|
||||
<Width>226.000000</Width>
|
||||
<Height>45.000000</Height>
|
||||
<Position>7.000000,22.000000,0.000000</Position>
|
||||
<Anchor>5</Anchor>
|
||||
<Show>false</Show>
|
||||
<Visual>XuiButton</Visual>
|
||||
<InterItemSpacing>0.000000,10.000000,0.000000</InterItemSpacing>
|
||||
</Properties>
|
||||
</XuiListItem>
|
||||
<XuiListItem>
|
||||
<Properties>
|
||||
<Id>control_ListItem</Id>
|
||||
<Width>226.000000</Width>
|
||||
<Height>45.000000</Height>
|
||||
<Position>7.000000,22.000000,0.000000</Position>
|
||||
<Anchor>5</Anchor>
|
||||
<Show>false</Show>
|
||||
<Visual>XuiButton</Visual>
|
||||
<InterItemSpacing>0.000000,10.000000,0.000000</InterItemSpacing>
|
||||
</Properties>
|
||||
</XuiListItem>
|
||||
<XuiListItem>
|
||||
<Properties>
|
||||
<Id>control_ListItem</Id>
|
||||
<Width>226.000000</Width>
|
||||
<Height>45.000000</Height>
|
||||
<Position>7.000000,22.000000,0.000000</Position>
|
||||
<Anchor>5</Anchor>
|
||||
<Show>false</Show>
|
||||
<Visual>XuiButton</Visual>
|
||||
<InterItemSpacing>0.000000,10.000000,0.000000</InterItemSpacing>
|
||||
</Properties>
|
||||
</XuiListItem>
|
||||
<XuiListItem>
|
||||
<Properties>
|
||||
<Id>control_ListItem</Id>
|
||||
<Width>226.000000</Width>
|
||||
<Height>45.000000</Height>
|
||||
<Position>7.000000,22.000000,0.000000</Position>
|
||||
<Anchor>5</Anchor>
|
||||
<Show>false</Show>
|
||||
<Visual>XuiButton</Visual>
|
||||
<InterItemSpacing>0.000000,10.000000,0.000000</InterItemSpacing>
|
||||
</Properties>
|
||||
</XuiListItem>
|
||||
<XuiListItem>
|
||||
<Properties>
|
||||
<Id>control_ListItem</Id>
|
||||
<Width>226.000000</Width>
|
||||
<Height>45.000000</Height>
|
||||
<Position>7.000000,22.000000,0.000000</Position>
|
||||
<Anchor>5</Anchor>
|
||||
<Show>false</Show>
|
||||
<Visual>XuiButton</Visual>
|
||||
<InterItemSpacing>0.000000,10.000000,0.000000</InterItemSpacing>
|
||||
</Properties>
|
||||
</XuiListItem>
|
||||
<XuiListItem>
|
||||
<Properties>
|
||||
<Id>control_ListItem</Id>
|
||||
<Width>226.000000</Width>
|
||||
<Height>45.000000</Height>
|
||||
<Position>7.000000,22.000000,0.000000</Position>
|
||||
<Anchor>5</Anchor>
|
||||
<Show>false</Show>
|
||||
<Visual>XuiButton</Visual>
|
||||
<InterItemSpacing>0.000000,10.000000,0.000000</InterItemSpacing>
|
||||
</Properties>
|
||||
</XuiListItem>
|
||||
<XuiListItem>
|
||||
<Properties>
|
||||
<Id>control_ListItem</Id>
|
||||
<Width>226.000000</Width>
|
||||
<Height>45.000000</Height>
|
||||
<Position>7.000000,22.000000,0.000000</Position>
|
||||
<Anchor>5</Anchor>
|
||||
<Show>false</Show>
|
||||
<Visual>XuiButton</Visual>
|
||||
<InterItemSpacing>0.000000,10.000000,0.000000</InterItemSpacing>
|
||||
</Properties>
|
||||
</XuiListItem>
|
||||
<XuiListItem>
|
||||
<Properties>
|
||||
<Id>control_ListItem</Id>
|
||||
<Width>226.000000</Width>
|
||||
<Height>45.000000</Height>
|
||||
<Position>7.000000,22.000000,0.000000</Position>
|
||||
<Anchor>5</Anchor>
|
||||
<Show>false</Show>
|
||||
<Visual>XuiButton</Visual>
|
||||
<InterItemSpacing>0.000000,10.000000,0.000000</InterItemSpacing>
|
||||
</Properties>
|
||||
</XuiListItem>
|
||||
<XuiListItem>
|
||||
<Properties>
|
||||
<Id>control_ListItem</Id>
|
||||
<Width>226.000000</Width>
|
||||
<Height>45.000000</Height>
|
||||
<Position>7.000000,22.000000,0.000000</Position>
|
||||
<Anchor>5</Anchor>
|
||||
<Show>false</Show>
|
||||
<Visual>XuiButton</Visual>
|
||||
<InterItemSpacing>0.000000,10.000000,0.000000</InterItemSpacing>
|
||||
</Properties>
|
||||
</XuiListItem>
|
||||
<XuiListItem>
|
||||
<Properties>
|
||||
<Id>control_ListItem</Id>
|
||||
<Width>226.000000</Width>
|
||||
<Height>45.000000</Height>
|
||||
<Position>7.000000,22.000000,0.000000</Position>
|
||||
<Anchor>5</Anchor>
|
||||
<Show>false</Show>
|
||||
<Visual>XuiButton</Visual>
|
||||
<InterItemSpacing>0.000000,10.000000,0.000000</InterItemSpacing>
|
||||
</Properties>
|
||||
</XuiListItem>
|
||||
<XuiListItem>
|
||||
<Properties>
|
||||
<Id>control_ListItem</Id>
|
||||
<Width>226.000000</Width>
|
||||
<Height>45.000000</Height>
|
||||
<Position>7.000000,22.000000,0.000000</Position>
|
||||
<Anchor>5</Anchor>
|
||||
<Show>false</Show>
|
||||
<Visual>XuiButton</Visual>
|
||||
<InterItemSpacing>0.000000,10.000000,0.000000</InterItemSpacing>
|
||||
</Properties>
|
||||
</XuiListItem>
|
||||
<XuiListItem>
|
||||
<Properties>
|
||||
<Id>control_ListItem</Id>
|
||||
<Width>226.000000</Width>
|
||||
<Height>45.000000</Height>
|
||||
<Position>7.000000,22.000000,0.000000</Position>
|
||||
<Anchor>5</Anchor>
|
||||
<Show>false</Show>
|
||||
<Visual>XuiButton</Visual>
|
||||
<InterItemSpacing>0.000000,10.000000,0.000000</InterItemSpacing>
|
||||
</Properties>
|
||||
</XuiListItem>
|
||||
<XuiListItem>
|
||||
<Properties>
|
||||
<Id>control_ListItem</Id>
|
||||
<Width>226.000000</Width>
|
||||
<Height>45.000000</Height>
|
||||
<Position>7.000000,22.000000,0.000000</Position>
|
||||
<Anchor>5</Anchor>
|
||||
<Show>false</Show>
|
||||
<Visual>XuiButton</Visual>
|
||||
<InterItemSpacing>0.000000,10.000000,0.000000</InterItemSpacing>
|
||||
</Properties>
|
||||
</XuiListItem>
|
||||
<XuiListItem>
|
||||
<Properties>
|
||||
<Id>control_ListItem</Id>
|
||||
<Width>226.000000</Width>
|
||||
<Height>45.000000</Height>
|
||||
<Position>7.000000,22.000000,0.000000</Position>
|
||||
<Anchor>5</Anchor>
|
||||
<Show>false</Show>
|
||||
<Visual>XuiButton</Visual>
|
||||
<InterItemSpacing>0.000000,10.000000,0.000000</InterItemSpacing>
|
||||
</Properties>
|
||||
</XuiListItem>
|
||||
<XuiListItem>
|
||||
<Properties>
|
||||
<Id>control_ListItem</Id>
|
||||
<Width>226.000000</Width>
|
||||
<Height>45.000000</Height>
|
||||
<Position>7.000000,22.000000,0.000000</Position>
|
||||
<Anchor>5</Anchor>
|
||||
<Show>false</Show>
|
||||
<Visual>XuiButton</Visual>
|
||||
<InterItemSpacing>0.000000,10.000000,0.000000</InterItemSpacing>
|
||||
</Properties>
|
||||
</XuiListItem>
|
||||
</XuiCommonList>
|
||||
<XuiBackButton>
|
||||
<Properties>
|
||||
<Id>XuiBackButton</Id>
|
||||
<Width>208.632019</Width>
|
||||
<Height>36.000000</Height>
|
||||
<Position>536.000000,448.000000,0.000000</Position>
|
||||
<Text>Go back to menu</Text>
|
||||
<PressKey>22593</PressKey>
|
||||
</Properties>
|
||||
</XuiBackButton>
|
||||
<XuiSlider>
|
||||
<Properties>
|
||||
<Id>XuiControlNoSlider</Id>
|
||||
<Width>102.000000</Width>
|
||||
<Height>60.000000</Height>
|
||||
<Position>618.000061,15.999985,0.000000</Position>
|
||||
<NavDown>XuiControlsList</NavDown>
|
||||
<RangeMax>3</RangeMax>
|
||||
</Properties>
|
||||
</XuiSlider>
|
||||
</XuiScene>
|
||||
</XuiCanvas>
|
||||
@@ -0,0 +1,199 @@
|
||||
<XuiCanvas version="000c">
|
||||
<Properties>
|
||||
<Width>1280.000000</Width>
|
||||
<Height>720.000000</Height>
|
||||
</Properties>
|
||||
<XuiScene>
|
||||
<Properties>
|
||||
<Id>XuiSceneFileBrowser</Id>
|
||||
<Width>1000.000061</Width>
|
||||
<Height>552.000000</Height>
|
||||
<Position>118.000031,88.000015,0.000000</Position>
|
||||
<ClassOverride>RetroArchFileBrowser</ClassOverride>
|
||||
</Properties>
|
||||
<XuiText>
|
||||
<Properties>
|
||||
<Id>XuiTxtTitle</Id>
|
||||
<Width>111.840027</Width>
|
||||
<Height>40.000000</Height>
|
||||
<Position>28.893612,12.519989,0.000000</Position>
|
||||
<Text>Filebrowser</Text>
|
||||
<TextColor>0xff0f0f0f</TextColor>
|
||||
<DropShadowColor>0x800f0f0f</DropShadowColor>
|
||||
<Font>Arial Unicode MS</Font>
|
||||
<TextStyle>21</TextStyle>
|
||||
</Properties>
|
||||
</XuiText>
|
||||
<XuiCommonList>
|
||||
<Properties>
|
||||
<Id>XuiRomList</Id>
|
||||
<Width>945.200073</Width>
|
||||
<Height>376.000031</Height>
|
||||
<Position>22.799980,88.000000,0.000000</Position>
|
||||
<NavUp>XuiBtnGameDir</NavUp>
|
||||
<NavDown>XuiBtnGameDir</NavDown>
|
||||
</Properties>
|
||||
<XuiListItem>
|
||||
<Properties>
|
||||
<Id>control_ListItem</Id>
|
||||
<Width>226.000000</Width>
|
||||
<Height>45.000000</Height>
|
||||
<Position>7.000000,22.000000,0.000000</Position>
|
||||
<Anchor>5</Anchor>
|
||||
<Show>false</Show>
|
||||
<Visual>XuiButton</Visual>
|
||||
<InterItemSpacing>0.000000,10.000000,0.000000</InterItemSpacing>
|
||||
</Properties>
|
||||
</XuiListItem>
|
||||
<XuiListItem>
|
||||
<Properties>
|
||||
<Id>control_ListItem</Id>
|
||||
<Width>226.000000</Width>
|
||||
<Height>45.000000</Height>
|
||||
<Position>7.000000,22.000000,0.000000</Position>
|
||||
<Anchor>5</Anchor>
|
||||
<Show>false</Show>
|
||||
<Visual>XuiButton</Visual>
|
||||
<InterItemSpacing>0.000000,10.000000,0.000000</InterItemSpacing>
|
||||
</Properties>
|
||||
</XuiListItem>
|
||||
<XuiListItem>
|
||||
<Properties>
|
||||
<Id>control_ListItem</Id>
|
||||
<Width>226.000000</Width>
|
||||
<Height>45.000000</Height>
|
||||
<Position>7.000000,22.000000,0.000000</Position>
|
||||
<Anchor>5</Anchor>
|
||||
<Show>false</Show>
|
||||
<Visual>XuiButton</Visual>
|
||||
<InterItemSpacing>0.000000,10.000000,0.000000</InterItemSpacing>
|
||||
</Properties>
|
||||
</XuiListItem>
|
||||
<XuiListItem>
|
||||
<Properties>
|
||||
<Id>control_ListItem</Id>
|
||||
<Width>226.000000</Width>
|
||||
<Height>45.000000</Height>
|
||||
<Position>7.000000,22.000000,0.000000</Position>
|
||||
<Anchor>5</Anchor>
|
||||
<Show>false</Show>
|
||||
<Visual>XuiButton</Visual>
|
||||
<InterItemSpacing>0.000000,10.000000,0.000000</InterItemSpacing>
|
||||
</Properties>
|
||||
</XuiListItem>
|
||||
<XuiListItem>
|
||||
<Properties>
|
||||
<Id>control_ListItem</Id>
|
||||
<Width>226.000000</Width>
|
||||
<Height>45.000000</Height>
|
||||
<Position>7.000000,22.000000,0.000000</Position>
|
||||
<Anchor>5</Anchor>
|
||||
<Show>false</Show>
|
||||
<Visual>XuiButton</Visual>
|
||||
<InterItemSpacing>0.000000,10.000000,0.000000</InterItemSpacing>
|
||||
</Properties>
|
||||
</XuiListItem>
|
||||
<XuiListItem>
|
||||
<Properties>
|
||||
<Id>control_ListItem</Id>
|
||||
<Width>226.000000</Width>
|
||||
<Height>45.000000</Height>
|
||||
<Position>7.000000,22.000000,0.000000</Position>
|
||||
<Anchor>5</Anchor>
|
||||
<Show>false</Show>
|
||||
<Visual>XuiButton</Visual>
|
||||
<InterItemSpacing>0.000000,10.000000,0.000000</InterItemSpacing>
|
||||
</Properties>
|
||||
</XuiListItem>
|
||||
<XuiListItem>
|
||||
<Properties>
|
||||
<Id>control_ListItem</Id>
|
||||
<Width>226.000000</Width>
|
||||
<Height>45.000000</Height>
|
||||
<Position>7.000000,22.000000,0.000000</Position>
|
||||
<Anchor>5</Anchor>
|
||||
<Show>false</Show>
|
||||
<Visual>XuiButton</Visual>
|
||||
<InterItemSpacing>0.000000,10.000000,0.000000</InterItemSpacing>
|
||||
</Properties>
|
||||
</XuiListItem>
|
||||
<XuiListItem>
|
||||
<Properties>
|
||||
<Id>control_ListItem</Id>
|
||||
<Width>226.000000</Width>
|
||||
<Height>45.000000</Height>
|
||||
<Position>7.000000,22.000000,0.000000</Position>
|
||||
<Anchor>5</Anchor>
|
||||
<Show>false</Show>
|
||||
<Visual>XuiButton</Visual>
|
||||
<InterItemSpacing>0.000000,10.000000,0.000000</InterItemSpacing>
|
||||
</Properties>
|
||||
</XuiListItem>
|
||||
<XuiListItem>
|
||||
<Properties>
|
||||
<Id>control_ListItem</Id>
|
||||
<Width>226.000000</Width>
|
||||
<Height>45.000000</Height>
|
||||
<Position>7.000000,22.000000,0.000000</Position>
|
||||
<Anchor>5</Anchor>
|
||||
<Show>false</Show>
|
||||
<Visual>XuiButton</Visual>
|
||||
<InterItemSpacing>0.000000,10.000000,0.000000</InterItemSpacing>
|
||||
</Properties>
|
||||
</XuiListItem>
|
||||
</XuiCommonList>
|
||||
<XuiBackButton>
|
||||
<Properties>
|
||||
<Id>XuiBackButton1</Id>
|
||||
<Width>204.599976</Width>
|
||||
<Height>36.000000</Height>
|
||||
<Position>355.115234,484.396851,0.000000</Position>
|
||||
<Text>Go back to menu</Text>
|
||||
<PressKey>22593</PressKey>
|
||||
</Properties>
|
||||
</XuiBackButton>
|
||||
<XuiText>
|
||||
<Properties>
|
||||
<Id>XuiTxtRomPath</Id>
|
||||
<Width>166.559998</Width>
|
||||
<Height>28.480011</Height>
|
||||
<Position>96.000000,42.480011,0.000000</Position>
|
||||
<TextColor>0xff0f0f0f</TextColor>
|
||||
<DropShadowColor>0x800f0f0f</DropShadowColor>
|
||||
</Properties>
|
||||
</XuiText>
|
||||
<XuiLabel>
|
||||
<Properties>
|
||||
<Id>XuiLblPath</Id>
|
||||
<Width>72.880005</Width>
|
||||
<Height>28.000000</Height>
|
||||
<Position>26.000000,43.000000,0.000000</Position>
|
||||
<Text>PATH:</Text>
|
||||
</Properties>
|
||||
</XuiLabel>
|
||||
<XuiButton>
|
||||
<Properties>
|
||||
<Id>XuiBtnGameDir</Id>
|
||||
<Width>115.640007</Width>
|
||||
<Height>38.000000</Height>
|
||||
<Position>31.999985,480.000061,0.000000</Position>
|
||||
<NavRight>XuiBtnCacheDir</NavRight>
|
||||
<NavUp>XuiRomList</NavUp>
|
||||
<NavDown>XuiRomList</NavDown>
|
||||
<Text>game:</Text>
|
||||
</Properties>
|
||||
</XuiButton>
|
||||
<XuiButton>
|
||||
<Properties>
|
||||
<Id>XuiBtnCacheDir</Id>
|
||||
<Width>119.960014</Width>
|
||||
<Height>38.000000</Height>
|
||||
<Position>161.999985,480.000061,0.000000</Position>
|
||||
<NavLeft>XuiBtnGameDir</NavLeft>
|
||||
<NavUp>XuiRomList</NavUp>
|
||||
<NavDown>XuiRomList</NavDown>
|
||||
<Text>cache:</Text>
|
||||
</Properties>
|
||||
</XuiButton>
|
||||
</XuiScene>
|
||||
</XuiCanvas>
|
||||
@@ -0,0 +1,197 @@
|
||||
<XuiCanvas version="000c">
|
||||
<Properties>
|
||||
<Width>1280.000000</Width>
|
||||
<Height>720.000000</Height>
|
||||
</Properties>
|
||||
<XuiScene>
|
||||
<Properties>
|
||||
<Id>XuiSceneCoreFileBrowser</Id>
|
||||
<Width>920.000122</Width>
|
||||
<Height>552.000000</Height>
|
||||
<Position>176.000015,88.000015,0.000000</Position>
|
||||
<ClassOverride>RetroArchCoreBrowser</ClassOverride>
|
||||
</Properties>
|
||||
<XuiText>
|
||||
<Properties>
|
||||
<Id>XuiTxtTitle</Id>
|
||||
<Width>326.640015</Width>
|
||||
<Height>40.000000</Height>
|
||||
<Position>28.893612,12.519989,0.000000</Position>
|
||||
<Text>Filebrowser - Select a libretro core</Text>
|
||||
<TextColor>0xff0f0f0f</TextColor>
|
||||
<DropShadowColor>0x800f0f0f</DropShadowColor>
|
||||
<Font>Arial Unicode MS</Font>
|
||||
<TextStyle>21</TextStyle>
|
||||
</Properties>
|
||||
</XuiText>
|
||||
<XuiCommonList>
|
||||
<Properties>
|
||||
<Id>XuiRomList</Id>
|
||||
<Width>857.200195</Width>
|
||||
<Height>406.400024</Height>
|
||||
<Position>22.799980,81.600006,0.000000</Position>
|
||||
</Properties>
|
||||
<XuiListItem>
|
||||
<Properties>
|
||||
<Id>control_ListItem</Id>
|
||||
<Width>226.000000</Width>
|
||||
<Height>45.000000</Height>
|
||||
<Position>7.000000,22.000000,0.000000</Position>
|
||||
<Anchor>5</Anchor>
|
||||
<Show>false</Show>
|
||||
<Visual>XuiButton</Visual>
|
||||
<InterItemSpacing>0.000000,10.000000,0.000000</InterItemSpacing>
|
||||
</Properties>
|
||||
</XuiListItem>
|
||||
<XuiListItem>
|
||||
<Properties>
|
||||
<Id>control_ListItem</Id>
|
||||
<Width>226.000000</Width>
|
||||
<Height>45.000000</Height>
|
||||
<Position>7.000000,22.000000,0.000000</Position>
|
||||
<Anchor>5</Anchor>
|
||||
<Show>false</Show>
|
||||
<Visual>XuiButton</Visual>
|
||||
<InterItemSpacing>0.000000,10.000000,0.000000</InterItemSpacing>
|
||||
</Properties>
|
||||
</XuiListItem>
|
||||
<XuiListItem>
|
||||
<Properties>
|
||||
<Id>control_ListItem</Id>
|
||||
<Width>226.000000</Width>
|
||||
<Height>45.000000</Height>
|
||||
<Position>7.000000,22.000000,0.000000</Position>
|
||||
<Anchor>5</Anchor>
|
||||
<Show>false</Show>
|
||||
<Visual>XuiButton</Visual>
|
||||
<InterItemSpacing>0.000000,10.000000,0.000000</InterItemSpacing>
|
||||
</Properties>
|
||||
</XuiListItem>
|
||||
<XuiListItem>
|
||||
<Properties>
|
||||
<Id>control_ListItem</Id>
|
||||
<Width>226.000000</Width>
|
||||
<Height>45.000000</Height>
|
||||
<Position>7.000000,22.000000,0.000000</Position>
|
||||
<Anchor>5</Anchor>
|
||||
<Show>false</Show>
|
||||
<Visual>XuiButton</Visual>
|
||||
<InterItemSpacing>0.000000,10.000000,0.000000</InterItemSpacing>
|
||||
</Properties>
|
||||
</XuiListItem>
|
||||
<XuiListItem>
|
||||
<Properties>
|
||||
<Id>control_ListItem</Id>
|
||||
<Width>226.000000</Width>
|
||||
<Height>45.000000</Height>
|
||||
<Position>7.000000,22.000000,0.000000</Position>
|
||||
<Anchor>5</Anchor>
|
||||
<Show>false</Show>
|
||||
<Visual>XuiButton</Visual>
|
||||
<InterItemSpacing>0.000000,10.000000,0.000000</InterItemSpacing>
|
||||
</Properties>
|
||||
</XuiListItem>
|
||||
<XuiListItem>
|
||||
<Properties>
|
||||
<Id>control_ListItem</Id>
|
||||
<Width>226.000000</Width>
|
||||
<Height>45.000000</Height>
|
||||
<Position>7.000000,22.000000,0.000000</Position>
|
||||
<Anchor>5</Anchor>
|
||||
<Show>false</Show>
|
||||
<Visual>XuiButton</Visual>
|
||||
<InterItemSpacing>0.000000,10.000000,0.000000</InterItemSpacing>
|
||||
</Properties>
|
||||
</XuiListItem>
|
||||
<XuiListItem>
|
||||
<Properties>
|
||||
<Id>control_ListItem</Id>
|
||||
<Width>226.000000</Width>
|
||||
<Height>45.000000</Height>
|
||||
<Position>7.000000,22.000000,0.000000</Position>
|
||||
<Anchor>5</Anchor>
|
||||
<Show>false</Show>
|
||||
<Visual>XuiButton</Visual>
|
||||
<InterItemSpacing>0.000000,10.000000,0.000000</InterItemSpacing>
|
||||
</Properties>
|
||||
</XuiListItem>
|
||||
<XuiListItem>
|
||||
<Properties>
|
||||
<Id>control_ListItem</Id>
|
||||
<Width>226.000000</Width>
|
||||
<Height>45.000000</Height>
|
||||
<Position>7.000000,22.000000,0.000000</Position>
|
||||
<Anchor>5</Anchor>
|
||||
<Show>false</Show>
|
||||
<Visual>XuiButton</Visual>
|
||||
<InterItemSpacing>0.000000,10.000000,0.000000</InterItemSpacing>
|
||||
</Properties>
|
||||
</XuiListItem>
|
||||
<XuiListItem>
|
||||
<Properties>
|
||||
<Id>control_ListItem</Id>
|
||||
<Width>226.000000</Width>
|
||||
<Height>45.000000</Height>
|
||||
<Position>7.000000,22.000000,0.000000</Position>
|
||||
<Anchor>5</Anchor>
|
||||
<Show>false</Show>
|
||||
<Visual>XuiButton</Visual>
|
||||
<InterItemSpacing>0.000000,10.000000,0.000000</InterItemSpacing>
|
||||
</Properties>
|
||||
</XuiListItem>
|
||||
<XuiListItem>
|
||||
<Properties>
|
||||
<Id>control_ListItem</Id>
|
||||
<Width>226.000000</Width>
|
||||
<Height>45.000000</Height>
|
||||
<Position>7.000000,22.000000,0.000000</Position>
|
||||
<Anchor>5</Anchor>
|
||||
<Show>false</Show>
|
||||
<Visual>XuiButton</Visual>
|
||||
<InterItemSpacing>0.000000,10.000000,0.000000</InterItemSpacing>
|
||||
</Properties>
|
||||
</XuiListItem>
|
||||
<XuiListItem>
|
||||
<Properties>
|
||||
<Id>control_ListItem</Id>
|
||||
<Width>226.000000</Width>
|
||||
<Height>45.000000</Height>
|
||||
<Position>7.000000,22.000000,0.000000</Position>
|
||||
<Anchor>5</Anchor>
|
||||
<Show>false</Show>
|
||||
<Visual>XuiButton</Visual>
|
||||
<InterItemSpacing>0.000000,10.000000,0.000000</InterItemSpacing>
|
||||
</Properties>
|
||||
</XuiListItem>
|
||||
</XuiCommonList>
|
||||
<XuiBackButton>
|
||||
<Properties>
|
||||
<Id>XuiBackButton1</Id>
|
||||
<Width>219.000000</Width>
|
||||
<Height>36.000000</Height>
|
||||
<Position>680.000061,504.000061,0.000000</Position>
|
||||
<Text>Go back to menu</Text>
|
||||
<PressKey>22593</PressKey>
|
||||
</Properties>
|
||||
</XuiBackButton>
|
||||
<XuiText>
|
||||
<Properties>
|
||||
<Id>XuiTxtRomPath</Id>
|
||||
<Width>166.559998</Width>
|
||||
<Height>28.480011</Height>
|
||||
<Position>96.000000,42.480011,0.000000</Position>
|
||||
<TextColor>0xff0f0f0f</TextColor>
|
||||
<DropShadowColor>0x800f0f0f</DropShadowColor>
|
||||
</Properties>
|
||||
</XuiText>
|
||||
<XuiLabel>
|
||||
<Properties>
|
||||
<Id>XuiLblPath</Id>
|
||||
<Width>72.880005</Width>
|
||||
<Height>28.000000</Height>
|
||||
<Position>26.000000,43.000000,0.000000</Position>
|
||||
<Text>PATH:</Text>
|
||||
</Properties>
|
||||
</XuiLabel>
|
||||
</XuiScene>
|
||||
</XuiCanvas>
|
||||
@@ -0,0 +1,116 @@
|
||||
<XuiCanvas version="000c">
|
||||
<Properties>
|
||||
<Width>1280.000000</Width>
|
||||
<Height>720.000000</Height>
|
||||
</Properties>
|
||||
<XuiScene>
|
||||
<Properties>
|
||||
<Id>XuiScene1</Id>
|
||||
<Width>752.000061</Width>
|
||||
<Height>512.000122</Height>
|
||||
<Position>264.000031,88.000008,0.000000</Position>
|
||||
<ClassOverride>RetroArchMain</ClassOverride>
|
||||
</Properties>
|
||||
<XuiButton>
|
||||
<Properties>
|
||||
<Id>XuiBtnRomBrowser</Id>
|
||||
<Width>689.672302</Width>
|
||||
<Height>48.992096</Height>
|
||||
<Position>38.127724,73.215515,0.000000</Position>
|
||||
<Pivot>245.362122,102.247192,0.000000</Pivot>
|
||||
<NavUp>XuiBtnQuit</NavUp>
|
||||
<NavDown>XuiBtnQuickMenu</NavDown>
|
||||
<Text>ROM Browser</Text>
|
||||
</Properties>
|
||||
</XuiButton>
|
||||
<XuiText>
|
||||
<Properties>
|
||||
<Id>XuiTxtTitle</Id>
|
||||
<Width>247.200012</Width>
|
||||
<Height>40.000000</Height>
|
||||
<Position>43.581604,21.159988,0.000000</Position>
|
||||
<Text>RetroArch 360</Text>
|
||||
<TextColor>0xff0f0f0f</TextColor>
|
||||
<DropShadowColor>0x800f0f0f</DropShadowColor>
|
||||
<Font>Arial Unicode MS</Font>
|
||||
<TextStyle>21</TextStyle>
|
||||
</Properties>
|
||||
</XuiText>
|
||||
<XuiButton>
|
||||
<Properties>
|
||||
<Id>XuiBtnSettings</Id>
|
||||
<Width>689.672302</Width>
|
||||
<Height>48.992096</Height>
|
||||
<Position>40.000000,263.960022,0.000000</Position>
|
||||
<NavUp>XuiBtnControls</NavUp>
|
||||
<NavDown>XuiBtnLibsnesCore</NavDown>
|
||||
<Text>Settings</Text>
|
||||
</Properties>
|
||||
</XuiButton>
|
||||
<XuiButton>
|
||||
<Properties>
|
||||
<Id>XuiBtnQuit</Id>
|
||||
<Width>689.672302</Width>
|
||||
<Height>48.992096</Height>
|
||||
<Position>40.199776,392.352020,0.000000</Position>
|
||||
<Pivot>245.162109,-84.153275,0.000000</Pivot>
|
||||
<NavUp>XuiBtnLibsnesCore</NavUp>
|
||||
<NavDown>XuiBtnRomBrowser</NavDown>
|
||||
<Text>Quit</Text>
|
||||
</Properties>
|
||||
</XuiButton>
|
||||
<XuiLabel>
|
||||
<Properties>
|
||||
<Id>XuiLblCore</Id>
|
||||
<Width>124.000000</Width>
|
||||
<Height>28.000000</Height>
|
||||
<Position>40.000000,448.400055,0.000000</Position>
|
||||
<Text>Libretro core:</Text>
|
||||
</Properties>
|
||||
</XuiLabel>
|
||||
<XuiText>
|
||||
<Properties>
|
||||
<Id>XuiTxtCoreText</Id>
|
||||
<Width>224.399963</Width>
|
||||
<Height>34.000000</Height>
|
||||
<Position>162.400024,448.000031,0.000000</Position>
|
||||
<TextColor>0xff0f0f0f</TextColor>
|
||||
<DropShadowColor>0x800f0f0f</DropShadowColor>
|
||||
<Font>Arial Unicode MS</Font>
|
||||
</Properties>
|
||||
</XuiText>
|
||||
<XuiButton>
|
||||
<Properties>
|
||||
<Id>XuiBtnQuickMenu</Id>
|
||||
<Width>689.672302</Width>
|
||||
<Height>48.992096</Height>
|
||||
<Position>39.999996,138.000000,0.000000</Position>
|
||||
<NavUp>XuiBtnRomBrowser</NavUp>
|
||||
<NavDown>XuiBtnControls</NavDown>
|
||||
<Text>Quick Menu</Text>
|
||||
</Properties>
|
||||
</XuiButton>
|
||||
<XuiButton>
|
||||
<Properties>
|
||||
<Id>XuiBtnControls</Id>
|
||||
<Width>689.672302</Width>
|
||||
<Height>48.992096</Height>
|
||||
<Position>40.002041,202.000015,0.000000</Position>
|
||||
<NavUp>XuiBtnQuickMenu</NavUp>
|
||||
<NavDown>XuiBtnSettings</NavDown>
|
||||
<Text>Controls</Text>
|
||||
</Properties>
|
||||
</XuiButton>
|
||||
<XuiButton>
|
||||
<Properties>
|
||||
<Id>XuiBtnLibsnesCore</Id>
|
||||
<Width>689.672302</Width>
|
||||
<Height>48.992096</Height>
|
||||
<Position>40.000000,328.959991,0.000000</Position>
|
||||
<NavUp>XuiBtnSettings</NavUp>
|
||||
<NavDown>XuiBtnQuit</NavDown>
|
||||
<Text>Change libretro core</Text>
|
||||
</Properties>
|
||||
</XuiButton>
|
||||
</XuiScene>
|
||||
</XuiCanvas>
|
||||
@@ -0,0 +1,142 @@
|
||||
<XuiCanvas version="000c">
|
||||
<Properties>
|
||||
<Width>1280.000000</Width>
|
||||
<Height>720.000000</Height>
|
||||
</Properties>
|
||||
<XuiScene>
|
||||
<Properties>
|
||||
<Id>XuiScene1</Id>
|
||||
<Width>824.000061</Width>
|
||||
<Height>496.000061</Height>
|
||||
<Position>182.000031,120.000023,0.000000</Position>
|
||||
<ClassOverride>RetroArchQuickMenu</ClassOverride>
|
||||
</Properties>
|
||||
<XuiText>
|
||||
<Properties>
|
||||
<Id>XuiTxtTitle</Id>
|
||||
<Width>121.056023</Width>
|
||||
<Height>40.000000</Height>
|
||||
<Position>43.581604,21.159988,0.000000</Position>
|
||||
<Text>Quick Menu</Text>
|
||||
<TextColor>0xff0f0f0f</TextColor>
|
||||
<DropShadowColor>0x800f0f0f</DropShadowColor>
|
||||
<Font>Arial Unicode MS</Font>
|
||||
<TextStyle>21</TextStyle>
|
||||
</Properties>
|
||||
</XuiText>
|
||||
<XuiCommonList>
|
||||
<Properties>
|
||||
<Id>XuiQuickMenuList</Id>
|
||||
<Width>723.120056</Width>
|
||||
<Height>367.040009</Height>
|
||||
<Position>44.880005,64.959991,0.000000</Position>
|
||||
<ItemsText>Load State
|
||||
Save State
|
||||
Aspect Ratio:
|
||||
Overscan:
|
||||
Orientation:
|
||||
Resize Mode
|
||||
Frame Advance
|
||||
Screenshot Mode
|
||||
Reset
|
||||
Return to Game
|
||||
Return to Dashboard
|
||||
</ItemsText>
|
||||
</Properties>
|
||||
<XuiListItem>
|
||||
<Properties>
|
||||
<Id>control_ListItem</Id>
|
||||
<Width>226.000000</Width>
|
||||
<Height>45.000000</Height>
|
||||
<Position>7.000000,22.000000,0.000000</Position>
|
||||
<Anchor>5</Anchor>
|
||||
<Show>false</Show>
|
||||
<Visual>XuiButton</Visual>
|
||||
<InterItemSpacing>0.000000,10.000000,0.000000</InterItemSpacing>
|
||||
</Properties>
|
||||
</XuiListItem>
|
||||
<XuiListItem>
|
||||
<Properties>
|
||||
<Id>control_ListItem</Id>
|
||||
<Width>226.000000</Width>
|
||||
<Height>45.000000</Height>
|
||||
<Position>7.000000,22.000000,0.000000</Position>
|
||||
<Anchor>5</Anchor>
|
||||
<Show>false</Show>
|
||||
<Visual>XuiButton</Visual>
|
||||
<InterItemSpacing>0.000000,10.000000,0.000000</InterItemSpacing>
|
||||
</Properties>
|
||||
</XuiListItem>
|
||||
<XuiListItem>
|
||||
<Properties>
|
||||
<Id>control_ListItem</Id>
|
||||
<Width>226.000000</Width>
|
||||
<Height>45.000000</Height>
|
||||
<Position>7.000000,22.000000,0.000000</Position>
|
||||
<Anchor>5</Anchor>
|
||||
<Show>false</Show>
|
||||
<Visual>XuiButton</Visual>
|
||||
<InterItemSpacing>0.000000,10.000000,0.000000</InterItemSpacing>
|
||||
</Properties>
|
||||
</XuiListItem>
|
||||
<XuiListItem>
|
||||
<Properties>
|
||||
<Id>control_ListItem</Id>
|
||||
<Width>226.000000</Width>
|
||||
<Height>45.000000</Height>
|
||||
<Position>7.000000,22.000000,0.000000</Position>
|
||||
<Anchor>5</Anchor>
|
||||
<Show>false</Show>
|
||||
<Visual>XuiButton</Visual>
|
||||
<InterItemSpacing>0.000000,10.000000,0.000000</InterItemSpacing>
|
||||
</Properties>
|
||||
</XuiListItem>
|
||||
<XuiListItem>
|
||||
<Properties>
|
||||
<Id>control_ListItem</Id>
|
||||
<Width>226.000000</Width>
|
||||
<Height>45.000000</Height>
|
||||
<Position>7.000000,22.000000,0.000000</Position>
|
||||
<Anchor>5</Anchor>
|
||||
<Show>false</Show>
|
||||
<Visual>XuiButton</Visual>
|
||||
<InterItemSpacing>0.000000,10.000000,0.000000</InterItemSpacing>
|
||||
</Properties>
|
||||
</XuiListItem>
|
||||
<XuiListItem>
|
||||
<Properties>
|
||||
<Id>control_ListItem</Id>
|
||||
<Width>226.000000</Width>
|
||||
<Height>45.000000</Height>
|
||||
<Position>7.000000,22.000000,0.000000</Position>
|
||||
<Anchor>5</Anchor>
|
||||
<Show>false</Show>
|
||||
<Visual>XuiButton</Visual>
|
||||
<InterItemSpacing>0.000000,10.000000,0.000000</InterItemSpacing>
|
||||
</Properties>
|
||||
</XuiListItem>
|
||||
<XuiListItem>
|
||||
<Properties>
|
||||
<Id>control_ListItem</Id>
|
||||
<Width>226.000000</Width>
|
||||
<Height>45.000000</Height>
|
||||
<Position>7.000000,22.000000,0.000000</Position>
|
||||
<Anchor>5</Anchor>
|
||||
<Show>false</Show>
|
||||
<Visual>XuiButton</Visual>
|
||||
<InterItemSpacing>0.000000,10.000000,0.000000</InterItemSpacing>
|
||||
</Properties>
|
||||
</XuiListItem>
|
||||
</XuiCommonList>
|
||||
<XuiBackButton>
|
||||
<Properties>
|
||||
<Id>XuiBackButton</Id>
|
||||
<Width>208.632019</Width>
|
||||
<Height>36.000000</Height>
|
||||
<Position>568.000061,432.000000,0.000000</Position>
|
||||
<Text>Go back to menu</Text>
|
||||
<PressKey>22593</PressKey>
|
||||
</Properties>
|
||||
</XuiBackButton>
|
||||
</XuiScene>
|
||||
</XuiCanvas>
|
||||
@@ -0,0 +1,226 @@
|
||||
<XuiCanvas version="000c">
|
||||
<Properties>
|
||||
<Width>1280.000000</Width>
|
||||
<Height>720.000000</Height>
|
||||
</Properties>
|
||||
<XuiScene>
|
||||
<Properties>
|
||||
<Id>XuiScene1</Id>
|
||||
<Width>776.000061</Width>
|
||||
<Height>512.000061</Height>
|
||||
<Position>198.000031,112.000023,0.000000</Position>
|
||||
<ClassOverride>RetroArchSettings</ClassOverride>
|
||||
</Properties>
|
||||
<XuiText>
|
||||
<Properties>
|
||||
<Id>XuiTxtTitle</Id>
|
||||
<Width>121.056023</Width>
|
||||
<Height>40.000000</Height>
|
||||
<Position>43.581604,21.159988,0.000000</Position>
|
||||
<Text>Settings</Text>
|
||||
<TextColor>0xff0f0f0f</TextColor>
|
||||
<DropShadowColor>0x800f0f0f</DropShadowColor>
|
||||
<Font>Arial Unicode MS</Font>
|
||||
<TextStyle>21</TextStyle>
|
||||
</Properties>
|
||||
</XuiText>
|
||||
<XuiCommonList>
|
||||
<Properties>
|
||||
<Id>XuiSettingsList</Id>
|
||||
<Width>683.120056</Width>
|
||||
<Height>383.040009</Height>
|
||||
<Position>44.880005,64.959991,0.000000</Position>
|
||||
<ItemsText>Rewind:
|
||||
Info messages:
|
||||
Menus:
|
||||
Gamma Correction:
|
||||
Color Format:
|
||||
Shader #1:
|
||||
Shader #2:
|
||||
Hardware filtering shader #1:
|
||||
Hardware filtering shader #2:
|
||||
Custom Scaling/Dual Shaders:
|
||||
Custom Scaling Factor:
|
||||
</ItemsText>
|
||||
</Properties>
|
||||
<XuiListItem>
|
||||
<Properties>
|
||||
<Id>control_ListItem</Id>
|
||||
<Width>226.000000</Width>
|
||||
<Height>45.000000</Height>
|
||||
<Position>7.000000,22.000000,0.000000</Position>
|
||||
<Anchor>5</Anchor>
|
||||
<Show>false</Show>
|
||||
<Visual>XuiButton</Visual>
|
||||
<InterItemSpacing>0.000000,10.000000,0.000000</InterItemSpacing>
|
||||
</Properties>
|
||||
</XuiListItem>
|
||||
<XuiListItem>
|
||||
<Properties>
|
||||
<Id>control_ListItem</Id>
|
||||
<Width>226.000000</Width>
|
||||
<Height>45.000000</Height>
|
||||
<Position>7.000000,22.000000,0.000000</Position>
|
||||
<Anchor>5</Anchor>
|
||||
<Show>false</Show>
|
||||
<Visual>XuiButton</Visual>
|
||||
<InterItemSpacing>0.000000,10.000000,0.000000</InterItemSpacing>
|
||||
</Properties>
|
||||
</XuiListItem>
|
||||
<XuiListItem>
|
||||
<Properties>
|
||||
<Id>control_ListItem</Id>
|
||||
<Width>226.000000</Width>
|
||||
<Height>45.000000</Height>
|
||||
<Position>7.000000,22.000000,0.000000</Position>
|
||||
<Anchor>5</Anchor>
|
||||
<Show>false</Show>
|
||||
<Visual>XuiButton</Visual>
|
||||
<InterItemSpacing>0.000000,10.000000,0.000000</InterItemSpacing>
|
||||
</Properties>
|
||||
</XuiListItem>
|
||||
<XuiListItem>
|
||||
<Properties>
|
||||
<Id>control_ListItem</Id>
|
||||
<Width>226.000000</Width>
|
||||
<Height>45.000000</Height>
|
||||
<Position>7.000000,22.000000,0.000000</Position>
|
||||
<Anchor>5</Anchor>
|
||||
<Show>false</Show>
|
||||
<Visual>XuiButton</Visual>
|
||||
<InterItemSpacing>0.000000,10.000000,0.000000</InterItemSpacing>
|
||||
</Properties>
|
||||
</XuiListItem>
|
||||
<XuiListItem>
|
||||
<Properties>
|
||||
<Id>control_ListItem</Id>
|
||||
<Width>226.000000</Width>
|
||||
<Height>45.000000</Height>
|
||||
<Position>7.000000,22.000000,0.000000</Position>
|
||||
<Anchor>5</Anchor>
|
||||
<Show>false</Show>
|
||||
<Visual>XuiButton</Visual>
|
||||
<InterItemSpacing>0.000000,10.000000,0.000000</InterItemSpacing>
|
||||
</Properties>
|
||||
</XuiListItem>
|
||||
<XuiListItem>
|
||||
<Properties>
|
||||
<Id>control_ListItem</Id>
|
||||
<Width>226.000000</Width>
|
||||
<Height>45.000000</Height>
|
||||
<Position>7.000000,22.000000,0.000000</Position>
|
||||
<Anchor>5</Anchor>
|
||||
<Show>false</Show>
|
||||
<Visual>XuiButton</Visual>
|
||||
<InterItemSpacing>0.000000,10.000000,0.000000</InterItemSpacing>
|
||||
</Properties>
|
||||
</XuiListItem>
|
||||
<XuiListItem>
|
||||
<Properties>
|
||||
<Id>control_ListItem</Id>
|
||||
<Width>226.000000</Width>
|
||||
<Height>45.000000</Height>
|
||||
<Position>7.000000,22.000000,0.000000</Position>
|
||||
<Anchor>5</Anchor>
|
||||
<Show>false</Show>
|
||||
<Visual>XuiButton</Visual>
|
||||
<InterItemSpacing>0.000000,10.000000,0.000000</InterItemSpacing>
|
||||
</Properties>
|
||||
</XuiListItem>
|
||||
<XuiListItem>
|
||||
<Properties>
|
||||
<Id>control_ListItem</Id>
|
||||
<Width>226.000000</Width>
|
||||
<Height>45.000000</Height>
|
||||
<Position>7.000000,22.000000,0.000000</Position>
|
||||
<Anchor>5</Anchor>
|
||||
<Show>false</Show>
|
||||
<Visual>XuiButton</Visual>
|
||||
<InterItemSpacing>0.000000,10.000000,0.000000</InterItemSpacing>
|
||||
</Properties>
|
||||
</XuiListItem>
|
||||
<XuiListItem>
|
||||
<Properties>
|
||||
<Id>control_ListItem</Id>
|
||||
<Width>226.000000</Width>
|
||||
<Height>45.000000</Height>
|
||||
<Position>7.000000,22.000000,0.000000</Position>
|
||||
<Anchor>5</Anchor>
|
||||
<Show>false</Show>
|
||||
<Visual>XuiButton</Visual>
|
||||
<InterItemSpacing>0.000000,10.000000,0.000000</InterItemSpacing>
|
||||
</Properties>
|
||||
</XuiListItem>
|
||||
<XuiListItem>
|
||||
<Properties>
|
||||
<Id>control_ListItem</Id>
|
||||
<Width>226.000000</Width>
|
||||
<Height>45.000000</Height>
|
||||
<Position>7.000000,22.000000,0.000000</Position>
|
||||
<Anchor>5</Anchor>
|
||||
<Show>false</Show>
|
||||
<Visual>XuiButton</Visual>
|
||||
<InterItemSpacing>0.000000,10.000000,0.000000</InterItemSpacing>
|
||||
</Properties>
|
||||
</XuiListItem>
|
||||
<XuiListItem>
|
||||
<Properties>
|
||||
<Id>control_ListItem</Id>
|
||||
<Width>226.000000</Width>
|
||||
<Height>45.000000</Height>
|
||||
<Position>7.000000,22.000000,0.000000</Position>
|
||||
<Anchor>5</Anchor>
|
||||
<Show>false</Show>
|
||||
<Visual>XuiButton</Visual>
|
||||
<InterItemSpacing>0.000000,10.000000,0.000000</InterItemSpacing>
|
||||
</Properties>
|
||||
</XuiListItem>
|
||||
<XuiListItem>
|
||||
<Properties>
|
||||
<Id>control_ListItem</Id>
|
||||
<Width>226.000000</Width>
|
||||
<Height>45.000000</Height>
|
||||
<Position>7.000000,22.000000,0.000000</Position>
|
||||
<Anchor>5</Anchor>
|
||||
<Show>false</Show>
|
||||
<Visual>XuiButton</Visual>
|
||||
<InterItemSpacing>0.000000,10.000000,0.000000</InterItemSpacing>
|
||||
</Properties>
|
||||
</XuiListItem>
|
||||
<XuiListItem>
|
||||
<Properties>
|
||||
<Id>control_ListItem</Id>
|
||||
<Width>226.000000</Width>
|
||||
<Height>45.000000</Height>
|
||||
<Position>7.000000,22.000000,0.000000</Position>
|
||||
<Anchor>5</Anchor>
|
||||
<Show>false</Show>
|
||||
<Visual>XuiButton</Visual>
|
||||
<InterItemSpacing>0.000000,10.000000,0.000000</InterItemSpacing>
|
||||
</Properties>
|
||||
</XuiListItem>
|
||||
<XuiListItem>
|
||||
<Properties>
|
||||
<Id>control_ListItem</Id>
|
||||
<Width>226.000000</Width>
|
||||
<Height>45.000000</Height>
|
||||
<Position>7.000000,22.000000,0.000000</Position>
|
||||
<Anchor>5</Anchor>
|
||||
<Show>false</Show>
|
||||
<Visual>XuiButton</Visual>
|
||||
<InterItemSpacing>0.000000,10.000000,0.000000</InterItemSpacing>
|
||||
</Properties>
|
||||
</XuiListItem>
|
||||
</XuiCommonList>
|
||||
<XuiBackButton>
|
||||
<Properties>
|
||||
<Id>XuiBackButton</Id>
|
||||
<Width>208.632019</Width>
|
||||
<Height>36.000000</Height>
|
||||
<Position>536.000000,448.000000,0.000000</Position>
|
||||
<Text>Go back to menu</Text>
|
||||
<PressKey>22593</PressKey>
|
||||
</Properties>
|
||||
</XuiBackButton>
|
||||
</XuiScene>
|
||||
</XuiCanvas>
|
||||
@@ -0,0 +1,233 @@
|
||||
<XuiCanvas version="000c">
|
||||
<Properties>
|
||||
<Width>1280.000000</Width>
|
||||
<Height>720.000000</Height>
|
||||
</Properties>
|
||||
<XuiScene>
|
||||
<Properties>
|
||||
<Id>XuiSceneCoreFileBrowser</Id>
|
||||
<Width>920.000122</Width>
|
||||
<Height>552.000000</Height>
|
||||
<Position>176.000015,88.000015,0.000000</Position>
|
||||
<ClassOverride>RetroArchShaderBrowser</ClassOverride>
|
||||
</Properties>
|
||||
<XuiText>
|
||||
<Properties>
|
||||
<Id>XuiTxtTitle</Id>
|
||||
<Width>326.640015</Width>
|
||||
<Height>40.000000</Height>
|
||||
<Position>28.893612,12.519989,0.000000</Position>
|
||||
<Text>Shader selection - Select a shader</Text>
|
||||
<TextColor>0xff0f0f0f</TextColor>
|
||||
<DropShadowColor>0x800f0f0f</DropShadowColor>
|
||||
<Font>Arial Unicode MS</Font>
|
||||
<TextStyle>21</TextStyle>
|
||||
</Properties>
|
||||
</XuiText>
|
||||
<XuiCommonList>
|
||||
<Properties>
|
||||
<Id>XuiRomList</Id>
|
||||
<Width>857.200195</Width>
|
||||
<Height>406.400024</Height>
|
||||
<Position>22.799980,81.600006,0.000000</Position>
|
||||
</Properties>
|
||||
<XuiListItem>
|
||||
<Properties>
|
||||
<Id>control_ListItem</Id>
|
||||
<Width>226.000000</Width>
|
||||
<Height>45.000000</Height>
|
||||
<Position>7.000000,22.000000,0.000000</Position>
|
||||
<Anchor>5</Anchor>
|
||||
<Show>false</Show>
|
||||
<Visual>XuiButton</Visual>
|
||||
<InterItemSpacing>0.000000,10.000000,0.000000</InterItemSpacing>
|
||||
</Properties>
|
||||
</XuiListItem>
|
||||
<XuiListItem>
|
||||
<Properties>
|
||||
<Id>control_ListItem</Id>
|
||||
<Width>226.000000</Width>
|
||||
<Height>45.000000</Height>
|
||||
<Position>7.000000,22.000000,0.000000</Position>
|
||||
<Anchor>5</Anchor>
|
||||
<Show>false</Show>
|
||||
<Visual>XuiButton</Visual>
|
||||
<InterItemSpacing>0.000000,10.000000,0.000000</InterItemSpacing>
|
||||
</Properties>
|
||||
</XuiListItem>
|
||||
<XuiListItem>
|
||||
<Properties>
|
||||
<Id>control_ListItem</Id>
|
||||
<Width>226.000000</Width>
|
||||
<Height>45.000000</Height>
|
||||
<Position>7.000000,22.000000,0.000000</Position>
|
||||
<Anchor>5</Anchor>
|
||||
<Show>false</Show>
|
||||
<Visual>XuiButton</Visual>
|
||||
<InterItemSpacing>0.000000,10.000000,0.000000</InterItemSpacing>
|
||||
</Properties>
|
||||
</XuiListItem>
|
||||
<XuiListItem>
|
||||
<Properties>
|
||||
<Id>control_ListItem</Id>
|
||||
<Width>226.000000</Width>
|
||||
<Height>45.000000</Height>
|
||||
<Position>7.000000,22.000000,0.000000</Position>
|
||||
<Anchor>5</Anchor>
|
||||
<Show>false</Show>
|
||||
<Visual>XuiButton</Visual>
|
||||
<InterItemSpacing>0.000000,10.000000,0.000000</InterItemSpacing>
|
||||
</Properties>
|
||||
</XuiListItem>
|
||||
<XuiListItem>
|
||||
<Properties>
|
||||
<Id>control_ListItem</Id>
|
||||
<Width>226.000000</Width>
|
||||
<Height>45.000000</Height>
|
||||
<Position>7.000000,22.000000,0.000000</Position>
|
||||
<Anchor>5</Anchor>
|
||||
<Show>false</Show>
|
||||
<Visual>XuiButton</Visual>
|
||||
<InterItemSpacing>0.000000,10.000000,0.000000</InterItemSpacing>
|
||||
</Properties>
|
||||
</XuiListItem>
|
||||
<XuiListItem>
|
||||
<Properties>
|
||||
<Id>control_ListItem</Id>
|
||||
<Width>226.000000</Width>
|
||||
<Height>45.000000</Height>
|
||||
<Position>7.000000,22.000000,0.000000</Position>
|
||||
<Anchor>5</Anchor>
|
||||
<Show>false</Show>
|
||||
<Visual>XuiButton</Visual>
|
||||
<InterItemSpacing>0.000000,10.000000,0.000000</InterItemSpacing>
|
||||
</Properties>
|
||||
</XuiListItem>
|
||||
<XuiListItem>
|
||||
<Properties>
|
||||
<Id>control_ListItem</Id>
|
||||
<Width>226.000000</Width>
|
||||
<Height>45.000000</Height>
|
||||
<Position>7.000000,22.000000,0.000000</Position>
|
||||
<Anchor>5</Anchor>
|
||||
<Show>false</Show>
|
||||
<Visual>XuiButton</Visual>
|
||||
<InterItemSpacing>0.000000,10.000000,0.000000</InterItemSpacing>
|
||||
</Properties>
|
||||
</XuiListItem>
|
||||
<XuiListItem>
|
||||
<Properties>
|
||||
<Id>control_ListItem</Id>
|
||||
<Width>226.000000</Width>
|
||||
<Height>45.000000</Height>
|
||||
<Position>7.000000,22.000000,0.000000</Position>
|
||||
<Anchor>5</Anchor>
|
||||
<Show>false</Show>
|
||||
<Visual>XuiButton</Visual>
|
||||
<InterItemSpacing>0.000000,10.000000,0.000000</InterItemSpacing>
|
||||
</Properties>
|
||||
</XuiListItem>
|
||||
<XuiListItem>
|
||||
<Properties>
|
||||
<Id>control_ListItem</Id>
|
||||
<Width>226.000000</Width>
|
||||
<Height>45.000000</Height>
|
||||
<Position>7.000000,22.000000,0.000000</Position>
|
||||
<Anchor>5</Anchor>
|
||||
<Show>false</Show>
|
||||
<Visual>XuiButton</Visual>
|
||||
<InterItemSpacing>0.000000,10.000000,0.000000</InterItemSpacing>
|
||||
</Properties>
|
||||
</XuiListItem>
|
||||
<XuiListItem>
|
||||
<Properties>
|
||||
<Id>control_ListItem</Id>
|
||||
<Width>226.000000</Width>
|
||||
<Height>45.000000</Height>
|
||||
<Position>7.000000,22.000000,0.000000</Position>
|
||||
<Anchor>5</Anchor>
|
||||
<Show>false</Show>
|
||||
<Visual>XuiButton</Visual>
|
||||
<InterItemSpacing>0.000000,10.000000,0.000000</InterItemSpacing>
|
||||
</Properties>
|
||||
</XuiListItem>
|
||||
<XuiListItem>
|
||||
<Properties>
|
||||
<Id>control_ListItem</Id>
|
||||
<Width>226.000000</Width>
|
||||
<Height>45.000000</Height>
|
||||
<Position>7.000000,22.000000,0.000000</Position>
|
||||
<Anchor>5</Anchor>
|
||||
<Show>false</Show>
|
||||
<Visual>XuiButton</Visual>
|
||||
<InterItemSpacing>0.000000,10.000000,0.000000</InterItemSpacing>
|
||||
</Properties>
|
||||
</XuiListItem>
|
||||
<XuiListItem>
|
||||
<Properties>
|
||||
<Id>control_ListItem</Id>
|
||||
<Width>226.000000</Width>
|
||||
<Height>45.000000</Height>
|
||||
<Position>7.000000,22.000000,0.000000</Position>
|
||||
<Anchor>5</Anchor>
|
||||
<Show>false</Show>
|
||||
<Visual>XuiButton</Visual>
|
||||
<InterItemSpacing>0.000000,10.000000,0.000000</InterItemSpacing>
|
||||
</Properties>
|
||||
</XuiListItem>
|
||||
<XuiListItem>
|
||||
<Properties>
|
||||
<Id>control_ListItem</Id>
|
||||
<Width>226.000000</Width>
|
||||
<Height>45.000000</Height>
|
||||
<Position>7.000000,22.000000,0.000000</Position>
|
||||
<Anchor>5</Anchor>
|
||||
<Show>false</Show>
|
||||
<Visual>XuiButton</Visual>
|
||||
<InterItemSpacing>0.000000,10.000000,0.000000</InterItemSpacing>
|
||||
</Properties>
|
||||
</XuiListItem>
|
||||
<XuiListItem>
|
||||
<Properties>
|
||||
<Id>control_ListItem</Id>
|
||||
<Width>226.000000</Width>
|
||||
<Height>45.000000</Height>
|
||||
<Position>7.000000,22.000000,0.000000</Position>
|
||||
<Anchor>5</Anchor>
|
||||
<Show>false</Show>
|
||||
<Visual>XuiButton</Visual>
|
||||
<InterItemSpacing>0.000000,10.000000,0.000000</InterItemSpacing>
|
||||
</Properties>
|
||||
</XuiListItem>
|
||||
</XuiCommonList>
|
||||
<XuiBackButton>
|
||||
<Properties>
|
||||
<Id>XuiBackButton1</Id>
|
||||
<Width>219.000000</Width>
|
||||
<Height>36.000000</Height>
|
||||
<Position>680.000061,504.000061,0.000000</Position>
|
||||
<Text>Go back to menu</Text>
|
||||
<PressKey>22593</PressKey>
|
||||
</Properties>
|
||||
</XuiBackButton>
|
||||
<XuiText>
|
||||
<Properties>
|
||||
<Id>XuiTxtRomPath</Id>
|
||||
<Width>512.000122</Width>
|
||||
<Height>28.480011</Height>
|
||||
<Position>96.000000,42.480011,0.000000</Position>
|
||||
<TextColor>0xff0f0f0f</TextColor>
|
||||
<DropShadowColor>0x800f0f0f</DropShadowColor>
|
||||
</Properties>
|
||||
</XuiText>
|
||||
<XuiLabel>
|
||||
<Properties>
|
||||
<Id>XuiLblPath</Id>
|
||||
<Width>72.880005</Width>
|
||||
<Height>28.000000</Height>
|
||||
<Position>26.000000,43.000000,0.000000</Position>
|
||||
<Text>PATH:</Text>
|
||||
</Properties>
|
||||
</XuiLabel>
|
||||
</XuiScene>
|
||||
</XuiCanvas>
|
||||
Binary file not shown.
File diff suppressed because it is too large.
Load diff
@@ -0,0 +1,291 @@
|
||||
<XuiCanvas version="000c">
|
||||
<Properties>
|
||||
<Width>1280.000000</Width>
|
||||
<Height>720.000000</Height>
|
||||
</Properties>
|
||||
<XuiScene>
|
||||
<Properties>
|
||||
<Id>XuiScene1</Id>
|
||||
<Width>584.528076</Width>
|
||||
<Height>363.320007</Height>
|
||||
<Position>344.000031,184.000015,0.000000</Position>
|
||||
<ClassOverride>RetroArchControls</ClassOverride>
|
||||
</Properties>
|
||||
<XuiText>
|
||||
<Properties>
|
||||
<Id>XuiTxtTitle</Id>
|
||||
<Width>121.056023</Width>
|
||||
<Height>40.000000</Height>
|
||||
<Position>43.581604,21.159988,0.000000</Position>
|
||||
<Text>Controls</Text>
|
||||
<TextColor>0xff0f0f0f</TextColor>
|
||||
<DropShadowColor>0x800f0f0f</DropShadowColor>
|
||||
<Font>Arial Unicode MS</Font>
|
||||
<TextStyle>21</TextStyle>
|
||||
</Properties>
|
||||
</XuiText>
|
||||
<XuiCommonList>
|
||||
<Properties>
|
||||
<Id>XuiControlsList</Id>
|
||||
<Width>492.000000</Width>
|
||||
<Height>209.679993</Height>
|
||||
<Position>44.880005,88.000000,0.000000</Position>
|
||||
<NavUp>XuiControlNoSlider</NavUp>
|
||||
<ItemsText>RetroPad Button B:
|
||||
RetroPad Button Y:
|
||||
RetroPad Button Select:
|
||||
RetroPad Button Start:
|
||||
RetroPad D-Pad Up:
|
||||
RetroPad D-Pad Down:
|
||||
RetroPad D-Pad Left:
|
||||
RetroPad D-Pad Right:
|
||||
RetroPad Button A:
|
||||
RetroPad Button X:
|
||||
RetroPad Button L1:
|
||||
RetroPad Button R1:
|
||||
RetroPad Button L2:
|
||||
RetroPad Button R2:
|
||||
RetroPad Button L3:
|
||||
RetroPad Button R3:
|
||||
Reset all buttons to defaults
|
||||
</ItemsText>
|
||||
</Properties>
|
||||
<XuiListItem>
|
||||
<Properties>
|
||||
<Id>control_ListItem</Id>
|
||||
<Width>226.000000</Width>
|
||||
<Height>45.000000</Height>
|
||||
<Position>7.000000,22.000000,0.000000</Position>
|
||||
<Anchor>5</Anchor>
|
||||
<Show>false</Show>
|
||||
<Visual>XuiButton</Visual>
|
||||
<InterItemSpacing>0.000000,10.000000,0.000000</InterItemSpacing>
|
||||
</Properties>
|
||||
</XuiListItem>
|
||||
<XuiListItem>
|
||||
<Properties>
|
||||
<Id>control_ListItem</Id>
|
||||
<Width>226.000000</Width>
|
||||
<Height>45.000000</Height>
|
||||
<Position>7.000000,22.000000,0.000000</Position>
|
||||
<Anchor>5</Anchor>
|
||||
<Show>false</Show>
|
||||
<Visual>XuiButton</Visual>
|
||||
<InterItemSpacing>0.000000,10.000000,0.000000</InterItemSpacing>
|
||||
</Properties>
|
||||
</XuiListItem>
|
||||
<XuiListItem>
|
||||
<Properties>
|
||||
<Id>control_ListItem</Id>
|
||||
<Width>226.000000</Width>
|
||||
<Height>45.000000</Height>
|
||||
<Position>7.000000,22.000000,0.000000</Position>
|
||||
<Anchor>5</Anchor>
|
||||
<Show>false</Show>
|
||||
<Visual>XuiButton</Visual>
|
||||
<InterItemSpacing>0.000000,10.000000,0.000000</InterItemSpacing>
|
||||
</Properties>
|
||||
</XuiListItem>
|
||||
<XuiListItem>
|
||||
<Properties>
|
||||
<Id>control_ListItem</Id>
|
||||
<Width>226.000000</Width>
|
||||
<Height>45.000000</Height>
|
||||
<Position>7.000000,22.000000,0.000000</Position>
|
||||
<Anchor>5</Anchor>
|
||||
<Show>false</Show>
|
||||
<Visual>XuiButton</Visual>
|
||||
<InterItemSpacing>0.000000,10.000000,0.000000</InterItemSpacing>
|
||||
</Properties>
|
||||
</XuiListItem>
|
||||
<XuiListItem>
|
||||
<Properties>
|
||||
<Id>control_ListItem</Id>
|
||||
<Width>226.000000</Width>
|
||||
<Height>45.000000</Height>
|
||||
<Position>7.000000,22.000000,0.000000</Position>
|
||||
<Anchor>5</Anchor>
|
||||
<Show>false</Show>
|
||||
<Visual>XuiButton</Visual>
|
||||
<InterItemSpacing>0.000000,10.000000,0.000000</InterItemSpacing>
|
||||
</Properties>
|
||||
</XuiListItem>
|
||||
<XuiListItem>
|
||||
<Properties>
|
||||
<Id>control_ListItem</Id>
|
||||
<Width>226.000000</Width>
|
||||
<Height>45.000000</Height>
|
||||
<Position>7.000000,22.000000,0.000000</Position>
|
||||
<Anchor>5</Anchor>
|
||||
<Show>false</Show>
|
||||
<Visual>XuiButton</Visual>
|
||||
<InterItemSpacing>0.000000,10.000000,0.000000</InterItemSpacing>
|
||||
</Properties>
|
||||
</XuiListItem>
|
||||
<XuiListItem>
|
||||
<Properties>
|
||||
<Id>control_ListItem</Id>
|
||||
<Width>226.000000</Width>
|
||||
<Height>45.000000</Height>
|
||||
<Position>7.000000,22.000000,0.000000</Position>
|
||||
<Anchor>5</Anchor>
|
||||
<Show>false</Show>
|
||||
<Visual>XuiButton</Visual>
|
||||
<InterItemSpacing>0.000000,10.000000,0.000000</InterItemSpacing>
|
||||
</Properties>
|
||||
</XuiListItem>
|
||||
<XuiListItem>
|
||||
<Properties>
|
||||
<Id>control_ListItem</Id>
|
||||
<Width>226.000000</Width>
|
||||
<Height>45.000000</Height>
|
||||
<Position>7.000000,22.000000,0.000000</Position>
|
||||
<Anchor>5</Anchor>
|
||||
<Show>false</Show>
|
||||
<Visual>XuiButton</Visual>
|
||||
<InterItemSpacing>0.000000,10.000000,0.000000</InterItemSpacing>
|
||||
</Properties>
|
||||
</XuiListItem>
|
||||
<XuiListItem>
|
||||
<Properties>
|
||||
<Id>control_ListItem</Id>
|
||||
<Width>226.000000</Width>
|
||||
<Height>45.000000</Height>
|
||||
<Position>7.000000,22.000000,0.000000</Position>
|
||||
<Anchor>5</Anchor>
|
||||
<Show>false</Show>
|
||||
<Visual>XuiButton</Visual>
|
||||
<InterItemSpacing>0.000000,10.000000,0.000000</InterItemSpacing>
|
||||
</Properties>
|
||||
</XuiListItem>
|
||||
<XuiListItem>
|
||||
<Properties>
|
||||
<Id>control_ListItem</Id>
|
||||
<Width>226.000000</Width>
|
||||
<Height>45.000000</Height>
|
||||
<Position>7.000000,22.000000,0.000000</Position>
|
||||
<Anchor>5</Anchor>
|
||||
<Show>false</Show>
|
||||
<Visual>XuiButton</Visual>
|
||||
<InterItemSpacing>0.000000,10.000000,0.000000</InterItemSpacing>
|
||||
</Properties>
|
||||
</XuiListItem>
|
||||
<XuiListItem>
|
||||
<Properties>
|
||||
<Id>control_ListItem</Id>
|
||||
<Width>226.000000</Width>
|
||||
<Height>45.000000</Height>
|
||||
<Position>7.000000,22.000000,0.000000</Position>
|
||||
<Anchor>5</Anchor>
|
||||
<Show>false</Show>
|
||||
<Visual>XuiButton</Visual>
|
||||
<InterItemSpacing>0.000000,10.000000,0.000000</InterItemSpacing>
|
||||
</Properties>
|
||||
</XuiListItem>
|
||||
<XuiListItem>
|
||||
<Properties>
|
||||
<Id>control_ListItem</Id>
|
||||
<Width>226.000000</Width>
|
||||
<Height>45.000000</Height>
|
||||
<Position>7.000000,22.000000,0.000000</Position>
|
||||
<Anchor>5</Anchor>
|
||||
<Show>false</Show>
|
||||
<Visual>XuiButton</Visual>
|
||||
<InterItemSpacing>0.000000,10.000000,0.000000</InterItemSpacing>
|
||||
</Properties>
|
||||
</XuiListItem>
|
||||
<XuiListItem>
|
||||
<Properties>
|
||||
<Id>control_ListItem</Id>
|
||||
<Width>226.000000</Width>
|
||||
<Height>45.000000</Height>
|
||||
<Position>7.000000,22.000000,0.000000</Position>
|
||||
<Anchor>5</Anchor>
|
||||
<Show>false</Show>
|
||||
<Visual>XuiButton</Visual>
|
||||
<InterItemSpacing>0.000000,10.000000,0.000000</InterItemSpacing>
|
||||
</Properties>
|
||||
</XuiListItem>
|
||||
<XuiListItem>
|
||||
<Properties>
|
||||
<Id>control_ListItem</Id>
|
||||
<Width>226.000000</Width>
|
||||
<Height>45.000000</Height>
|
||||
<Position>7.000000,22.000000,0.000000</Position>
|
||||
<Anchor>5</Anchor>
|
||||
<Show>false</Show>
|
||||
<Visual>XuiButton</Visual>
|
||||
<InterItemSpacing>0.000000,10.000000,0.000000</InterItemSpacing>
|
||||
</Properties>
|
||||
</XuiListItem>
|
||||
<XuiListItem>
|
||||
<Properties>
|
||||
<Id>control_ListItem</Id>
|
||||
<Width>226.000000</Width>
|
||||
<Height>45.000000</Height>
|
||||
<Position>7.000000,22.000000,0.000000</Position>
|
||||
<Anchor>5</Anchor>
|
||||
<Show>false</Show>
|
||||
<Visual>XuiButton</Visual>
|
||||
<InterItemSpacing>0.000000,10.000000,0.000000</InterItemSpacing>
|
||||
</Properties>
|
||||
</XuiListItem>
|
||||
<XuiListItem>
|
||||
<Properties>
|
||||
<Id>control_ListItem</Id>
|
||||
<Width>226.000000</Width>
|
||||
<Height>45.000000</Height>
|
||||
<Position>7.000000,22.000000,0.000000</Position>
|
||||
<Anchor>5</Anchor>
|
||||
<Show>false</Show>
|
||||
<Visual>XuiButton</Visual>
|
||||
<InterItemSpacing>0.000000,10.000000,0.000000</InterItemSpacing>
|
||||
</Properties>
|
||||
</XuiListItem>
|
||||
<XuiListItem>
|
||||
<Properties>
|
||||
<Id>control_ListItem</Id>
|
||||
<Width>226.000000</Width>
|
||||
<Height>45.000000</Height>
|
||||
<Position>7.000000,22.000000,0.000000</Position>
|
||||
<Anchor>5</Anchor>
|
||||
<Show>false</Show>
|
||||
<Visual>XuiButton</Visual>
|
||||
<InterItemSpacing>0.000000,10.000000,0.000000</InterItemSpacing>
|
||||
</Properties>
|
||||
</XuiListItem>
|
||||
<XuiListItem>
|
||||
<Properties>
|
||||
<Id>control_ListItem</Id>
|
||||
<Width>226.000000</Width>
|
||||
<Height>45.000000</Height>
|
||||
<Position>7.000000,22.000000,0.000000</Position>
|
||||
<Anchor>5</Anchor>
|
||||
<Show>false</Show>
|
||||
<Visual>XuiButton</Visual>
|
||||
<InterItemSpacing>0.000000,10.000000,0.000000</InterItemSpacing>
|
||||
</Properties>
|
||||
</XuiListItem>
|
||||
</XuiCommonList>
|
||||
<XuiBackButton>
|
||||
<Properties>
|
||||
<Id>XuiBackButton</Id>
|
||||
<Width>208.632019</Width>
|
||||
<Height>36.000000</Height>
|
||||
<Position>356.670013,309.000000,0.000000</Position>
|
||||
<Text>Go back to menu</Text>
|
||||
<PressKey>22593</PressKey>
|
||||
</Properties>
|
||||
</XuiBackButton>
|
||||
<XuiSlider>
|
||||
<Properties>
|
||||
<Id>XuiControlNoSlider</Id>
|
||||
<Width>94.000061</Width>
|
||||
<Height>64.000000</Height>
|
||||
<Position>440.000000,16.000000,0.000000</Position>
|
||||
<NavDown>XuiControlsList</NavDown>
|
||||
<RangeMax>3</RangeMax>
|
||||
</Properties>
|
||||
</XuiSlider>
|
||||
</XuiScene>
|
||||
</XuiCanvas>
|
||||
@@ -0,0 +1,187 @@
|
||||
<XuiCanvas version="000c">
|
||||
<Properties>
|
||||
<Width>1280.000000</Width>
|
||||
<Height>720.000000</Height>
|
||||
</Properties>
|
||||
<XuiScene>
|
||||
<Properties>
|
||||
<Id>XuiSceneFileBrowser</Id>
|
||||
<Width>575.888062</Width>
|
||||
<Height>336.017609</Height>
|
||||
<Position>333.995880,209.035965,0.000000</Position>
|
||||
<ClassOverride>RetroArchFileBrowser</ClassOverride>
|
||||
</Properties>
|
||||
<XuiText>
|
||||
<Properties>
|
||||
<Id>XuiTxtTitle</Id>
|
||||
<Width>111.840027</Width>
|
||||
<Height>40.000000</Height>
|
||||
<Position>28.893612,12.519989,0.000000</Position>
|
||||
<Text>Filebrowser</Text>
|
||||
<TextColor>0xff0f0f0f</TextColor>
|
||||
<DropShadowColor>0x800f0f0f</DropShadowColor>
|
||||
<Font>Arial Unicode MS</Font>
|
||||
<TextStyle>21</TextStyle>
|
||||
</Properties>
|
||||
</XuiText>
|
||||
<XuiCommonList>
|
||||
<Properties>
|
||||
<Id>XuiRomList</Id>
|
||||
<Width>536.582458</Width>
|
||||
<Height>170.800018</Height>
|
||||
<Position>22.799980,81.600006,0.000000</Position>
|
||||
<NavUp>XuiBtnGameDir</NavUp>
|
||||
<NavDown>XuiBtnGameDir</NavDown>
|
||||
</Properties>
|
||||
<XuiListItem>
|
||||
<Properties>
|
||||
<Id>control_ListItem</Id>
|
||||
<Width>226.000000</Width>
|
||||
<Height>45.000000</Height>
|
||||
<Position>7.000000,22.000000,0.000000</Position>
|
||||
<Anchor>5</Anchor>
|
||||
<Show>false</Show>
|
||||
<Visual>XuiButton</Visual>
|
||||
<InterItemSpacing>0.000000,10.000000,0.000000</InterItemSpacing>
|
||||
</Properties>
|
||||
</XuiListItem>
|
||||
<XuiListItem>
|
||||
<Properties>
|
||||
<Id>control_ListItem</Id>
|
||||
<Width>226.000000</Width>
|
||||
<Height>45.000000</Height>
|
||||
<Position>7.000000,22.000000,0.000000</Position>
|
||||
<Anchor>5</Anchor>
|
||||
<Show>false</Show>
|
||||
<Visual>XuiButton</Visual>
|
||||
<InterItemSpacing>0.000000,10.000000,0.000000</InterItemSpacing>
|
||||
</Properties>
|
||||
</XuiListItem>
|
||||
<XuiListItem>
|
||||
<Properties>
|
||||
<Id>control_ListItem</Id>
|
||||
<Width>226.000000</Width>
|
||||
<Height>45.000000</Height>
|
||||
<Position>7.000000,22.000000,0.000000</Position>
|
||||
<Anchor>5</Anchor>
|
||||
<Show>false</Show>
|
||||
<Visual>XuiButton</Visual>
|
||||
<InterItemSpacing>0.000000,10.000000,0.000000</InterItemSpacing>
|
||||
</Properties>
|
||||
</XuiListItem>
|
||||
<XuiListItem>
|
||||
<Properties>
|
||||
<Id>control_ListItem</Id>
|
||||
<Width>226.000000</Width>
|
||||
<Height>45.000000</Height>
|
||||
<Position>7.000000,22.000000,0.000000</Position>
|
||||
<Anchor>5</Anchor>
|
||||
<Show>false</Show>
|
||||
<Visual>XuiButton</Visual>
|
||||
<InterItemSpacing>0.000000,10.000000,0.000000</InterItemSpacing>
|
||||
</Properties>
|
||||
</XuiListItem>
|
||||
<XuiListItem>
|
||||
<Properties>
|
||||
<Id>control_ListItem</Id>
|
||||
<Width>226.000000</Width>
|
||||
<Height>45.000000</Height>
|
||||
<Position>7.000000,22.000000,0.000000</Position>
|
||||
<Anchor>5</Anchor>
|
||||
<Show>false</Show>
|
||||
<Visual>XuiButton</Visual>
|
||||
<InterItemSpacing>0.000000,10.000000,0.000000</InterItemSpacing>
|
||||
</Properties>
|
||||
</XuiListItem>
|
||||
<XuiListItem>
|
||||
<Properties>
|
||||
<Id>control_ListItem</Id>
|
||||
<Width>226.000000</Width>
|
||||
<Height>45.000000</Height>
|
||||
<Position>7.000000,22.000000,0.000000</Position>
|
||||
<Anchor>5</Anchor>
|
||||
<Show>false</Show>
|
||||
<Visual>XuiButton</Visual>
|
||||
<InterItemSpacing>0.000000,10.000000,0.000000</InterItemSpacing>
|
||||
</Properties>
|
||||
</XuiListItem>
|
||||
<XuiListItem>
|
||||
<Properties>
|
||||
<Id>control_ListItem</Id>
|
||||
<Width>226.000000</Width>
|
||||
<Height>45.000000</Height>
|
||||
<Position>7.000000,22.000000,0.000000</Position>
|
||||
<Anchor>5</Anchor>
|
||||
<Show>false</Show>
|
||||
<Visual>XuiButton</Visual>
|
||||
<InterItemSpacing>0.000000,10.000000,0.000000</InterItemSpacing>
|
||||
</Properties>
|
||||
</XuiListItem>
|
||||
<XuiListItem>
|
||||
<Properties>
|
||||
<Id>control_ListItem</Id>
|
||||
<Width>226.000000</Width>
|
||||
<Height>45.000000</Height>
|
||||
<Position>7.000000,22.000000,0.000000</Position>
|
||||
<Anchor>5</Anchor>
|
||||
<Show>false</Show>
|
||||
<Visual>XuiButton</Visual>
|
||||
<InterItemSpacing>0.000000,10.000000,0.000000</InterItemSpacing>
|
||||
</Properties>
|
||||
</XuiListItem>
|
||||
</XuiCommonList>
|
||||
<XuiBackButton>
|
||||
<Properties>
|
||||
<Id>XuiBackButton1</Id>
|
||||
<Width>204.599976</Width>
|
||||
<Height>36.000000</Height>
|
||||
<Position>353.115234,281.396820,0.000000</Position>
|
||||
<Text>Go back to menu</Text>
|
||||
<PressKey>22593</PressKey>
|
||||
</Properties>
|
||||
</XuiBackButton>
|
||||
<XuiText>
|
||||
<Properties>
|
||||
<Id>XuiTxtRomPath</Id>
|
||||
<Width>166.559998</Width>
|
||||
<Height>28.480011</Height>
|
||||
<Position>96.000000,42.480011,0.000000</Position>
|
||||
<TextColor>0xff0f0f0f</TextColor>
|
||||
<DropShadowColor>0x800f0f0f</DropShadowColor>
|
||||
</Properties>
|
||||
</XuiText>
|
||||
<XuiLabel>
|
||||
<Properties>
|
||||
<Id>XuiLblPath</Id>
|
||||
<Width>72.880005</Width>
|
||||
<Height>28.000000</Height>
|
||||
<Position>26.000000,43.000000,0.000000</Position>
|
||||
<Text>PATH:</Text>
|
||||
</Properties>
|
||||
</XuiLabel>
|
||||
<XuiButton>
|
||||
<Properties>
|
||||
<Id>XuiBtnGameDir</Id>
|
||||
<Width>115.640007</Width>
|
||||
<Height>38.000000</Height>
|
||||
<Position>30.000000,277.000000,0.000000</Position>
|
||||
<NavRight>XuiBtnCacheDir</NavRight>
|
||||
<NavUp>XuiRomList</NavUp>
|
||||
<NavDown>XuiRomList</NavDown>
|
||||
<Text>game:</Text>
|
||||
</Properties>
|
||||
</XuiButton>
|
||||
<XuiButton>
|
||||
<Properties>
|
||||
<Id>XuiBtnCacheDir</Id>
|
||||
<Width>119.960014</Width>
|
||||
<Height>38.000000</Height>
|
||||
<Position>160.000000,277.000000,0.000000</Position>
|
||||
<NavLeft>XuiBtnGameDir</NavLeft>
|
||||
<NavUp>XuiRomList</NavUp>
|
||||
<NavDown>XuiRomList</NavDown>
|
||||
<Text>cache:</Text>
|
||||
</Properties>
|
||||
</XuiButton>
|
||||
</XuiScene>
|
||||
</XuiCanvas>
|
||||
@@ -0,0 +1,173 @@
|
||||
<XuiCanvas version="000c">
|
||||
<Properties>
|
||||
<Width>1280.000000</Width>
|
||||
<Height>720.000000</Height>
|
||||
</Properties>
|
||||
<XuiScene>
|
||||
<Properties>
|
||||
<Id>XuiSceneCoreFileBrowser</Id>
|
||||
<Width>575.888062</Width>
|
||||
<Height>336.017609</Height>
|
||||
<Position>353.995880,209.035965,0.000000</Position>
|
||||
<ClassOverride>RetroArchCoreBrowser</ClassOverride>
|
||||
</Properties>
|
||||
<XuiText>
|
||||
<Properties>
|
||||
<Id>XuiTxtTitle</Id>
|
||||
<Width>326.640015</Width>
|
||||
<Height>40.000000</Height>
|
||||
<Position>28.893612,12.519989,0.000000</Position>
|
||||
<Text>Filebrowser - Select a libretro core</Text>
|
||||
<TextColor>0xff0f0f0f</TextColor>
|
||||
<DropShadowColor>0x800f0f0f</DropShadowColor>
|
||||
<Font>Arial Unicode MS</Font>
|
||||
<TextStyle>21</TextStyle>
|
||||
</Properties>
|
||||
</XuiText>
|
||||
<XuiCommonList>
|
||||
<Properties>
|
||||
<Id>XuiRomList</Id>
|
||||
<Width>536.582458</Width>
|
||||
<Height>170.800018</Height>
|
||||
<Position>22.799980,81.600006,0.000000</Position>
|
||||
</Properties>
|
||||
<XuiListItem>
|
||||
<Properties>
|
||||
<Id>control_ListItem</Id>
|
||||
<Width>226.000000</Width>
|
||||
<Height>45.000000</Height>
|
||||
<Position>7.000000,22.000000,0.000000</Position>
|
||||
<Anchor>5</Anchor>
|
||||
<Show>false</Show>
|
||||
<Visual>XuiButton</Visual>
|
||||
<InterItemSpacing>0.000000,10.000000,0.000000</InterItemSpacing>
|
||||
</Properties>
|
||||
</XuiListItem>
|
||||
<XuiListItem>
|
||||
<Properties>
|
||||
<Id>control_ListItem</Id>
|
||||
<Width>226.000000</Width>
|
||||
<Height>45.000000</Height>
|
||||
<Position>7.000000,22.000000,0.000000</Position>
|
||||
<Anchor>5</Anchor>
|
||||
<Show>false</Show>
|
||||
<Visual>XuiButton</Visual>
|
||||
<InterItemSpacing>0.000000,10.000000,0.000000</InterItemSpacing>
|
||||
</Properties>
|
||||
</XuiListItem>
|
||||
<XuiListItem>
|
||||
<Properties>
|
||||
<Id>control_ListItem</Id>
|
||||
<Width>226.000000</Width>
|
||||
<Height>45.000000</Height>
|
||||
<Position>7.000000,22.000000,0.000000</Position>
|
||||
<Anchor>5</Anchor>
|
||||
<Show>false</Show>
|
||||
<Visual>XuiButton</Visual>
|
||||
<InterItemSpacing>0.000000,10.000000,0.000000</InterItemSpacing>
|
||||
</Properties>
|
||||
</XuiListItem>
|
||||
<XuiListItem>
|
||||
<Properties>
|
||||
<Id>control_ListItem</Id>
|
||||
<Width>226.000000</Width>
|
||||
<Height>45.000000</Height>
|
||||
<Position>7.000000,22.000000,0.000000</Position>
|
||||
<Anchor>5</Anchor>
|
||||
<Show>false</Show>
|
||||
<Visual>XuiButton</Visual>
|
||||
<InterItemSpacing>0.000000,10.000000,0.000000</InterItemSpacing>
|
||||
</Properties>
|
||||
</XuiListItem>
|
||||
<XuiListItem>
|
||||
<Properties>
|
||||
<Id>control_ListItem</Id>
|
||||
<Width>226.000000</Width>
|
||||
<Height>45.000000</Height>
|
||||
<Position>7.000000,22.000000,0.000000</Position>
|
||||
<Anchor>5</Anchor>
|
||||
<Show>false</Show>
|
||||
<Visual>XuiButton</Visual>
|
||||
<InterItemSpacing>0.000000,10.000000,0.000000</InterItemSpacing>
|
||||
</Properties>
|
||||
</XuiListItem>
|
||||
<XuiListItem>
|
||||
<Properties>
|
||||
<Id>control_ListItem</Id>
|
||||
<Width>226.000000</Width>
|
||||
<Height>45.000000</Height>
|
||||
<Position>7.000000,22.000000,0.000000</Position>
|
||||
<Anchor>5</Anchor>
|
||||
<Show>false</Show>
|
||||
<Visual>XuiButton</Visual>
|
||||
<InterItemSpacing>0.000000,10.000000,0.000000</InterItemSpacing>
|
||||
</Properties>
|
||||
</XuiListItem>
|
||||
<XuiListItem>
|
||||
<Properties>
|
||||
<Id>control_ListItem</Id>
|
||||
<Width>226.000000</Width>
|
||||
<Height>45.000000</Height>
|
||||
<Position>7.000000,22.000000,0.000000</Position>
|
||||
<Anchor>5</Anchor>
|
||||
<Show>false</Show>
|
||||
<Visual>XuiButton</Visual>
|
||||
<InterItemSpacing>0.000000,10.000000,0.000000</InterItemSpacing>
|
||||
</Properties>
|
||||
</XuiListItem>
|
||||
<XuiListItem>
|
||||
<Properties>
|
||||
<Id>control_ListItem</Id>
|
||||
<Width>226.000000</Width>
|
||||
<Height>45.000000</Height>
|
||||
<Position>7.000000,22.000000,0.000000</Position>
|
||||
<Anchor>5</Anchor>
|
||||
<Show>false</Show>
|
||||
<Visual>XuiButton</Visual>
|
||||
<InterItemSpacing>0.000000,10.000000,0.000000</InterItemSpacing>
|
||||
</Properties>
|
||||
</XuiListItem>
|
||||
<XuiListItem>
|
||||
<Properties>
|
||||
<Id>control_ListItem</Id>
|
||||
<Width>226.000000</Width>
|
||||
<Height>45.000000</Height>
|
||||
<Position>7.000000,22.000000,0.000000</Position>
|
||||
<Anchor>5</Anchor>
|
||||
<Show>false</Show>
|
||||
<Visual>XuiButton</Visual>
|
||||
<InterItemSpacing>0.000000,10.000000,0.000000</InterItemSpacing>
|
||||
</Properties>
|
||||
</XuiListItem>
|
||||
</XuiCommonList>
|
||||
<XuiBackButton>
|
||||
<Properties>
|
||||
<Id>XuiBackButton1</Id>
|
||||
<Width>219.000000</Width>
|
||||
<Height>36.000000</Height>
|
||||
<Position>338.715210,281.396820,0.000000</Position>
|
||||
<Text>Go back to menu</Text>
|
||||
<PressKey>22593</PressKey>
|
||||
</Properties>
|
||||
</XuiBackButton>
|
||||
<XuiText>
|
||||
<Properties>
|
||||
<Id>XuiTxtRomPath</Id>
|
||||
<Width>166.559998</Width>
|
||||
<Height>28.480011</Height>
|
||||
<Position>96.000000,42.480011,0.000000</Position>
|
||||
<TextColor>0xff0f0f0f</TextColor>
|
||||
<DropShadowColor>0x800f0f0f</DropShadowColor>
|
||||
</Properties>
|
||||
</XuiText>
|
||||
<XuiLabel>
|
||||
<Properties>
|
||||
<Id>XuiLblPath</Id>
|
||||
<Width>72.880005</Width>
|
||||
<Height>28.000000</Height>
|
||||
<Position>26.000000,43.000000,0.000000</Position>
|
||||
<Text>PATH:</Text>
|
||||
</Properties>
|
||||
</XuiLabel>
|
||||
</XuiScene>
|
||||
</XuiCanvas>
|
||||
@@ -0,0 +1,116 @@
|
||||
<XuiCanvas version="000c">
|
||||
<Properties>
|
||||
<Width>1280.000000</Width>
|
||||
<Height>720.000000</Height>
|
||||
</Properties>
|
||||
<XuiScene>
|
||||
<Properties>
|
||||
<Id>XuiScene1</Id>
|
||||
<Width>584.528076</Width>
|
||||
<Height>363.320007</Height>
|
||||
<Position>347.429474,184.843964,0.000000</Position>
|
||||
<ClassOverride>RetroArchMain</ClassOverride>
|
||||
</Properties>
|
||||
<XuiButton>
|
||||
<Properties>
|
||||
<Id>XuiBtnRomBrowser</Id>
|
||||
<Width>488.312012</Width>
|
||||
<Height>30.799988</Height>
|
||||
<Position>38.127724,64.215515,0.000000</Position>
|
||||
<Pivot>245.362122,102.247192,0.000000</Pivot>
|
||||
<NavUp>XuiBtnQuit</NavUp>
|
||||
<NavDown>XuiBtnQuickMenu</NavDown>
|
||||
<Text>ROM Browser</Text>
|
||||
</Properties>
|
||||
</XuiButton>
|
||||
<XuiText>
|
||||
<Properties>
|
||||
<Id>XuiTxtTitle</Id>
|
||||
<Width>247.200012</Width>
|
||||
<Height>40.000000</Height>
|
||||
<Position>43.581604,21.159988,0.000000</Position>
|
||||
<Text>RetroArch 360</Text>
|
||||
<TextColor>0xff0f0f0f</TextColor>
|
||||
<DropShadowColor>0x800f0f0f</DropShadowColor>
|
||||
<Font>Arial Unicode MS</Font>
|
||||
<TextStyle>21</TextStyle>
|
||||
</Properties>
|
||||
</XuiText>
|
||||
<XuiButton>
|
||||
<Properties>
|
||||
<Id>XuiBtnSettings</Id>
|
||||
<Width>488.312012</Width>
|
||||
<Height>30.799988</Height>
|
||||
<Position>38.127960,196.615982,0.000000</Position>
|
||||
<NavUp>XuiBtnControls</NavUp>
|
||||
<NavDown>XuiBtnLibsnesCore</NavDown>
|
||||
<Text>Settings</Text>
|
||||
</Properties>
|
||||
</XuiButton>
|
||||
<XuiButton>
|
||||
<Properties>
|
||||
<Id>XuiBtnQuit</Id>
|
||||
<Width>488.312012</Width>
|
||||
<Height>30.799988</Height>
|
||||
<Position>38.327736,287.007996,0.000000</Position>
|
||||
<Pivot>245.162109,-84.153275,0.000000</Pivot>
|
||||
<NavUp>XuiBtnLibsnesCore</NavUp>
|
||||
<NavDown>XuiBtnRomBrowser</NavDown>
|
||||
<Text>Quit</Text>
|
||||
</Properties>
|
||||
</XuiButton>
|
||||
<XuiLabel>
|
||||
<Properties>
|
||||
<Id>XuiLblCore</Id>
|
||||
<Width>124.000000</Width>
|
||||
<Height>28.000000</Height>
|
||||
<Position>12.544006,324.792023,0.000000</Position>
|
||||
<Text>Libretro core:</Text>
|
||||
</Properties>
|
||||
</XuiLabel>
|
||||
<XuiText>
|
||||
<Properties>
|
||||
<Id>XuiTxtCoreText</Id>
|
||||
<Width>224.399963</Width>
|
||||
<Height>34.000000</Height>
|
||||
<Position>134.944031,324.391998,0.000000</Position>
|
||||
<TextColor>0xff0f0f0f</TextColor>
|
||||
<DropShadowColor>0x800f0f0f</DropShadowColor>
|
||||
<Font>Arial Unicode MS</Font>
|
||||
</Properties>
|
||||
</XuiText>
|
||||
<XuiButton>
|
||||
<Properties>
|
||||
<Id>XuiBtnQuickMenu</Id>
|
||||
<Width>488.312012</Width>
|
||||
<Height>30.799988</Height>
|
||||
<Position>38.130001,106.655991,0.000000</Position>
|
||||
<NavUp>XuiBtnRomBrowser</NavUp>
|
||||
<NavDown>XuiBtnControls</NavDown>
|
||||
<Text>Quick Menu</Text>
|
||||
</Properties>
|
||||
</XuiButton>
|
||||
<XuiButton>
|
||||
<Properties>
|
||||
<Id>XuiBtnControls</Id>
|
||||
<Width>488.312012</Width>
|
||||
<Height>30.799988</Height>
|
||||
<Position>38.130001,151.655991,0.000000</Position>
|
||||
<NavUp>XuiBtnQuickMenu</NavUp>
|
||||
<NavDown>XuiBtnSettings</NavDown>
|
||||
<Text>Controls</Text>
|
||||
</Properties>
|
||||
</XuiButton>
|
||||
<XuiButton>
|
||||
<Properties>
|
||||
<Id>XuiBtnLibsnesCore</Id>
|
||||
<Width>488.312012</Width>
|
||||
<Height>30.799988</Height>
|
||||
<Position>38.127960,241.615982,0.000000</Position>
|
||||
<NavUp>XuiBtnSettings</NavUp>
|
||||
<NavDown>XuiBtnQuit</NavDown>
|
||||
<Text>Change libretro core</Text>
|
||||
</Properties>
|
||||
</XuiButton>
|
||||
</XuiScene>
|
||||
</XuiCanvas>
|
||||
@@ -0,0 +1,130 @@
|
||||
<XuiCanvas version="000c">
|
||||
<Properties>
|
||||
<Width>1280.000000</Width>
|
||||
<Height>720.000000</Height>
|
||||
</Properties>
|
||||
<XuiScene>
|
||||
<Properties>
|
||||
<Id>XuiScene1</Id>
|
||||
<Width>584.528076</Width>
|
||||
<Height>363.320007</Height>
|
||||
<Position>302.429474,184.843964,0.000000</Position>
|
||||
<ClassOverride>RetroArchQuickMenu</ClassOverride>
|
||||
</Properties>
|
||||
<XuiText>
|
||||
<Properties>
|
||||
<Id>XuiTxtTitle</Id>
|
||||
<Width>121.056023</Width>
|
||||
<Height>40.000000</Height>
|
||||
<Position>43.581604,21.159988,0.000000</Position>
|
||||
<Text>Quick Menu</Text>
|
||||
<TextColor>0xff0f0f0f</TextColor>
|
||||
<DropShadowColor>0x800f0f0f</DropShadowColor>
|
||||
<Font>Arial Unicode MS</Font>
|
||||
<TextStyle>21</TextStyle>
|
||||
</Properties>
|
||||
</XuiText>
|
||||
<XuiCommonList>
|
||||
<Properties>
|
||||
<Id>XuiQuickMenuList</Id>
|
||||
<Width>492.000000</Width>
|
||||
<Height>232.720001</Height>
|
||||
<Position>44.880005,64.959991,0.000000</Position>
|
||||
<ItemsText>Load State
|
||||
Save State
|
||||
Aspect Ratio:
|
||||
Overscan:
|
||||
Orientation:
|
||||
Resize Mode
|
||||
Frame Advance
|
||||
Screenshot Mode
|
||||
Reset
|
||||
Return to Game
|
||||
Return to Dashboard
|
||||
</ItemsText>
|
||||
</Properties>
|
||||
<XuiListItem>
|
||||
<Properties>
|
||||
<Id>control_ListItem</Id>
|
||||
<Width>226.000000</Width>
|
||||
<Height>45.000000</Height>
|
||||
<Position>7.000000,22.000000,0.000000</Position>
|
||||
<Anchor>5</Anchor>
|
||||
<Show>false</Show>
|
||||
<Visual>XuiButton</Visual>
|
||||
<InterItemSpacing>0.000000,10.000000,0.000000</InterItemSpacing>
|
||||
</Properties>
|
||||
</XuiListItem>
|
||||
<XuiListItem>
|
||||
<Properties>
|
||||
<Id>control_ListItem</Id>
|
||||
<Width>226.000000</Width>
|
||||
<Height>45.000000</Height>
|
||||
<Position>7.000000,22.000000,0.000000</Position>
|
||||
<Anchor>5</Anchor>
|
||||
<Show>false</Show>
|
||||
<Visual>XuiButton</Visual>
|
||||
<InterItemSpacing>0.000000,10.000000,0.000000</InterItemSpacing>
|
||||
</Properties>
|
||||
</XuiListItem>
|
||||
<XuiListItem>
|
||||
<Properties>
|
||||
<Id>control_ListItem</Id>
|
||||
<Width>226.000000</Width>
|
||||
<Height>45.000000</Height>
|
||||
<Position>7.000000,22.000000,0.000000</Position>
|
||||
<Anchor>5</Anchor>
|
||||
<Show>false</Show>
|
||||
<Visual>XuiButton</Visual>
|
||||
<InterItemSpacing>0.000000,10.000000,0.000000</InterItemSpacing>
|
||||
</Properties>
|
||||
</XuiListItem>
|
||||
<XuiListItem>
|
||||
<Properties>
|
||||
<Id>control_ListItem</Id>
|
||||
<Width>226.000000</Width>
|
||||
<Height>45.000000</Height>
|
||||
<Position>7.000000,22.000000,0.000000</Position>
|
||||
<Anchor>5</Anchor>
|
||||
<Show>false</Show>
|
||||
<Visual>XuiButton</Visual>
|
||||
<InterItemSpacing>0.000000,10.000000,0.000000</InterItemSpacing>
|
||||
</Properties>
|
||||
</XuiListItem>
|
||||
<XuiListItem>
|
||||
<Properties>
|
||||
<Id>control_ListItem</Id>
|
||||
<Width>226.000000</Width>
|
||||
<Height>45.000000</Height>
|
||||
<Position>7.000000,22.000000,0.000000</Position>
|
||||
<Anchor>5</Anchor>
|
||||
<Show>false</Show>
|
||||
<Visual>XuiButton</Visual>
|
||||
<InterItemSpacing>0.000000,10.000000,0.000000</InterItemSpacing>
|
||||
</Properties>
|
||||
</XuiListItem>
|
||||
<XuiListItem>
|
||||
<Properties>
|
||||
<Id>control_ListItem</Id>
|
||||
<Width>226.000000</Width>
|
||||
<Height>45.000000</Height>
|
||||
<Position>7.000000,22.000000,0.000000</Position>
|
||||
<Anchor>5</Anchor>
|
||||
<Show>false</Show>
|
||||
<Visual>XuiButton</Visual>
|
||||
<InterItemSpacing>0.000000,10.000000,0.000000</InterItemSpacing>
|
||||
</Properties>
|
||||
</XuiListItem>
|
||||
</XuiCommonList>
|
||||
<XuiBackButton>
|
||||
<Properties>
|
||||
<Id>XuiBackButton</Id>
|
||||
<Width>208.632019</Width>
|
||||
<Height>36.000000</Height>
|
||||
<Position>356.670013,309.000000,0.000000</Position>
|
||||
<Text>Go back to menu</Text>
|
||||
<PressKey>22593</PressKey>
|
||||
</Properties>
|
||||
</XuiBackButton>
|
||||
</XuiScene>
|
||||
</XuiCanvas>
|
||||
@@ -0,0 +1,202 @@
|
||||
<XuiCanvas version="000c">
|
||||
<Properties>
|
||||
<Width>1280.000000</Width>
|
||||
<Height>720.000000</Height>
|
||||
</Properties>
|
||||
<XuiScene>
|
||||
<Properties>
|
||||
<Id>XuiScene1</Id>
|
||||
<Width>584.528076</Width>
|
||||
<Height>363.320007</Height>
|
||||
<Position>344.000031,184.000015,0.000000</Position>
|
||||
<ClassOverride>RetroArchSettings</ClassOverride>
|
||||
</Properties>
|
||||
<XuiText>
|
||||
<Properties>
|
||||
<Id>XuiTxtTitle</Id>
|
||||
<Width>121.056023</Width>
|
||||
<Height>40.000000</Height>
|
||||
<Position>43.581604,21.159988,0.000000</Position>
|
||||
<Text>Settings</Text>
|
||||
<TextColor>0xff0f0f0f</TextColor>
|
||||
<DropShadowColor>0x800f0f0f</DropShadowColor>
|
||||
<Font>Arial Unicode MS</Font>
|
||||
<TextStyle>21</TextStyle>
|
||||
</Properties>
|
||||
</XuiText>
|
||||
<XuiCommonList>
|
||||
<Properties>
|
||||
<Id>XuiSettingsList</Id>
|
||||
<Width>492.000000</Width>
|
||||
<Height>232.720001</Height>
|
||||
<Position>44.880005,64.959991,0.000000</Position>
|
||||
<ItemsText>Rewind:
|
||||
Info messages:
|
||||
Menus:
|
||||
Color Format:
|
||||
Gamma Correction:
|
||||
Shader #1:
|
||||
Shader #2:
|
||||
Hardware filtering shader #1:
|
||||
Hardware filtering shader #2:
|
||||
Cutom Scaling/Dual Shaders:
|
||||
Cutom Scaling Factor:
|
||||
</ItemsText>
|
||||
</Properties>
|
||||
<XuiListItem>
|
||||
<Properties>
|
||||
<Id>control_ListItem</Id>
|
||||
<Width>226.000000</Width>
|
||||
<Height>45.000000</Height>
|
||||
<Position>7.000000,22.000000,0.000000</Position>
|
||||
<Anchor>5</Anchor>
|
||||
<Show>false</Show>
|
||||
<Visual>XuiButton</Visual>
|
||||
<InterItemSpacing>0.000000,10.000000,0.000000</InterItemSpacing>
|
||||
</Properties>
|
||||
</XuiListItem>
|
||||
<XuiListItem>
|
||||
<Properties>
|
||||
<Id>control_ListItem</Id>
|
||||
<Width>226.000000</Width>
|
||||
<Height>45.000000</Height>
|
||||
<Position>7.000000,22.000000,0.000000</Position>
|
||||
<Anchor>5</Anchor>
|
||||
<Show>false</Show>
|
||||
<Visual>XuiButton</Visual>
|
||||
<InterItemSpacing>0.000000,10.000000,0.000000</InterItemSpacing>
|
||||
</Properties>
|
||||
</XuiListItem>
|
||||
<XuiListItem>
|
||||
<Properties>
|
||||
<Id>control_ListItem</Id>
|
||||
<Width>226.000000</Width>
|
||||
<Height>45.000000</Height>
|
||||
<Position>7.000000,22.000000,0.000000</Position>
|
||||
<Anchor>5</Anchor>
|
||||
<Show>false</Show>
|
||||
<Visual>XuiButton</Visual>
|
||||
<InterItemSpacing>0.000000,10.000000,0.000000</InterItemSpacing>
|
||||
</Properties>
|
||||
</XuiListItem>
|
||||
<XuiListItem>
|
||||
<Properties>
|
||||
<Id>control_ListItem</Id>
|
||||
<Width>226.000000</Width>
|
||||
<Height>45.000000</Height>
|
||||
<Position>7.000000,22.000000,0.000000</Position>
|
||||
<Anchor>5</Anchor>
|
||||
<Show>false</Show>
|
||||
<Visual>XuiButton</Visual>
|
||||
<InterItemSpacing>0.000000,10.000000,0.000000</InterItemSpacing>
|
||||
</Properties>
|
||||
</XuiListItem>
|
||||
<XuiListItem>
|
||||
<Properties>
|
||||
<Id>control_ListItem</Id>
|
||||
<Width>226.000000</Width>
|
||||
<Height>45.000000</Height>
|
||||
<Position>7.000000,22.000000,0.000000</Position>
|
||||
<Anchor>5</Anchor>
|
||||
<Show>false</Show>
|
||||
<Visual>XuiButton</Visual>
|
||||
<InterItemSpacing>0.000000,10.000000,0.000000</InterItemSpacing>
|
||||
</Properties>
|
||||
</XuiListItem>
|
||||
<XuiListItem>
|
||||
<Properties>
|
||||
<Id>control_ListItem</Id>
|
||||
<Width>226.000000</Width>
|
||||
<Height>45.000000</Height>
|
||||
<Position>7.000000,22.000000,0.000000</Position>
|
||||
<Anchor>5</Anchor>
|
||||
<Show>false</Show>
|
||||
<Visual>XuiButton</Visual>
|
||||
<InterItemSpacing>0.000000,10.000000,0.000000</InterItemSpacing>
|
||||
</Properties>
|
||||
</XuiListItem>
|
||||
<XuiListItem>
|
||||
<Properties>
|
||||
<Id>control_ListItem</Id>
|
||||
<Width>226.000000</Width>
|
||||
<Height>45.000000</Height>
|
||||
<Position>7.000000,22.000000,0.000000</Position>
|
||||
<Anchor>5</Anchor>
|
||||
<Show>false</Show>
|
||||
<Visual>XuiButton</Visual>
|
||||
<InterItemSpacing>0.000000,10.000000,0.000000</InterItemSpacing>
|
||||
</Properties>
|
||||
</XuiListItem>
|
||||
<XuiListItem>
|
||||
<Properties>
|
||||
<Id>control_ListItem</Id>
|
||||
<Width>226.000000</Width>
|
||||
<Height>45.000000</Height>
|
||||
<Position>7.000000,22.000000,0.000000</Position>
|
||||
<Anchor>5</Anchor>
|
||||
<Show>false</Show>
|
||||
<Visual>XuiButton</Visual>
|
||||
<InterItemSpacing>0.000000,10.000000,0.000000</InterItemSpacing>
|
||||
</Properties>
|
||||
</XuiListItem>
|
||||
<XuiListItem>
|
||||
<Properties>
|
||||
<Id>control_ListItem</Id>
|
||||
<Width>226.000000</Width>
|
||||
<Height>45.000000</Height>
|
||||
<Position>7.000000,22.000000,0.000000</Position>
|
||||
<Anchor>5</Anchor>
|
||||
<Show>false</Show>
|
||||
<Visual>XuiButton</Visual>
|
||||
<InterItemSpacing>0.000000,10.000000,0.000000</InterItemSpacing>
|
||||
</Properties>
|
||||
</XuiListItem>
|
||||
<XuiListItem>
|
||||
<Properties>
|
||||
<Id>control_ListItem</Id>
|
||||
<Width>226.000000</Width>
|
||||
<Height>45.000000</Height>
|
||||
<Position>7.000000,22.000000,0.000000</Position>
|
||||
<Anchor>5</Anchor>
|
||||
<Show>false</Show>
|
||||
<Visual>XuiButton</Visual>
|
||||
<InterItemSpacing>0.000000,10.000000,0.000000</InterItemSpacing>
|
||||
</Properties>
|
||||
</XuiListItem>
|
||||
<XuiListItem>
|
||||
<Properties>
|
||||
<Id>control_ListItem</Id>
|
||||
<Width>226.000000</Width>
|
||||
<Height>45.000000</Height>
|
||||
<Position>7.000000,22.000000,0.000000</Position>
|
||||
<Anchor>5</Anchor>
|
||||
<Show>false</Show>
|
||||
<Visual>XuiButton</Visual>
|
||||
<InterItemSpacing>0.000000,10.000000,0.000000</InterItemSpacing>
|
||||
</Properties>
|
||||
</XuiListItem>
|
||||
<XuiListItem>
|
||||
<Properties>
|
||||
<Id>control_ListItem</Id>
|
||||
<Width>226.000000</Width>
|
||||
<Height>45.000000</Height>
|
||||
<Position>7.000000,22.000000,0.000000</Position>
|
||||
<Anchor>5</Anchor>
|
||||
<Show>false</Show>
|
||||
<Visual>XuiButton</Visual>
|
||||
<InterItemSpacing>0.000000,10.000000,0.000000</InterItemSpacing>
|
||||
</Properties>
|
||||
</XuiListItem>
|
||||
</XuiCommonList>
|
||||
<XuiBackButton>
|
||||
<Properties>
|
||||
<Id>XuiBackButton</Id>
|
||||
<Width>208.632019</Width>
|
||||
<Height>36.000000</Height>
|
||||
<Position>356.670013,309.000000,0.000000</Position>
|
||||
<Text>Go back to menu</Text>
|
||||
<PressKey>22593</PressKey>
|
||||
</Properties>
|
||||
</XuiBackButton>
|
||||
</XuiScene>
|
||||
</XuiCanvas>
|
||||
@@ -0,0 +1,209 @@
|
||||
<XuiCanvas version="000c">
|
||||
<Properties>
|
||||
<Width>1280.000000</Width>
|
||||
<Height>720.000000</Height>
|
||||
</Properties>
|
||||
<XuiScene>
|
||||
<Properties>
|
||||
<Id>XuiSceneCoreFileBrowser</Id>
|
||||
<Width>575.888062</Width>
|
||||
<Height>336.017609</Height>
|
||||
<Position>353.995880,209.035965,0.000000</Position>
|
||||
<ClassOverride>RetroArchShaderBrowser</ClassOverride>
|
||||
</Properties>
|
||||
<XuiText>
|
||||
<Properties>
|
||||
<Id>XuiTxtTitle</Id>
|
||||
<Width>326.640015</Width>
|
||||
<Height>40.000000</Height>
|
||||
<Position>28.893612,12.519989,0.000000</Position>
|
||||
<Text>Shader selection - Select a shader</Text>
|
||||
<TextColor>0xff0f0f0f</TextColor>
|
||||
<DropShadowColor>0x800f0f0f</DropShadowColor>
|
||||
<Font>Arial Unicode MS</Font>
|
||||
<TextStyle>21</TextStyle>
|
||||
</Properties>
|
||||
</XuiText>
|
||||
<XuiCommonList>
|
||||
<Properties>
|
||||
<Id>XuiRomList</Id>
|
||||
<Width>536.582458</Width>
|
||||
<Height>170.800018</Height>
|
||||
<Position>22.799980,81.600006,0.000000</Position>
|
||||
</Properties>
|
||||
<XuiListItem>
|
||||
<Properties>
|
||||
<Id>control_ListItem</Id>
|
||||
<Width>226.000000</Width>
|
||||
<Height>45.000000</Height>
|
||||
<Position>7.000000,22.000000,0.000000</Position>
|
||||
<Anchor>5</Anchor>
|
||||
<Show>false</Show>
|
||||
<Visual>XuiButton</Visual>
|
||||
<InterItemSpacing>0.000000,10.000000,0.000000</InterItemSpacing>
|
||||
</Properties>
|
||||
</XuiListItem>
|
||||
<XuiListItem>
|
||||
<Properties>
|
||||
<Id>control_ListItem</Id>
|
||||
<Width>226.000000</Width>
|
||||
<Height>45.000000</Height>
|
||||
<Position>7.000000,22.000000,0.000000</Position>
|
||||
<Anchor>5</Anchor>
|
||||
<Show>false</Show>
|
||||
<Visual>XuiButton</Visual>
|
||||
<InterItemSpacing>0.000000,10.000000,0.000000</InterItemSpacing>
|
||||
</Properties>
|
||||
</XuiListItem>
|
||||
<XuiListItem>
|
||||
<Properties>
|
||||
<Id>control_ListItem</Id>
|
||||
<Width>226.000000</Width>
|
||||
<Height>45.000000</Height>
|
||||
<Position>7.000000,22.000000,0.000000</Position>
|
||||
<Anchor>5</Anchor>
|
||||
<Show>false</Show>
|
||||
<Visual>XuiButton</Visual>
|
||||
<InterItemSpacing>0.000000,10.000000,0.000000</InterItemSpacing>
|
||||
</Properties>
|
||||
</XuiListItem>
|
||||
<XuiListItem>
|
||||
<Properties>
|
||||
<Id>control_ListItem</Id>
|
||||
<Width>226.000000</Width>
|
||||
<Height>45.000000</Height>
|
||||
<Position>7.000000,22.000000,0.000000</Position>
|
||||
<Anchor>5</Anchor>
|
||||
<Show>false</Show>
|
||||
<Visual>XuiButton</Visual>
|
||||
<InterItemSpacing>0.000000,10.000000,0.000000</InterItemSpacing>
|
||||
</Properties>
|
||||
</XuiListItem>
|
||||
<XuiListItem>
|
||||
<Properties>
|
||||
<Id>control_ListItem</Id>
|
||||
<Width>226.000000</Width>
|
||||
<Height>45.000000</Height>
|
||||
<Position>7.000000,22.000000,0.000000</Position>
|
||||
<Anchor>5</Anchor>
|
||||
<Show>false</Show>
|
||||
<Visual>XuiButton</Visual>
|
||||
<InterItemSpacing>0.000000,10.000000,0.000000</InterItemSpacing>
|
||||
</Properties>
|
||||
</XuiListItem>
|
||||
<XuiListItem>
|
||||
<Properties>
|
||||
<Id>control_ListItem</Id>
|
||||
<Width>226.000000</Width>
|
||||
<Height>45.000000</Height>
|
||||
<Position>7.000000,22.000000,0.000000</Position>
|
||||
<Anchor>5</Anchor>
|
||||
<Show>false</Show>
|
||||
<Visual>XuiButton</Visual>
|
||||
<InterItemSpacing>0.000000,10.000000,0.000000</InterItemSpacing>
|
||||
</Properties>
|
||||
</XuiListItem>
|
||||
<XuiListItem>
|
||||
<Properties>
|
||||
<Id>control_ListItem</Id>
|
||||
<Width>226.000000</Width>
|
||||
<Height>45.000000</Height>
|
||||
<Position>7.000000,22.000000,0.000000</Position>
|
||||
<Anchor>5</Anchor>
|
||||
<Show>false</Show>
|
||||
<Visual>XuiButton</Visual>
|
||||
<InterItemSpacing>0.000000,10.000000,0.000000</InterItemSpacing>
|
||||
</Properties>
|
||||
</XuiListItem>
|
||||
<XuiListItem>
|
||||
<Properties>
|
||||
<Id>control_ListItem</Id>
|
||||
<Width>226.000000</Width>
|
||||
<Height>45.000000</Height>
|
||||
<Position>7.000000,22.000000,0.000000</Position>
|
||||
<Anchor>5</Anchor>
|
||||
<Show>false</Show>
|
||||
<Visual>XuiButton</Visual>
|
||||
<InterItemSpacing>0.000000,10.000000,0.000000</InterItemSpacing>
|
||||
</Properties>
|
||||
</XuiListItem>
|
||||
<XuiListItem>
|
||||
<Properties>
|
||||
<Id>control_ListItem</Id>
|
||||
<Width>226.000000</Width>
|
||||
<Height>45.000000</Height>
|
||||
<Position>7.000000,22.000000,0.000000</Position>
|
||||
<Anchor>5</Anchor>
|
||||
<Show>false</Show>
|
||||
<Visual>XuiButton</Visual>
|
||||
<InterItemSpacing>0.000000,10.000000,0.000000</InterItemSpacing>
|
||||
</Properties>
|
||||
</XuiListItem>
|
||||
<XuiListItem>
|
||||
<Properties>
|
||||
<Id>control_ListItem</Id>
|
||||
<Width>226.000000</Width>
|
||||
<Height>45.000000</Height>
|
||||
<Position>7.000000,22.000000,0.000000</Position>
|
||||
<Anchor>5</Anchor>
|
||||
<Show>false</Show>
|
||||
<Visual>XuiButton</Visual>
|
||||
<InterItemSpacing>0.000000,10.000000,0.000000</InterItemSpacing>
|
||||
</Properties>
|
||||
</XuiListItem>
|
||||
<XuiListItem>
|
||||
<Properties>
|
||||
<Id>control_ListItem</Id>
|
||||
<Width>226.000000</Width>
|
||||
<Height>45.000000</Height>
|
||||
<Position>7.000000,22.000000,0.000000</Position>
|
||||
<Anchor>5</Anchor>
|
||||
<Show>false</Show>
|
||||
<Visual>XuiButton</Visual>
|
||||
<InterItemSpacing>0.000000,10.000000,0.000000</InterItemSpacing>
|
||||
</Properties>
|
||||
</XuiListItem>
|
||||
<XuiListItem>
|
||||
<Properties>
|
||||
<Id>control_ListItem</Id>
|
||||
<Width>226.000000</Width>
|
||||
<Height>45.000000</Height>
|
||||
<Position>7.000000,22.000000,0.000000</Position>
|
||||
<Anchor>5</Anchor>
|
||||
<Show>false</Show>
|
||||
<Visual>XuiButton</Visual>
|
||||
<InterItemSpacing>0.000000,10.000000,0.000000</InterItemSpacing>
|
||||
</Properties>
|
||||
</XuiListItem>
|
||||
</XuiCommonList>
|
||||
<XuiBackButton>
|
||||
<Properties>
|
||||
<Id>XuiBackButton1</Id>
|
||||
<Width>219.000000</Width>
|
||||
<Height>36.000000</Height>
|
||||
<Position>338.715210,281.396820,0.000000</Position>
|
||||
<Text>Go back to menu</Text>
|
||||
<PressKey>22593</PressKey>
|
||||
</Properties>
|
||||
</XuiBackButton>
|
||||
<XuiText>
|
||||
<Properties>
|
||||
<Id>XuiTxtRomPath</Id>
|
||||
<Width>406.004150</Width>
|
||||
<Height>28.480011</Height>
|
||||
<Position>96.000000,42.480011,0.000000</Position>
|
||||
<TextColor>0xff0f0f0f</TextColor>
|
||||
<DropShadowColor>0x800f0f0f</DropShadowColor>
|
||||
</Properties>
|
||||
</XuiText>
|
||||
<XuiLabel>
|
||||
<Properties>
|
||||
<Id>XuiLblPath</Id>
|
||||
<Width>72.880005</Width>
|
||||
<Height>28.000000</Height>
|
||||
<Position>26.000000,43.000000,0.000000</Position>
|
||||
<Text>PATH:</Text>
|
||||
</Properties>
|
||||
</XuiLabel>
|
||||
</XuiScene>
|
||||
</XuiCanvas>
|
||||
@@ -0,0 +1,40 @@
|
||||
/*
|
||||
VERTEX_SHADER
|
||||
*/
|
||||
void main_vertex
|
||||
(
|
||||
float2 position : POSITION,
|
||||
float2 texCoord : TEXCOORD0,
|
||||
uniform float4x4 modelViewProj,
|
||||
out float4 oPosition : POSITION,
|
||||
out float2 otexCoord : TEXCOORD
|
||||
)
|
||||
{
|
||||
oPosition = mul(modelViewProj, float4(position, 0.0, 1.0));
|
||||
otexCoord = texCoord;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
FRAGMENT SHADER
|
||||
*/
|
||||
struct output
|
||||
{
|
||||
float4 color : COLOR;
|
||||
};
|
||||
|
||||
struct input
|
||||
{
|
||||
float2 video_size;
|
||||
float2 texture_size;
|
||||
float2 output_size;
|
||||
};
|
||||
|
||||
|
||||
output main_fragment(float2 texCoord : TEXCOORD0, uniform sampler2D decal : TEXUNIT0, uniform input IN)
|
||||
{
|
||||
output OUT;
|
||||
OUT.color = tex2D(decal, texCoord);
|
||||
return OUT;
|
||||
}
|
||||
|
||||
+916
@@ -0,0 +1,916 @@
|
||||
/* RetroArch - A frontend for libretro.
|
||||
* Copyright (C) 2010-2012 - Hans-Kristian Arntzen
|
||||
* Copyright (C) 2011-2012 - Daniel De Matteis
|
||||
*
|
||||
* RetroArch is free software: you can redistribute it and/or modify it under the terms
|
||||
* of the GNU General Public License as published by the Free Software Found-
|
||||
* ation, either version 3 of the License, or (at your option) any later version.
|
||||
*
|
||||
* RetroArch is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
|
||||
* without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
|
||||
* PURPOSE. See the GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along with RetroArch.
|
||||
* If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include <stdint.h>
|
||||
#include <crtdefs.h>
|
||||
#include <tchar.h>
|
||||
#include <xtl.h>
|
||||
#include "../console/fileio/file_browser.h"
|
||||
#include "../console/console_ext.h"
|
||||
#include "xdk360_video.h"
|
||||
#include "menu.h"
|
||||
#include "../message.h"
|
||||
|
||||
#include "../general.h"
|
||||
|
||||
CRetroArch app;
|
||||
HXUIOBJ hCur;
|
||||
filebrowser_t browser;
|
||||
filebrowser_t tmp_browser;
|
||||
uint32_t set_shader = 0;
|
||||
wchar_t strw_buffer[PATH_MAX];
|
||||
|
||||
/* Register custom classes */
|
||||
HRESULT CRetroArch::RegisterXuiClasses (void)
|
||||
{
|
||||
CRetroArchMain::Register();
|
||||
CRetroArchFileBrowser::Register();
|
||||
CRetroArchCoreBrowser::Register();
|
||||
CRetroArchShaderBrowser::Register();
|
||||
CRetroArchQuickMenu::Register();
|
||||
CRetroArchControls::Register();
|
||||
CRetroArchSettings::Register();
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Unregister custom classes */
|
||||
HRESULT CRetroArch::UnregisterXuiClasses (void)
|
||||
{
|
||||
CRetroArchMain::Unregister();
|
||||
CRetroArchCoreBrowser::Unregister();
|
||||
CRetroArchShaderBrowser::Unregister();
|
||||
CRetroArchFileBrowser::Unregister();
|
||||
CRetroArchQuickMenu::Register();
|
||||
CRetroArchControls::Register();
|
||||
CRetroArchSettings::Unregister();
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void filebrowser_fetch_directory_entries(const char *path, filebrowser_t * browser, CXuiList * romlist,
|
||||
CXuiTextElement * rompath_title)
|
||||
{
|
||||
filebrowser_push_directory(browser, path, true);
|
||||
|
||||
rarch_convert_char_to_wchar(strw_buffer, path, sizeof(strw_buffer));
|
||||
rompath_title->SetText(strw_buffer);
|
||||
|
||||
romlist->DeleteItems(0, romlist->GetItemCount());
|
||||
romlist->InsertItems(0, browser->file_count);
|
||||
for(unsigned i = 0; i < browser->file_count; i++)
|
||||
{
|
||||
rarch_convert_char_to_wchar(strw_buffer, browser->cur[i].d_name, sizeof(strw_buffer));
|
||||
romlist->SetText(i, strw_buffer);
|
||||
}
|
||||
}
|
||||
|
||||
HRESULT CRetroArchFileBrowser::OnInit(XUIMessageInit * pInitData, BOOL& bHandled)
|
||||
{
|
||||
GetChildById(L"XuiRomList", &m_romlist);
|
||||
GetChildById(L"XuiBackButton1", &m_back);
|
||||
GetChildById(L"XuiTxtRomPath", &m_rompathtitle);
|
||||
GetChildById(L"XuiBtnGameDir", &m_dir_game);
|
||||
GetChildById(L"XuiBtnCacheDir", &m_dir_cache);
|
||||
|
||||
filebrowser_fetch_directory_entries(g_console.default_rom_startup_dir, &browser, &m_romlist, &m_rompathtitle);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
HRESULT CRetroArchCoreBrowser::OnInit(XUIMessageInit * pInitData, BOOL& bHandled)
|
||||
{
|
||||
GetChildById(L"XuiRomList", &m_romlist);
|
||||
GetChildById(L"XuiBackButton1", &m_back);
|
||||
GetChildById(L"XuiTxtRomPath", &m_rompathtitle);
|
||||
|
||||
filebrowser_new(&tmp_browser, "game:", "xex|XEX");
|
||||
filebrowser_fetch_directory_entries("game:", &tmp_browser, &m_romlist, &m_rompathtitle);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
HRESULT CRetroArchShaderBrowser::OnInit(XUIMessageInit * pInitData, BOOL& bHandled)
|
||||
{
|
||||
GetChildById(L"XuiRomList", &m_shaderlist);
|
||||
GetChildById(L"XuiBackButton1", &m_back);
|
||||
GetChildById(L"XuiTxtRomPath", &m_shaderpathtitle);
|
||||
|
||||
filebrowser_new(&tmp_browser, "game:\\media\\shaders", "cg|CG");
|
||||
filebrowser_fetch_directory_entries("game:\\media\\shaders", &tmp_browser, &m_shaderlist, &m_shaderpathtitle);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
HRESULT CRetroArchControls::OnInit(XUIMessageInit * pInitData, BOOL& bHandled)
|
||||
{
|
||||
unsigned i;
|
||||
int controlno;
|
||||
char buttons[RARCH_FIRST_META_KEY][128];
|
||||
|
||||
GetChildById(L"XuiControlsList", &m_controlslist);
|
||||
GetChildById(L"XuiBackButton", &m_back);
|
||||
GetChildById(L"XuiControlNoSlider", &m_controlnoslider);
|
||||
|
||||
m_controlnoslider.SetValue(g_settings.input.currently_selected_controller_no);
|
||||
m_controlnoslider.GetValue(&controlno);
|
||||
|
||||
for(i = 0; i < RARCH_FIRST_META_KEY; i++)
|
||||
{
|
||||
snprintf(buttons[i], sizeof(buttons[i]), "%s #%d: %s", rarch_default_libretro_keybind_name_lut[i], controlno, rarch_input_find_platform_key_label(g_settings.input.binds[controlno][i].joykey));
|
||||
rarch_convert_char_to_wchar(strw_buffer, buttons[i], sizeof(strw_buffer));
|
||||
m_controlslist.SetText(i, strw_buffer);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
HRESULT CRetroArchControls::OnControlNavigate(XUIMessageControlNavigate *pControlNavigateData, BOOL& bHandled)
|
||||
{
|
||||
char button[128];
|
||||
char buttons[RARCH_FIRST_META_KEY][128];
|
||||
int controlno, i, current_index;
|
||||
|
||||
current_index = m_controlslist.GetCurSel();
|
||||
m_controlnoslider.GetValue(&controlno);
|
||||
|
||||
for(i = 0; i < RARCH_FIRST_META_KEY; i++)
|
||||
{
|
||||
snprintf(buttons[i], sizeof(buttons[i]), "%s #%d: %s", rarch_default_libretro_keybind_name_lut[i], controlno, rarch_input_find_platform_key_label(g_settings.input.binds[controlno][i].joykey));
|
||||
rarch_convert_char_to_wchar(strw_buffer, buttons[i], sizeof(strw_buffer));
|
||||
m_controlslist.SetText(i, strw_buffer);
|
||||
}
|
||||
|
||||
switch(pControlNavigateData->nControlNavigate)
|
||||
{
|
||||
case XUI_CONTROL_NAVIGATE_LEFT:
|
||||
if(current_index > 0 && current_index != SETTING_CONTROLS_DEFAULT_ALL)
|
||||
{
|
||||
rarch_input_set_keybind(controlno, KEYBIND_DECREMENT, current_index);
|
||||
snprintf(button, sizeof(button), "%s #%d: %s", rarch_default_libretro_keybind_name_lut[current_index], controlno, rarch_input_find_platform_key_label(g_settings.input.binds[controlno][current_index].joykey));
|
||||
rarch_convert_char_to_wchar(strw_buffer, button, sizeof(strw_buffer));
|
||||
m_controlslist.SetText(current_index, strw_buffer);
|
||||
}
|
||||
break;
|
||||
case XUI_CONTROL_NAVIGATE_RIGHT:
|
||||
if(current_index < RARCH_FIRST_META_KEY && current_index != SETTING_CONTROLS_DEFAULT_ALL)
|
||||
{
|
||||
rarch_input_set_keybind(controlno, KEYBIND_INCREMENT, current_index);
|
||||
snprintf(button, sizeof(button), "%s #%d: %s", rarch_default_libretro_keybind_name_lut[current_index], controlno, rarch_input_find_platform_key_label(g_settings.input.binds[controlno][current_index].joykey));
|
||||
rarch_convert_char_to_wchar(strw_buffer, button, sizeof(strw_buffer));
|
||||
m_controlslist.SetText(current_index, strw_buffer);
|
||||
}
|
||||
break;
|
||||
case XUI_CONTROL_NAVIGATE_UP:
|
||||
case XUI_CONTROL_NAVIGATE_DOWN:
|
||||
break;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
HRESULT CRetroArchControls::OnNotifyPress( HXUIOBJ hObjPressed, int & bHandled )
|
||||
{
|
||||
int current_index, i, controlno;
|
||||
char buttons[RARCH_FIRST_META_KEY][128];
|
||||
m_controlnoslider.GetValue(&controlno);
|
||||
|
||||
if ( hObjPressed == m_controlslist)
|
||||
{
|
||||
current_index = m_controlslist.GetCurSel();
|
||||
|
||||
switch(current_index)
|
||||
{
|
||||
case SETTING_CONTROLS_DEFAULT_ALL:
|
||||
rarch_input_set_default_keybinds(0);
|
||||
|
||||
for(i = 0; i < RARCH_FIRST_META_KEY; i++)
|
||||
{
|
||||
snprintf(buttons[i], sizeof(buttons[i]), "%s #%d: %s", rarch_default_libretro_keybind_name_lut[i], controlno, rarch_input_find_platform_key_label(g_settings.input.binds[controlno][i].joykey));
|
||||
rarch_convert_char_to_wchar(strw_buffer, buttons[i], sizeof(strw_buffer));
|
||||
m_controlslist.SetText(i, strw_buffer);
|
||||
}
|
||||
break;
|
||||
default:
|
||||
rarch_input_set_keybind(controlno, KEYBIND_DEFAULT, current_index);
|
||||
snprintf(buttons[current_index], sizeof(buttons[current_index]), "%s #%d: %s", rarch_default_libretro_keybind_name_lut[current_index], controlno, rarch_input_find_platform_key_label(g_settings.input.binds[controlno][current_index].joykey));
|
||||
rarch_convert_char_to_wchar(strw_buffer, buttons[current_index], sizeof(strw_buffer));
|
||||
m_controlslist.SetText(current_index, strw_buffer);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
bHandled = TRUE;
|
||||
return 0;
|
||||
}
|
||||
|
||||
HRESULT CRetroArchSettings::OnInit(XUIMessageInit * pInitData, BOOL& bHandled)
|
||||
{
|
||||
GetChildById(L"XuiSettingsList", &m_settingslist);
|
||||
GetChildById(L"XuiBackButton", &m_back);
|
||||
|
||||
m_settingslist.SetText(SETTING_EMU_REWIND_ENABLED, g_settings.rewind_enable ? L"Rewind: ON" : L"Rewind: OFF");
|
||||
m_settingslist.SetText(SETTING_EMU_SHOW_INFO_MSG, g_console.info_msg_enable ? L"Info messages: ON" : L"Info messages: OFF");
|
||||
m_settingslist.SetText(SETTING_EMU_MENUS, g_console.menus_hd_enable ? L"Menus: HD" : L"Menus: SD");
|
||||
m_settingslist.SetText(SETTING_GAMMA_CORRECTION_ENABLED, g_console.gamma_correction_enable ? L"Gamma correction: ON" : L"Gamma correction: OFF");
|
||||
m_settingslist.SetText(SETTING_HW_TEXTURE_FILTER, g_settings.video.smooth ? L"Hardware filtering shader #1: Linear interpolation" : L"Hardware filtering shader #1: Point filtering");
|
||||
m_settingslist.SetText(SETTING_HW_TEXTURE_FILTER_2, g_settings.video.second_pass_smooth ? L"Hardware filtering shader #2: Linear interpolation" : L"Hardware filtering shader #2: Point filtering");
|
||||
m_settingslist.SetText(SETTING_SCALE_ENABLED, g_console.fbo_enabled ? L"Custom Scaling/Dual Shaders: ON" : L"Custom Scaling/Dual Shaders: OFF");
|
||||
rarch_settings_create_menu_item_label(strw_buffer, S_LBL_SHADER, sizeof(strw_buffer));
|
||||
m_settingslist.SetText(SETTING_SHADER, strw_buffer);
|
||||
m_settingslist.SetText(SETTING_COLOR_FORMAT, g_console.color_format ? L"Color format: 32bit ARGB" : L"Color format: 16bit RGBA");
|
||||
rarch_settings_create_menu_item_label(strw_buffer, S_LBL_SHADER_2, sizeof(strw_buffer));
|
||||
m_settingslist.SetText(SETTING_SHADER_2, strw_buffer);
|
||||
rarch_settings_create_menu_item_label(strw_buffer, S_LBL_SCALE_FACTOR, sizeof(strw_buffer));
|
||||
m_settingslist.SetText(SETTING_SCALE_FACTOR, strw_buffer);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
HRESULT CRetroArchSettings::OnControlNavigate(XUIMessageControlNavigate *pControlNavigateData, BOOL& bHandled)
|
||||
{
|
||||
int current_index;
|
||||
xdk360_video_t *vid = (xdk360_video_t*)driver.video_data;
|
||||
|
||||
current_index = m_settingslist.GetCurSel();
|
||||
|
||||
switch(pControlNavigateData->nControlNavigate)
|
||||
{
|
||||
case XUI_CONTROL_NAVIGATE_LEFT:
|
||||
switch(current_index)
|
||||
{
|
||||
case SETTING_SCALE_FACTOR:
|
||||
if(vid->fbo_enabled)
|
||||
{
|
||||
if((g_settings.video.fbo_scale_x > MIN_SCALING_FACTOR))
|
||||
{
|
||||
rarch_settings_change(S_SCALE_FACTOR_DECREMENT);
|
||||
//xdk360_gfx_init_fbo(vid);
|
||||
rarch_settings_create_menu_item_label(strw_buffer, S_LBL_SCALE_FACTOR, sizeof(strw_buffer));
|
||||
m_settingslist.SetText(SETTING_SCALE_FACTOR, strw_buffer);
|
||||
}
|
||||
}
|
||||
default:
|
||||
break;
|
||||
}
|
||||
break;
|
||||
case XUI_CONTROL_NAVIGATE_RIGHT:
|
||||
switch(current_index)
|
||||
{
|
||||
case SETTING_SCALE_FACTOR:
|
||||
if(vid->fbo_enabled)
|
||||
{
|
||||
if((g_settings.video.fbo_scale_x < MAX_SCALING_FACTOR))
|
||||
{
|
||||
rarch_settings_change(S_SCALE_FACTOR_INCREMENT);
|
||||
//xdk360_gfx_init_fbo(vid);
|
||||
rarch_settings_create_menu_item_label(strw_buffer, S_LBL_SCALE_FACTOR, sizeof(strw_buffer));
|
||||
m_settingslist.SetText(SETTING_SCALE_FACTOR, strw_buffer);
|
||||
}
|
||||
}
|
||||
default:
|
||||
break;
|
||||
}
|
||||
break;
|
||||
case XUI_CONTROL_NAVIGATE_UP:
|
||||
case XUI_CONTROL_NAVIGATE_DOWN:
|
||||
break;
|
||||
}
|
||||
|
||||
bHandled = TRUE;
|
||||
|
||||
switch(pControlNavigateData->nControlNavigate)
|
||||
{
|
||||
case XUI_CONTROL_NAVIGATE_LEFT:
|
||||
case XUI_CONTROL_NAVIGATE_RIGHT:
|
||||
case XUI_CONTROL_NAVIGATE_UP:
|
||||
case XUI_CONTROL_NAVIGATE_DOWN:
|
||||
pControlNavigateData->hObjDest = pControlNavigateData->hObjSource;
|
||||
break;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
HRESULT CRetroArchQuickMenu::OnInit(XUIMessageInit * pInitData, BOOL& bHandled)
|
||||
{
|
||||
GetChildById(L"XuiQuickMenuList", &m_quickmenulist);
|
||||
GetChildById(L"XuiBackButton", &m_back);
|
||||
|
||||
rarch_settings_create_menu_item_label(strw_buffer, S_LBL_ROTATION, sizeof(strw_buffer));
|
||||
m_quickmenulist.SetText(MENU_ITEM_ORIENTATION, strw_buffer);
|
||||
|
||||
rarch_settings_create_menu_item_label(strw_buffer, S_LBL_ASPECT_RATIO, sizeof(strw_buffer));
|
||||
m_quickmenulist.SetText(MENU_ITEM_KEEP_ASPECT_RATIO, strw_buffer);
|
||||
|
||||
rarch_settings_create_menu_item_label(strw_buffer, S_LBL_LOAD_STATE_SLOT, sizeof(strw_buffer));
|
||||
m_quickmenulist.SetText(MENU_ITEM_LOAD_STATE, strw_buffer);
|
||||
|
||||
rarch_settings_create_menu_item_label(strw_buffer, S_LBL_SAVE_STATE_SLOT, sizeof(strw_buffer));
|
||||
m_quickmenulist.SetText(MENU_ITEM_SAVE_STATE, strw_buffer);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
HRESULT CRetroArchQuickMenu::OnControlNavigate(XUIMessageControlNavigate *pControlNavigateData, BOOL& bHandled)
|
||||
{
|
||||
bool aspectratio_changed = false;
|
||||
int current_index;
|
||||
xdk360_video_t *d3d9 = (xdk360_video_t*)driver.video_data;
|
||||
|
||||
current_index = m_quickmenulist.GetCurSel();
|
||||
|
||||
switch(pControlNavigateData->nControlNavigate)
|
||||
{
|
||||
case XUI_CONTROL_NAVIGATE_LEFT:
|
||||
switch(current_index)
|
||||
{
|
||||
case MENU_ITEM_LOAD_STATE:
|
||||
case MENU_ITEM_SAVE_STATE:
|
||||
rarch_state_slot_decrease();
|
||||
rarch_settings_create_menu_item_label(strw_buffer, S_LBL_LOAD_STATE_SLOT, sizeof(strw_buffer));
|
||||
m_quickmenulist.SetText(MENU_ITEM_LOAD_STATE, strw_buffer);
|
||||
rarch_settings_create_menu_item_label(strw_buffer, S_LBL_SAVE_STATE_SLOT, sizeof(strw_buffer));
|
||||
m_quickmenulist.SetText(MENU_ITEM_SAVE_STATE, strw_buffer);
|
||||
break;
|
||||
case MENU_ITEM_KEEP_ASPECT_RATIO:
|
||||
rarch_settings_change(S_ASPECT_RATIO_DECREMENT);
|
||||
aspectratio_changed = true;
|
||||
break;
|
||||
case MENU_ITEM_ORIENTATION:
|
||||
rarch_settings_change(S_ROTATION_DECREMENT);
|
||||
rarch_settings_create_menu_item_label(strw_buffer, S_LBL_ROTATION, sizeof(strw_buffer));
|
||||
m_quickmenulist.SetText(MENU_ITEM_ORIENTATION, strw_buffer);
|
||||
video_xdk360.set_rotation(driver.video_data, g_console.screen_orientation);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
break;
|
||||
case XUI_CONTROL_NAVIGATE_RIGHT:
|
||||
switch(current_index)
|
||||
{
|
||||
case MENU_ITEM_LOAD_STATE:
|
||||
case MENU_ITEM_SAVE_STATE:
|
||||
rarch_state_slot_increase();
|
||||
rarch_settings_create_menu_item_label(strw_buffer, S_LBL_LOAD_STATE_SLOT, sizeof(strw_buffer));
|
||||
m_quickmenulist.SetText(MENU_ITEM_LOAD_STATE, strw_buffer);
|
||||
rarch_settings_create_menu_item_label(strw_buffer, S_LBL_SAVE_STATE_SLOT, sizeof(strw_buffer));
|
||||
m_quickmenulist.SetText(MENU_ITEM_SAVE_STATE, strw_buffer);
|
||||
break;
|
||||
case MENU_ITEM_KEEP_ASPECT_RATIO:
|
||||
rarch_settings_change(S_ASPECT_RATIO_INCREMENT);
|
||||
aspectratio_changed = true;
|
||||
break;
|
||||
case MENU_ITEM_ORIENTATION:
|
||||
rarch_settings_change(S_ROTATION_INCREMENT);
|
||||
rarch_settings_create_menu_item_label(strw_buffer, S_LBL_ROTATION, sizeof(strw_buffer));
|
||||
m_quickmenulist.SetText(MENU_ITEM_ORIENTATION, strw_buffer);
|
||||
video_xdk360.set_rotation(driver.video_data, g_console.screen_orientation);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
break;
|
||||
case XUI_CONTROL_NAVIGATE_UP:
|
||||
case XUI_CONTROL_NAVIGATE_DOWN:
|
||||
break;
|
||||
}
|
||||
|
||||
if(aspectratio_changed)
|
||||
{
|
||||
gfx_ctx_set_aspect_ratio(d3d9, g_console.aspect_ratio_index);
|
||||
rarch_settings_create_menu_item_label(strw_buffer, S_LBL_ASPECT_RATIO, sizeof(strw_buffer));
|
||||
m_quickmenulist.SetText(MENU_ITEM_KEEP_ASPECT_RATIO, strw_buffer);
|
||||
}
|
||||
|
||||
bHandled = TRUE;
|
||||
|
||||
switch(pControlNavigateData->nControlNavigate)
|
||||
{
|
||||
case XUI_CONTROL_NAVIGATE_LEFT:
|
||||
case XUI_CONTROL_NAVIGATE_RIGHT:
|
||||
case XUI_CONTROL_NAVIGATE_UP:
|
||||
case XUI_CONTROL_NAVIGATE_DOWN:
|
||||
pControlNavigateData->hObjDest = pControlNavigateData->hObjSource;
|
||||
break;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
HRESULT CRetroArchQuickMenu::OnNotifyPress( HXUIOBJ hObjPressed, int & bHandled )
|
||||
{
|
||||
xdk360_video_t *d3d9 = (xdk360_video_t*)driver.video_data;
|
||||
int current_index;
|
||||
|
||||
if ( hObjPressed == m_quickmenulist)
|
||||
{
|
||||
current_index = m_quickmenulist.GetCurSel();
|
||||
|
||||
switch(current_index)
|
||||
{
|
||||
case MENU_ITEM_LOAD_STATE:
|
||||
if (g_console.emulator_initialized)
|
||||
{
|
||||
rarch_load_state();
|
||||
rarch_settings_change(S_RETURN_TO_GAME);
|
||||
}
|
||||
break;
|
||||
case MENU_ITEM_SAVE_STATE:
|
||||
if (g_console.emulator_initialized)
|
||||
{
|
||||
rarch_save_state();
|
||||
rarch_settings_change(S_RETURN_TO_GAME);
|
||||
}
|
||||
break;
|
||||
case MENU_ITEM_KEEP_ASPECT_RATIO:
|
||||
{
|
||||
rarch_settings_default(S_DEF_ASPECT_RATIO);
|
||||
|
||||
gfx_ctx_set_aspect_ratio(d3d9, g_console.aspect_ratio_index);
|
||||
rarch_settings_create_menu_item_label(strw_buffer, S_LBL_ASPECT_RATIO, sizeof(strw_buffer));
|
||||
m_quickmenulist.SetText(MENU_ITEM_KEEP_ASPECT_RATIO, strw_buffer);
|
||||
}
|
||||
break;
|
||||
case MENU_ITEM_OVERSCAN_AMOUNT:
|
||||
if(g_console.info_msg_enable)
|
||||
rarch_settings_msg(S_MSG_NOT_IMPLEMENTED, S_DELAY_180);
|
||||
break;
|
||||
case MENU_ITEM_ORIENTATION:
|
||||
rarch_settings_default(S_DEF_ROTATION);
|
||||
rarch_settings_create_menu_item_label(strw_buffer, S_LBL_ROTATION, sizeof(strw_buffer));
|
||||
m_quickmenulist.SetText(MENU_ITEM_ORIENTATION, strw_buffer);
|
||||
video_xdk360.set_rotation(driver.video_data, g_console.screen_orientation);
|
||||
break;
|
||||
case MENU_ITEM_RESIZE_MODE:
|
||||
g_console.input_loop = INPUT_LOOP_RESIZE_MODE;
|
||||
if (g_console.info_msg_enable)
|
||||
rarch_settings_msg(S_MSG_RESIZE_SCREEN, S_DELAY_270);
|
||||
break;
|
||||
case MENU_ITEM_FRAME_ADVANCE:
|
||||
if (g_console.emulator_initialized)
|
||||
rarch_settings_change(S_FRAME_ADVANCE);
|
||||
break;
|
||||
case MENU_ITEM_SCREENSHOT_MODE:
|
||||
if (g_console.info_msg_enable)
|
||||
rarch_settings_msg(S_MSG_NOT_IMPLEMENTED, S_DELAY_180);
|
||||
break;
|
||||
case MENU_ITEM_RESET:
|
||||
if (g_console.emulator_initialized)
|
||||
{
|
||||
rarch_settings_change(S_RETURN_TO_GAME);
|
||||
rarch_game_reset();
|
||||
}
|
||||
break;
|
||||
case MENU_ITEM_RETURN_TO_GAME:
|
||||
if (g_console.emulator_initialized)
|
||||
rarch_settings_change(S_RETURN_TO_GAME);
|
||||
break;
|
||||
case MENU_ITEM_RETURN_TO_DASHBOARD:
|
||||
rarch_settings_change(S_RETURN_TO_DASHBOARD);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
bHandled = TRUE;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
HRESULT CRetroArchMain::OnInit(XUIMessageInit * pInitData, BOOL& bHandled)
|
||||
{
|
||||
struct retro_system_info info;
|
||||
retro_get_system_info(&info);
|
||||
const char *id = info.library_name ? info.library_name : "Unknown";
|
||||
|
||||
GetChildById(L"XuiBtnRomBrowser", &m_filebrowser);
|
||||
GetChildById(L"XuiBtnSettings", &m_settings);
|
||||
GetChildById(L"XuiBtnQuickMenu", &m_quick_menu);
|
||||
GetChildById(L"XuiBtnControls", &m_controls);
|
||||
GetChildById(L"XuiBtnQuit", &m_quit);
|
||||
GetChildById(L"XuiTxtTitle", &m_title);
|
||||
GetChildById(L"XuiTxtCoreText", &m_core);
|
||||
GetChildById(L"XuiBtnLibsnesCore", &m_change_libretro_core);
|
||||
|
||||
char core_text[256];
|
||||
snprintf(core_text, sizeof(core_text), "%s (v%s)", id, info.library_version);
|
||||
|
||||
rarch_convert_char_to_wchar(strw_buffer, core_text, sizeof(strw_buffer));
|
||||
m_core.SetText(strw_buffer);
|
||||
rarch_settings_create_menu_item_label(strw_buffer, S_LBL_RARCH_VERSION, sizeof(strw_buffer));
|
||||
m_title.SetText(strw_buffer);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
HRESULT CRetroArchFileBrowser::OnNotifyPress( HXUIOBJ hObjPressed, BOOL& bHandled )
|
||||
{
|
||||
char path[PATH_MAX];
|
||||
|
||||
if(hObjPressed == m_romlist)
|
||||
{
|
||||
int index = m_romlist.GetCurSel();
|
||||
if(browser.cur[index].d_type != FILE_ATTRIBUTE_DIRECTORY)
|
||||
{
|
||||
struct retro_system_info info;
|
||||
retro_get_system_info(&info);
|
||||
bool block_zip_extract = info.block_extract;
|
||||
|
||||
const char * strbuffer = rarch_convert_wchar_to_const_char((const wchar_t*)m_romlist.GetText(index));
|
||||
|
||||
if((strstr(strbuffer, ".zip") || strstr(strbuffer, ".ZIP")) && !block_zip_extract)
|
||||
{
|
||||
char path_tmp[1024];
|
||||
snprintf(path_tmp, sizeof(path_tmp), "%s\\%s", FILEBROWSER_GET_CURRENT_DIRECTORY_NAME(browser), strbuffer);
|
||||
rarch_extract_zipfile(path_tmp);
|
||||
}
|
||||
else
|
||||
{
|
||||
memset(g_console.rom_path, 0, sizeof(g_console.rom_path));
|
||||
snprintf(g_console.rom_path, sizeof(g_console.rom_path), "%s\\%s", FILEBROWSER_GET_CURRENT_DIRECTORY_NAME(browser), strbuffer);
|
||||
rarch_settings_change(S_START_RARCH);
|
||||
}
|
||||
}
|
||||
else if(browser.cur[index].d_type == FILE_ATTRIBUTE_DIRECTORY)
|
||||
{
|
||||
|
||||
const char * strbuffer = rarch_convert_wchar_to_const_char((const wchar_t *)m_romlist.GetText(index));
|
||||
snprintf(path, sizeof(path), "%s\\%s", FILEBROWSER_GET_CURRENT_DIRECTORY_NAME(browser), strbuffer);
|
||||
filebrowser_fetch_directory_entries(path, &browser, &m_romlist, &m_rompathtitle);
|
||||
}
|
||||
}
|
||||
else if (hObjPressed == m_dir_game)
|
||||
{
|
||||
filebrowser_new(&browser, g_console.default_rom_startup_dir, rarch_console_get_rom_ext());
|
||||
filebrowser_fetch_directory_entries(g_console.default_rom_startup_dir, &browser, &m_romlist, &m_rompathtitle);
|
||||
}
|
||||
else if (hObjPressed == m_dir_cache)
|
||||
{
|
||||
filebrowser_new(&browser, "cache:", rarch_console_get_rom_ext());
|
||||
filebrowser_fetch_directory_entries("cache:", &browser, &m_romlist, &m_rompathtitle);
|
||||
if (g_console.info_msg_enable)
|
||||
rarch_settings_msg(S_MSG_CACHE_PARTITION, S_DELAY_180);
|
||||
}
|
||||
|
||||
bHandled = TRUE;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
HRESULT CRetroArchShaderBrowser::OnNotifyPress( HXUIOBJ hObjPressed, BOOL& bHandled )
|
||||
{
|
||||
char path[PATH_MAX];
|
||||
|
||||
if(hObjPressed == m_shaderlist)
|
||||
{
|
||||
int index = m_shaderlist.GetCurSel();
|
||||
if(tmp_browser.cur[index].d_type != FILE_ATTRIBUTE_DIRECTORY)
|
||||
{
|
||||
const char * strbuffer = rarch_convert_wchar_to_const_char((const wchar_t *)m_shaderlist.GetText(index));
|
||||
|
||||
switch(set_shader)
|
||||
{
|
||||
case 1:
|
||||
snprintf(g_settings.video.cg_shader_path, sizeof(g_settings.video.cg_shader_path), "%s\\%s", FILEBROWSER_GET_CURRENT_DIRECTORY_NAME(tmp_browser), strbuffer);
|
||||
hlsl_load_shader(set_shader, g_settings.video.cg_shader_path);
|
||||
break;
|
||||
case 2:
|
||||
snprintf (g_settings.video.second_pass_shader, sizeof(g_settings.video.second_pass_shader), "%s\\%s", FILEBROWSER_GET_CURRENT_DIRECTORY_NAME(tmp_browser), strbuffer);
|
||||
hlsl_load_shader(set_shader, g_settings.video.second_pass_shader);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
if (g_console.info_msg_enable)
|
||||
rarch_settings_msg(S_MSG_SHADER_LOADING_SUCCEEDED, S_DELAY_180);
|
||||
}
|
||||
else if(tmp_browser.cur[index].d_type == FILE_ATTRIBUTE_DIRECTORY)
|
||||
{
|
||||
const char * strbuffer = rarch_convert_wchar_to_const_char((const wchar_t *)m_shaderlist.GetText(index));
|
||||
snprintf(path, sizeof(path), "%s\\%s", FILEBROWSER_GET_CURRENT_DIRECTORY_NAME(tmp_browser), strbuffer);
|
||||
filebrowser_fetch_directory_entries(path, &tmp_browser, &m_shaderlist, &m_shaderpathtitle);
|
||||
}
|
||||
}
|
||||
|
||||
bHandled = TRUE;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
HRESULT CRetroArchCoreBrowser::OnNotifyPress( HXUIOBJ hObjPressed, BOOL& bHandled )
|
||||
{
|
||||
char path[PATH_MAX];
|
||||
|
||||
if(hObjPressed == m_romlist)
|
||||
{
|
||||
int index = m_romlist.GetCurSel();
|
||||
if(tmp_browser.cur[index].d_type != FILE_ATTRIBUTE_DIRECTORY)
|
||||
{
|
||||
const char * strbuffer = rarch_convert_wchar_to_const_char((const wchar_t *)m_romlist.GetText(index));
|
||||
snprintf(g_console.launch_app_on_exit, sizeof(g_console.launch_app_on_exit), "%s\\%s", FILEBROWSER_GET_CURRENT_DIRECTORY_NAME(tmp_browser), strbuffer);
|
||||
rarch_settings_change(S_RETURN_TO_LAUNCHER);
|
||||
}
|
||||
else if(tmp_browser.cur[index].d_type == FILE_ATTRIBUTE_DIRECTORY)
|
||||
{
|
||||
const char * strbuffer = rarch_convert_wchar_to_const_char((const wchar_t *)m_romlist.GetText(index));
|
||||
snprintf(path, sizeof(path), "%s%s\\", FILEBROWSER_GET_CURRENT_DIRECTORY_NAME(tmp_browser), strbuffer);
|
||||
filebrowser_fetch_directory_entries(path, &tmp_browser, &m_romlist, &m_rompathtitle);
|
||||
}
|
||||
}
|
||||
|
||||
bHandled = TRUE;
|
||||
return 0;
|
||||
}
|
||||
|
||||
HRESULT CRetroArchSettings::OnNotifyPress( HXUIOBJ hObjPressed, int & bHandled )
|
||||
{
|
||||
int current_index;
|
||||
HRESULT hr;
|
||||
|
||||
if ( hObjPressed == m_settingslist)
|
||||
{
|
||||
current_index = m_settingslist.GetCurSel();
|
||||
|
||||
switch(current_index)
|
||||
{
|
||||
case SETTING_EMU_REWIND_ENABLED:
|
||||
rarch_settings_change(S_REWIND);
|
||||
m_settingslist.SetText(SETTING_EMU_REWIND_ENABLED, g_settings.rewind_enable ? L"Rewind: ON" : L"Rewind: OFF");
|
||||
|
||||
if (g_console.info_msg_enable)
|
||||
rarch_settings_msg(S_MSG_RESTART_RARCH, S_DELAY_180);
|
||||
break;
|
||||
case SETTING_EMU_SHOW_INFO_MSG:
|
||||
g_console.info_msg_enable = !g_console.info_msg_enable;
|
||||
m_settingslist.SetText(SETTING_EMU_SHOW_INFO_MSG, g_console.info_msg_enable ? L"Info messages: ON" : L"Info messages: OFF");
|
||||
break;
|
||||
case SETTING_EMU_MENUS:
|
||||
g_console.menus_hd_enable = !g_console.menus_hd_enable;
|
||||
m_settingslist.SetText(SETTING_EMU_MENUS, g_console.menus_hd_enable ? L"Menus: HD" : L"Menus: SD");
|
||||
break;
|
||||
case SETTING_GAMMA_CORRECTION_ENABLED:
|
||||
g_console.gamma_correction_enable = !g_console.gamma_correction_enable;
|
||||
m_settingslist.SetText(SETTING_GAMMA_CORRECTION_ENABLED, g_console.gamma_correction_enable ? L"Gamma correction: ON" : L"Gamma correction: OFF");
|
||||
if(g_console.info_msg_enable)
|
||||
rarch_settings_msg(S_MSG_RESTART_RARCH, S_DELAY_180);
|
||||
break;
|
||||
case SETTING_COLOR_FORMAT:
|
||||
g_console.color_format = !g_console.color_format;
|
||||
m_settingslist.SetText(SETTING_COLOR_FORMAT, g_console.color_format ? L"Color format: 32bit ARGB" : L"Color format: 16bit RGBA");
|
||||
if(g_console.info_msg_enable)
|
||||
rarch_settings_msg(S_MSG_RESTART_RARCH, S_DELAY_180);
|
||||
break;
|
||||
case SETTING_SHADER:
|
||||
set_shader = 1;
|
||||
hr = XuiSceneCreate(g_console.menus_hd_enable ? L"file://game:/media/hd/" : L"file://game:/media/sd/", L"rarch_shader_browser.xur", NULL, &app.hShaderBrowser);
|
||||
|
||||
if (hr < 0)
|
||||
{
|
||||
RARCH_ERR("Failed to load scene.\n");
|
||||
}
|
||||
hCur = app.hShaderBrowser;
|
||||
|
||||
if (g_console.info_msg_enable)
|
||||
rarch_settings_msg(S_MSG_SELECT_SHADER, S_DELAY_180);
|
||||
NavigateForward(app.hShaderBrowser);
|
||||
break;
|
||||
case SETTING_SHADER_2:
|
||||
set_shader = 2;
|
||||
hr = XuiSceneCreate(g_console.menus_hd_enable ? L"file://game:/media/hd/" : L"file://game:/media/sd/", L"rarch_shader_browser.xur", NULL, &app.hShaderBrowser);
|
||||
if (hr < 0)
|
||||
{
|
||||
RARCH_ERR("Failed to load scene.\n");
|
||||
}
|
||||
hCur = app.hShaderBrowser;
|
||||
if (g_console.info_msg_enable)
|
||||
rarch_settings_msg(S_MSG_SELECT_SHADER, S_DELAY_180);
|
||||
NavigateForward(app.hShaderBrowser);
|
||||
break;
|
||||
case SETTING_HW_TEXTURE_FILTER:
|
||||
g_settings.video.smooth = !g_settings.video.smooth;
|
||||
m_settingslist.SetText(SETTING_HW_TEXTURE_FILTER, g_settings.video.smooth ? L"Hardware filtering shader #1: Linear interpolation" : L"Hardware filtering shader #1: Point filtering");
|
||||
break;
|
||||
case SETTING_HW_TEXTURE_FILTER_2:
|
||||
g_settings.video.second_pass_smooth = !g_settings.video.second_pass_smooth;
|
||||
m_settingslist.SetText(SETTING_HW_TEXTURE_FILTER_2, g_settings.video.second_pass_smooth ? L"Hardware filtering shader #2: Linear interpolation" : L"Hardware filtering shader #2: Point filtering");
|
||||
break;
|
||||
case SETTING_SCALE_ENABLED:
|
||||
g_console.fbo_enabled = !g_console.fbo_enabled;
|
||||
m_settingslist.SetText(SETTING_SCALE_ENABLED, g_console.fbo_enabled ? L"Custom Scaling/Dual Shaders: ON" : L"Custom Scaling/Dual Shaders: OFF");
|
||||
gfx_ctx_set_fbo(g_console.fbo_enabled);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
bHandled = TRUE;
|
||||
return 0;
|
||||
}
|
||||
|
||||
HRESULT CRetroArchMain::OnNotifyPress( HXUIOBJ hObjPressed, int & bHandled )
|
||||
{
|
||||
xdk360_video_t *vid = (xdk360_video_t*)driver.video_data;
|
||||
|
||||
bool hdmenus_allowed = g_console.menus_hd_enable;
|
||||
|
||||
HRESULT hr;
|
||||
|
||||
if ( hObjPressed == m_filebrowser )
|
||||
{
|
||||
hr = XuiSceneCreate(hdmenus_allowed ? L"file://game:/media/hd/" : L"file://game:/media/sd/", L"rarch_filebrowser.xur", NULL, &app.hFileBrowser);
|
||||
|
||||
if (hr < 0)
|
||||
RARCH_ERR("Failed to load scene.\n");
|
||||
|
||||
hCur = app.hFileBrowser;
|
||||
NavigateForward(app.hFileBrowser);
|
||||
}
|
||||
else if ( hObjPressed == m_quick_menu)
|
||||
{
|
||||
hr = XuiSceneCreate(hdmenus_allowed ? L"file://game:/media/hd/" : L"file://game:/media/sd/", L"rarch_quickmenu.xur", NULL, &app.hQuickMenu);
|
||||
|
||||
if (hr < 0)
|
||||
RARCH_ERR("Failed to load scene.\n");
|
||||
|
||||
hCur = app.hQuickMenu;
|
||||
NavigateForward(app.hQuickMenu);
|
||||
}
|
||||
else if ( hObjPressed == m_controls)
|
||||
{
|
||||
hr = XuiSceneCreate(hdmenus_allowed ? L"file://game:/media/hd/" : L"file://game:/media/sd/", L"rarch_controls.xur", NULL, &app.hControlsMenu);
|
||||
|
||||
if (hr < 0)
|
||||
RARCH_ERR("Failed to load scene.\n");
|
||||
|
||||
hCur = app.hControlsMenu;
|
||||
if (g_console.info_msg_enable)
|
||||
rarch_settings_msg(S_MSG_CHANGE_CONTROLS, S_DELAY_180);
|
||||
NavigateForward(app.hControlsMenu);
|
||||
}
|
||||
else if ( hObjPressed == m_change_libretro_core )
|
||||
{
|
||||
hr = XuiSceneCreate(hdmenus_allowed ? L"file://game:/media/hd/" : L"file://game:/media/sd/", L"rarch_libretrocore_browser.xur", NULL, &app.hCoreBrowser);
|
||||
|
||||
if (hr < 0)
|
||||
{
|
||||
RARCH_ERR("Failed to load scene.\n");
|
||||
}
|
||||
hCur = app.hCoreBrowser;
|
||||
|
||||
if (g_console.info_msg_enable)
|
||||
rarch_settings_msg(S_MSG_SELECT_LIBRETRO_CORE, S_DELAY_180);
|
||||
NavigateForward(app.hCoreBrowser);
|
||||
}
|
||||
else if ( hObjPressed == m_settings )
|
||||
{
|
||||
hr = XuiSceneCreate(hdmenus_allowed ? L"file://game:/media/hd/" : L"file://game:/media/sd/", L"rarch_settings.xur", NULL, &app.hRetroArchSettings);
|
||||
|
||||
if (hr < 0)
|
||||
RARCH_ERR("Failed to load scene.\n");
|
||||
|
||||
hCur = app.hRetroArchSettings;
|
||||
NavigateForward(app.hRetroArchSettings);
|
||||
}
|
||||
else if ( hObjPressed == m_quit )
|
||||
rarch_settings_change(S_RETURN_TO_DASHBOARD);
|
||||
|
||||
bHandled = TRUE;
|
||||
return 0;
|
||||
}
|
||||
|
||||
int menu_init (void)
|
||||
{
|
||||
HRESULT hr;
|
||||
|
||||
xdk360_video_t *vid = (xdk360_video_t*)driver.video_data;
|
||||
|
||||
hr = app.InitShared(vid->d3d_render_device, &vid->d3dpp, XuiPNGTextureLoader);
|
||||
|
||||
if (hr < 0)
|
||||
{
|
||||
RARCH_ERR("Failed initializing XUI application.\n");
|
||||
return 1;
|
||||
}
|
||||
|
||||
/* Register font */
|
||||
hr = app.RegisterDefaultTypeface(L"Arial Unicode MS", L"file://game:/media/rarch.ttf" );
|
||||
if (hr < 0)
|
||||
{
|
||||
RARCH_ERR("Failed to register default typeface.\n");
|
||||
return 1;
|
||||
}
|
||||
|
||||
hr = app.LoadSkin( L"file://game:/media/rarch_scene_skin.xur");
|
||||
if (hr < 0)
|
||||
{
|
||||
RARCH_ERR("Failed to load skin.\n");
|
||||
return 1;
|
||||
}
|
||||
|
||||
hr = XuiSceneCreate(L"file://game:/media/sd/", L"rarch_main.xur", NULL, &app.hMainScene);
|
||||
if (hr < 0)
|
||||
{
|
||||
RARCH_ERR("Failed to create scene 'rarch_main.xur'.\n");
|
||||
return 1;
|
||||
}
|
||||
|
||||
hCur = app.hMainScene;
|
||||
XuiSceneNavigateFirst(app.GetRootObj(), app.hMainScene, XUSER_INDEX_FOCUS);
|
||||
|
||||
filebrowser_new(&browser, g_console.default_rom_startup_dir, rarch_console_get_rom_ext());
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
void menu_deinit (void)
|
||||
{
|
||||
app.Uninit();
|
||||
}
|
||||
|
||||
void menu_loop(void)
|
||||
{
|
||||
HRESULT hr;
|
||||
xdk360_video_t *d3d9 = (xdk360_video_t*)driver.video_data;
|
||||
|
||||
g_console.menu_enable = true;
|
||||
|
||||
d3d9->block_swap = true;
|
||||
|
||||
g_console.input_loop = INPUT_LOOP_MENU;
|
||||
|
||||
do
|
||||
{
|
||||
if(g_console.emulator_initialized)
|
||||
{
|
||||
rarch_render_cached_frame();
|
||||
}
|
||||
else
|
||||
{
|
||||
d3d9->d3d_render_device->Clear(0, NULL, D3DCLEAR_TARGET, D3DCOLOR_ARGB(0, 0, 0, 0), 1.0f, 0);
|
||||
d3d9->frame_count++;
|
||||
}
|
||||
|
||||
XINPUT_STATE state;
|
||||
XInputGetState(0, &state);
|
||||
|
||||
g_console.menu_enable = !((state.Gamepad.wButtons & XINPUT_GAMEPAD_LEFT_THUMB)
|
||||
&& (state.Gamepad.wButtons & XINPUT_GAMEPAD_RIGHT_THUMB) && (g_console.emulator_initialized)
|
||||
&& IS_TIMER_EXPIRED(d3d9));
|
||||
|
||||
g_console.mode_switch = g_console.menu_enable ? MODE_MENU : MODE_EMULATION;
|
||||
|
||||
switch(g_console.input_loop)
|
||||
{
|
||||
case INPUT_LOOP_MENU:
|
||||
app.RunFrame(); /* Update XUI */
|
||||
if(state.Gamepad.wButtons & XINPUT_GAMEPAD_B && hCur != app.hMainScene)
|
||||
XuiSceneNavigateBack(hCur, app.hMainScene, XUSER_INDEX_ANY);
|
||||
break;
|
||||
case INPUT_LOOP_RESIZE_MODE:
|
||||
xdk360_input_loop();
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
hr = app.Render(); /* Render XUI */
|
||||
hr = XuiTimersRun(); /* Update XUI timers */
|
||||
|
||||
if(g_console.mode_switch == MODE_EMULATION && !g_console.frame_advance_enable)
|
||||
{
|
||||
SET_TIMER_EXPIRATION(d3d9, 30);
|
||||
}
|
||||
|
||||
const char *message = msg_queue_pull(g_extern.msg_queue);
|
||||
|
||||
if (message)
|
||||
{
|
||||
if(IS_TIMER_EXPIRED(d3d9))
|
||||
{
|
||||
xdk360_console_format(message);
|
||||
SET_TIMER_EXPIRATION(d3d9, 30);
|
||||
}
|
||||
xdk360_console_draw();
|
||||
}
|
||||
|
||||
gfx_ctx_swap_buffers();
|
||||
}while(g_console.menu_enable);
|
||||
|
||||
d3d9->block_swap = false;
|
||||
|
||||
g_console.ingame_menu_enable = false;
|
||||
}
|
||||
+223
@@ -0,0 +1,223 @@
|
||||
/* RetroArch - A frontend for libretro.
|
||||
* Copyright (C) 2010-2012 - Hans-Kristian Arntzen
|
||||
* Copyright (C) 2011-2012 - Daniel De Matteis
|
||||
*
|
||||
* RetroArch is free software: you can redistribute it and/or modify it under the terms
|
||||
* of the GNU General Public License as published by the Free Software Found-
|
||||
* ation, either version 3 of the License, or (at your option) any later version.
|
||||
*
|
||||
* RetroArch is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
|
||||
* without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
|
||||
* PURPOSE. See the GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along with RetroArch.
|
||||
* If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifndef _MENU_XUI_H_
|
||||
#define _MENU_XUI_H_
|
||||
|
||||
#include <xui.h>
|
||||
#include <xuiapp.h>
|
||||
|
||||
enum
|
||||
{
|
||||
SETTING_EMU_REWIND_ENABLED = 0,
|
||||
SETTING_EMU_SHOW_INFO_MSG,
|
||||
SETTING_EMU_MENUS,
|
||||
SETTING_GAMMA_CORRECTION_ENABLED,
|
||||
SETTING_COLOR_FORMAT,
|
||||
SETTING_SHADER,
|
||||
SETTING_SHADER_2,
|
||||
SETTING_HW_TEXTURE_FILTER,
|
||||
SETTING_HW_TEXTURE_FILTER_2,
|
||||
SETTING_SCALE_ENABLED,
|
||||
SETTING_SCALE_FACTOR
|
||||
};
|
||||
|
||||
enum
|
||||
{
|
||||
SETTING_CONTROLS_RETRO_DEVICE_ID_JOYPAD_B = 0,
|
||||
SETTING_CONTROLS_RETRO_DEVICE_ID_JOYPAD_Y,
|
||||
SETTING_CONTROLS_RETRO_DEVICE_ID_JOYPAD_SELECT,
|
||||
SETTING_CONTROLS_RETRO_DEVICE_ID_JOYPAD_START,
|
||||
SETTING_CONTROLS_RETRO_DEVICE_ID_JOYPAD_UP,
|
||||
SETTING_CONTROLS_RETRO_DEVICE_ID_JOYPAD_DOWN,
|
||||
SETTING_CONTROLS_RETRO_DEVICE_ID_JOYPAD_LEFT,
|
||||
SETTING_CONTROLS_RETRO_DEVICE_ID_JOYPAD_RIGHT,
|
||||
SETTING_CONTROLS_RETRO_DEVICE_ID_JOYPAD_A,
|
||||
SETTING_CONTROLS_RETRO_DEVICE_ID_JOYPAD_X,
|
||||
SETTING_CONTROLS_RETRO_DEVICE_ID_JOYPAD_L,
|
||||
SETTING_CONTROLS_RETRO_DEVICE_ID_JOYPAD_R,
|
||||
SETTING_CONTROLS_RETRO_DEVICE_ID_JOYPAD_L2,
|
||||
SETTING_CONTROLS_RETRO_DEVICE_ID_JOYPAD_R2,
|
||||
SETTING_CONTROLS_RETRO_DEVICE_ID_JOYPAD_L3,
|
||||
SETTING_CONTROLS_RETRO_DEVICE_ID_JOYPAD_R3,
|
||||
SETTING_CONTROLS_DEFAULT_ALL
|
||||
};
|
||||
|
||||
enum
|
||||
{
|
||||
INPUT_LOOP_MENU,
|
||||
INPUT_LOOP_RESIZE_MODE
|
||||
};
|
||||
|
||||
class CRetroArch : public CXuiModule
|
||||
{
|
||||
public:
|
||||
HXUIOBJ hMainScene;
|
||||
HXUIOBJ hControlsMenu;
|
||||
HXUIOBJ hFileBrowser;
|
||||
HXUIOBJ hCoreBrowser;
|
||||
HXUIOBJ hShaderBrowser;
|
||||
HXUIOBJ hQuickMenu;
|
||||
HXUIOBJ hRetroArchSettings;
|
||||
protected:
|
||||
virtual HRESULT RegisterXuiClasses();
|
||||
virtual HRESULT UnregisterXuiClasses();
|
||||
};
|
||||
|
||||
class CRetroArchMain: public CXuiSceneImpl
|
||||
{
|
||||
protected:
|
||||
CXuiControl m_filebrowser;
|
||||
CXuiControl m_quick_menu;
|
||||
CXuiControl m_controls;
|
||||
CXuiControl m_settings;
|
||||
CXuiControl m_change_libretro_core;
|
||||
CXuiControl m_quit;
|
||||
CXuiTextElement m_title;
|
||||
CXuiTextElement m_core;
|
||||
public:
|
||||
HRESULT OnInit( XUIMessageInit* pInitData, int & bHandled );
|
||||
HRESULT OnNotifyPress( HXUIOBJ hObjPressed, int & bHandled );
|
||||
|
||||
XUI_BEGIN_MSG_MAP()
|
||||
XUI_ON_XM_INIT( OnInit)
|
||||
XUI_ON_XM_NOTIFY_PRESS( OnNotifyPress )
|
||||
XUI_END_MSG_MAP();
|
||||
|
||||
XUI_IMPLEMENT_CLASS(CRetroArchMain, L"RetroArchMain", XUI_CLASS_SCENE)
|
||||
};
|
||||
|
||||
class CRetroArchFileBrowser: public CXuiSceneImpl
|
||||
{
|
||||
protected:
|
||||
CXuiList m_romlist;
|
||||
CXuiControl m_back;
|
||||
CXuiControl m_dir_game;
|
||||
CXuiControl m_dir_cache;
|
||||
CXuiTextElement m_rompathtitle;
|
||||
public:
|
||||
HRESULT OnInit( XUIMessageInit* pInitData, int & bHandled );
|
||||
HRESULT OnNotifyPress( HXUIOBJ hObjPressed, int & bHandled );
|
||||
|
||||
XUI_BEGIN_MSG_MAP()
|
||||
XUI_ON_XM_INIT( OnInit)
|
||||
XUI_ON_XM_NOTIFY_PRESS( OnNotifyPress )
|
||||
XUI_END_MSG_MAP();
|
||||
|
||||
XUI_IMPLEMENT_CLASS(CRetroArchFileBrowser, L"RetroArchFileBrowser", XUI_CLASS_SCENE)
|
||||
};
|
||||
|
||||
class CRetroArchCoreBrowser: public CXuiSceneImpl
|
||||
{
|
||||
protected:
|
||||
CXuiList m_romlist;
|
||||
CXuiControl m_back;
|
||||
CXuiTextElement m_rompathtitle;
|
||||
public:
|
||||
HRESULT OnInit( XUIMessageInit* pInitData, int & bHandled );
|
||||
HRESULT OnNotifyPress( HXUIOBJ hObjPressed, int & bHandled );
|
||||
|
||||
XUI_BEGIN_MSG_MAP()
|
||||
XUI_ON_XM_INIT( OnInit)
|
||||
XUI_ON_XM_NOTIFY_PRESS( OnNotifyPress )
|
||||
XUI_END_MSG_MAP();
|
||||
|
||||
XUI_IMPLEMENT_CLASS(CRetroArchCoreBrowser, L"RetroArchCoreBrowser", XUI_CLASS_SCENE)
|
||||
};
|
||||
|
||||
class CRetroArchShaderBrowser: public CXuiSceneImpl
|
||||
{
|
||||
protected:
|
||||
CXuiList m_shaderlist;
|
||||
CXuiControl m_back;
|
||||
CXuiTextElement m_shaderpathtitle;
|
||||
public:
|
||||
HRESULT OnInit( XUIMessageInit* pInitData, int & bHandled );
|
||||
HRESULT OnNotifyPress( HXUIOBJ hObjPressed, int & bHandled );
|
||||
|
||||
XUI_BEGIN_MSG_MAP()
|
||||
XUI_ON_XM_INIT( OnInit)
|
||||
XUI_ON_XM_NOTIFY_PRESS( OnNotifyPress )
|
||||
XUI_END_MSG_MAP();
|
||||
|
||||
XUI_IMPLEMENT_CLASS(CRetroArchShaderBrowser, L"RetroArchShaderBrowser", XUI_CLASS_SCENE)
|
||||
};
|
||||
|
||||
class CRetroArchQuickMenu: public CXuiSceneImpl
|
||||
{
|
||||
protected:
|
||||
CXuiList m_quickmenulist;
|
||||
CXuiControl m_back;
|
||||
public:
|
||||
HRESULT OnInit( XUIMessageInit* pInitData, int & bHandled );
|
||||
HRESULT OnNotifyPress( HXUIOBJ hObjPressed, int & bHandled );
|
||||
HRESULT OnControlNavigate(XUIMessageControlNavigate *pControlNavigateData, BOOL& bHandled);
|
||||
|
||||
XUI_BEGIN_MSG_MAP()
|
||||
XUI_ON_XM_INIT( OnInit)
|
||||
XUI_ON_XM_CONTROL_NAVIGATE( OnControlNavigate )
|
||||
XUI_ON_XM_NOTIFY_PRESS( OnNotifyPress )
|
||||
XUI_END_MSG_MAP();
|
||||
|
||||
XUI_IMPLEMENT_CLASS(CRetroArchQuickMenu, L"RetroArchQuickMenu", XUI_CLASS_SCENE)
|
||||
};
|
||||
|
||||
class CRetroArchSettings: public CXuiSceneImpl
|
||||
{
|
||||
protected:
|
||||
CXuiList m_settingslist;
|
||||
CXuiControl m_back;
|
||||
public:
|
||||
HRESULT OnInit( XUIMessageInit* pInitData, int & bHandled );
|
||||
HRESULT OnNotifyPress( HXUIOBJ hObjPressed, int & bHandled );
|
||||
HRESULT OnControlNavigate(XUIMessageControlNavigate *pControlNavigateData, BOOL& bHandled);
|
||||
|
||||
XUI_BEGIN_MSG_MAP()
|
||||
XUI_ON_XM_INIT( OnInit)
|
||||
XUI_ON_XM_CONTROL_NAVIGATE( OnControlNavigate )
|
||||
XUI_ON_XM_NOTIFY_PRESS( OnNotifyPress )
|
||||
XUI_END_MSG_MAP();
|
||||
|
||||
XUI_IMPLEMENT_CLASS(CRetroArchSettings, L"RetroArchSettings", XUI_CLASS_SCENE)
|
||||
};
|
||||
|
||||
class CRetroArchControls: public CXuiSceneImpl
|
||||
{
|
||||
protected:
|
||||
CXuiList m_controlslist;
|
||||
CXuiControl m_back;
|
||||
CXuiSlider m_controlnoslider;
|
||||
public:
|
||||
HRESULT OnInit( XUIMessageInit* pInitData, int & bHandled );
|
||||
HRESULT OnNotifyPress( HXUIOBJ hObjPressed, int & bHandled );
|
||||
HRESULT OnControlNavigate(XUIMessageControlNavigate *pControlNavigateData, BOOL& bHandled);
|
||||
|
||||
XUI_BEGIN_MSG_MAP()
|
||||
XUI_ON_XM_INIT( OnInit)
|
||||
XUI_ON_XM_CONTROL_NAVIGATE( OnControlNavigate )
|
||||
XUI_ON_XM_NOTIFY_PRESS( OnNotifyPress )
|
||||
XUI_END_MSG_MAP();
|
||||
|
||||
XUI_IMPLEMENT_CLASS(CRetroArchControls, L"RetroArchControls", XUI_CLASS_SCENE)
|
||||
};
|
||||
|
||||
int menu_init (void);
|
||||
void menu_deinit (void);
|
||||
void menu_loop (void);
|
||||
|
||||
extern CRetroArch app;
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,767 @@
|
||||
#if !defined( _XOBJBASE_H_ )
|
||||
#define _XOBJBASE_H_
|
||||
|
||||
#include <sal.h>
|
||||
|
||||
#if _MSC_VER > 1000
|
||||
#pragma once
|
||||
#endif
|
||||
|
||||
#define __RPC_FAR
|
||||
|
||||
typedef unsigned char byte;
|
||||
typedef unsigned char boolean;
|
||||
|
||||
typedef double DOUBLE;
|
||||
|
||||
#ifdef CONST_VTABLE
|
||||
#define CONST_VTBL const
|
||||
#else
|
||||
#define CONST_VTBL
|
||||
#endif
|
||||
|
||||
/****************************************************************************
|
||||
* Special things for VC5 Com support
|
||||
****************************************************************************/
|
||||
|
||||
#ifndef DECLSPEC_SELECTANY
|
||||
#if (_MSC_VER >= 1100)
|
||||
#define DECLSPEC_SELECTANY __declspec(selectany)
|
||||
#else
|
||||
#define DECLSPEC_SELECTANY
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#ifndef DECLSPEC_NOVTABLE
|
||||
#define DECLSPEC_NOVTABLE
|
||||
#endif
|
||||
|
||||
#ifndef DECLSPEC_UUID
|
||||
#define DECLSPEC_UUID(x)
|
||||
#endif
|
||||
|
||||
#define MIDL_INTERFACE(x) struct DECLSPEC_UUID(x) DECLSPEC_NOVTABLE
|
||||
|
||||
#if _MSC_VER >= 1100
|
||||
#define EXTERN_GUID(itf,l1,s1,s2,c1,c2,c3,c4,c5,c6,c7,c8) \
|
||||
EXTERN_C const IID DECLSPEC_SELECTANY itf = {l1,s1,s2,{c1,c2,c3,c4,c5,c6,c7,c8}}
|
||||
#else
|
||||
#define EXTERN_GUID(itf,l1,s1,s2,c1,c2,c3,c4,c5,c6,c7,c8) EXTERN_C const IID itf
|
||||
#endif
|
||||
|
||||
#include <pshpack8.h>
|
||||
|
||||
#define WINOLEAPI EXTERN_C DECLSPEC_IMPORT HRESULT STDAPICALLTYPE
|
||||
#define WINOLEAPI_(type) EXTERN_C DECLSPEC_IMPORT type STDAPICALLTYPE
|
||||
|
||||
/****** Interface Declaration ***********************************************/
|
||||
|
||||
/*
|
||||
* These are macros for declaring interfaces. They exist so that
|
||||
* a single definition of the interface is simulataneously a proper
|
||||
* declaration of the interface structures (C++ abstract classes)
|
||||
* for both C and C++.
|
||||
*
|
||||
* DECLARE_INTERFACE(iface) is used to declare an interface that does
|
||||
* not derive from a base interface.
|
||||
* DECLARE_INTERFACE_(iface, baseiface) is used to declare an interface
|
||||
* that does derive from a base interface.
|
||||
*
|
||||
* By default if the source file has a .c extension the C version of
|
||||
* the interface declaratations will be expanded; if it has a .cpp
|
||||
* extension the C++ version will be expanded. if you want to force
|
||||
* the C version expansion even though the source file has a .cpp
|
||||
* extension, then define the macro "CINTERFACE".
|
||||
* eg. cl -DCINTERFACE file.cpp
|
||||
*
|
||||
*
|
||||
* Example C expansion:
|
||||
*
|
||||
* typedef struct IClassFactory
|
||||
* {
|
||||
* const struct IClassFactoryVtbl FAR* lpVtbl;
|
||||
* } IClassFactory;
|
||||
*
|
||||
* typedef struct IClassFactoryVtbl IClassFactoryVtbl;
|
||||
*
|
||||
* struct IClassFactoryVtbl
|
||||
* {
|
||||
* HRESULT (STDMETHODCALLTYPE * QueryInterface) (
|
||||
* IClassFactory FAR* This,
|
||||
* IID FAR* riid,
|
||||
* LPVOID FAR* ppvObj) ;
|
||||
* ULONG (STDMETHODCALLTYPE * AddRef) (IClassFactory FAR* This) ;
|
||||
* ULONG (STDMETHODCALLTYPE * Release) (IClassFactory FAR* This) ;
|
||||
* HRESULT (STDMETHODCALLTYPE * CreateInstance) (
|
||||
* IClassFactory FAR* This,
|
||||
* LPUNKNOWN pUnkOuter,
|
||||
* IID FAR* riid,
|
||||
* LPVOID FAR* ppvObject);
|
||||
* HRESULT (STDMETHODCALLTYPE * LockServer) (
|
||||
* IClassFactory FAR* This,
|
||||
* BOOL fLock);
|
||||
* };
|
||||
*/
|
||||
|
||||
#define interface struct
|
||||
|
||||
#define STDMETHOD(method) HRESULT (STDMETHODCALLTYPE * method)
|
||||
#define STDMETHOD_(type,method) type (STDMETHODCALLTYPE * method)
|
||||
#define STDMETHODV(method) HRESULT (STDMETHODVCALLTYPE * method)
|
||||
#define STDMETHODV_(type,method) type (STDMETHODVCALLTYPE * method)
|
||||
|
||||
#if !defined(BEGIN_INTERFACE)
|
||||
#define BEGIN_INTERFACE
|
||||
#define END_INTERFACE
|
||||
#endif
|
||||
|
||||
|
||||
#define PURE
|
||||
#define THIS_ INTERFACE FAR* This,
|
||||
#define THIS INTERFACE FAR* This
|
||||
#ifdef CONST_VTABLE
|
||||
#undef CONST_VTBL
|
||||
#define CONST_VTBL const
|
||||
#define DECLARE_INTERFACE(iface) typedef interface iface { \
|
||||
const struct iface##Vtbl FAR* lpVtbl; \
|
||||
} iface; \
|
||||
typedef const struct iface##Vtbl iface##Vtbl; \
|
||||
const struct iface##Vtbl
|
||||
#else
|
||||
#undef CONST_VTBL
|
||||
#define CONST_VTBL
|
||||
#define DECLARE_INTERFACE(iface) typedef interface iface { \
|
||||
struct iface##Vtbl FAR* lpVtbl; \
|
||||
} iface; \
|
||||
typedef struct iface##Vtbl iface##Vtbl; \
|
||||
struct iface##Vtbl
|
||||
#endif
|
||||
#define DECLARE_INTERFACE_(iface, baseiface) DECLARE_INTERFACE(iface)
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
/****** Additional basic types **********************************************/
|
||||
|
||||
|
||||
#ifndef FARSTRUCT
|
||||
#define FARSTRUCT
|
||||
#endif // FARSTRUCT
|
||||
|
||||
|
||||
|
||||
#ifndef HUGEP
|
||||
#if defined(_WIN32) || defined(_MPPC_)
|
||||
#define HUGEP
|
||||
#else
|
||||
#define HUGEP __huge
|
||||
#endif // WIN32
|
||||
#endif // HUGEP
|
||||
|
||||
|
||||
#include <stdlib.h>
|
||||
|
||||
#define LISet32(li, v) ((li).HighPart = (v) < 0 ? -1 : 0, (li).LowPart = (v))
|
||||
|
||||
#define ULISet32(li, v) ((li).HighPart = 0, (li).LowPart = (v))
|
||||
|
||||
|
||||
#if defined(_WIN32) && !defined(OLE2ANSI)
|
||||
typedef WCHAR OLECHAR;
|
||||
|
||||
typedef /* [string] */ OLECHAR __RPC_FAR *LPOLESTR;
|
||||
|
||||
typedef /* [string] */ const OLECHAR __RPC_FAR *LPCOLESTR;
|
||||
|
||||
#define OLESTR(str) L##str
|
||||
|
||||
#else
|
||||
|
||||
typedef char OLECHAR;
|
||||
typedef LPSTR LPOLESTR;
|
||||
typedef LPCSTR LPCOLESTR;
|
||||
#define OLESTR(str) str
|
||||
#endif
|
||||
|
||||
|
||||
/* Forward Declarations */
|
||||
|
||||
#ifndef __IUnknown_FWD_DEFINED__
|
||||
#define __IUnknown_FWD_DEFINED__
|
||||
typedef interface IUnknown IUnknown;
|
||||
#endif /* __IUnknown_FWD_DEFINED__ */
|
||||
|
||||
|
||||
#ifndef __IUnknown_INTERFACE_DEFINED__
|
||||
#define __IUnknown_INTERFACE_DEFINED__
|
||||
|
||||
|
||||
/* interface IUnknown */
|
||||
/* [unique][uuid][object][local] */
|
||||
|
||||
typedef /* [unique] */ IUnknown __RPC_FAR *LPUNKNOWN;
|
||||
typedef /* [unique] */ IUnknown __RPC_FAR *PUNKNOWN;
|
||||
|
||||
//////////////////////////////////////////////////////////////////
|
||||
// IID_IUnknown and all other system IIDs are provided in UUID.LIB
|
||||
// Link that library in with your proxies, clients and servers
|
||||
//////////////////////////////////////////////////////////////////
|
||||
|
||||
EXTERN_C const IID IID_IUnknown;
|
||||
|
||||
typedef struct IUnknownVtbl
|
||||
{
|
||||
BEGIN_INTERFACE
|
||||
|
||||
HRESULT ( STDMETHODCALLTYPE __RPC_FAR *QueryInterface )(
|
||||
IUnknown __RPC_FAR * This,
|
||||
/* [in] */ __in REFIID riid,
|
||||
/* [iid_is][out] */ __deref_out void __RPC_FAR *__RPC_FAR *ppvObject);
|
||||
|
||||
ULONG ( STDMETHODCALLTYPE __RPC_FAR *AddRef )(
|
||||
IUnknown __RPC_FAR * This);
|
||||
|
||||
ULONG ( STDMETHODCALLTYPE __RPC_FAR *Release )(
|
||||
IUnknown __RPC_FAR * This);
|
||||
|
||||
END_INTERFACE
|
||||
} IUnknownVtbl;
|
||||
|
||||
interface IUnknown
|
||||
{
|
||||
CONST_VTBL struct IUnknownVtbl __RPC_FAR *lpVtbl;
|
||||
};
|
||||
|
||||
|
||||
#define IUnknown_QueryInterface(This,riid,ppvObject) \
|
||||
(This)->lpVtbl -> QueryInterface(This,riid,ppvObject)
|
||||
|
||||
#define IUnknown_AddRef(This) \
|
||||
(This)->lpVtbl -> AddRef(This)
|
||||
|
||||
#define IUnknown_Release(This) \
|
||||
(This)->lpVtbl -> Release(This)
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
/* interface __MIDL_itf_unknwn_0005 */
|
||||
/* [local] */
|
||||
|
||||
#endif // VC6 hack
|
||||
|
||||
|
||||
#ifndef __ISequentialStream_FWD_DEFINED__
|
||||
#define __ISequentialStream_FWD_DEFINED__
|
||||
typedef interface ISequentialStream ISequentialStream;
|
||||
#endif /* __ISequentialStream_FWD_DEFINED__ */
|
||||
|
||||
|
||||
#ifndef __ISequentialStream_INTERFACE_DEFINED__
|
||||
#define __ISequentialStream_INTERFACE_DEFINED__
|
||||
|
||||
/* interface ISequentialStream */
|
||||
/* [unique][uuid][object] */
|
||||
|
||||
|
||||
EXTERN_C const IID IID_ISequentialStream;
|
||||
|
||||
typedef struct ISequentialStreamVtbl
|
||||
{
|
||||
BEGIN_INTERFACE
|
||||
|
||||
HRESULT ( STDMETHODCALLTYPE __RPC_FAR *QueryInterface )(
|
||||
ISequentialStream __RPC_FAR * This,
|
||||
/* [in] */ __in REFIID riid,
|
||||
/* [iid_is][out] */ __deref_out void __RPC_FAR *__RPC_FAR *ppvObject);
|
||||
|
||||
ULONG ( STDMETHODCALLTYPE __RPC_FAR *AddRef )(
|
||||
ISequentialStream __RPC_FAR * This);
|
||||
|
||||
ULONG ( STDMETHODCALLTYPE __RPC_FAR *Release )(
|
||||
ISequentialStream __RPC_FAR * This);
|
||||
|
||||
/* [local] */ HRESULT ( STDMETHODCALLTYPE __RPC_FAR *Read )(
|
||||
ISequentialStream __RPC_FAR * This,
|
||||
/* [length_is][size_is][out] */ __out_bcount_part_opt(cb, *pcbRead) void __RPC_FAR *pv,
|
||||
/* [in] */ __in ULONG cb,
|
||||
/* [out] */ __out_opt ULONG __RPC_FAR *pcbRead);
|
||||
|
||||
/* [local] */ HRESULT ( STDMETHODCALLTYPE __RPC_FAR *Write )(
|
||||
ISequentialStream __RPC_FAR * This,
|
||||
/* [size_is][in] */ __in_bcount_opt(cb) const void __RPC_FAR *pv,
|
||||
/* [in] */ __in ULONG cb,
|
||||
/* [out] */ __out_opt ULONG __RPC_FAR *pcbWritten);
|
||||
|
||||
END_INTERFACE
|
||||
} ISequentialStreamVtbl;
|
||||
|
||||
interface ISequentialStream
|
||||
{
|
||||
CONST_VTBL struct ISequentialStreamVtbl __RPC_FAR *lpVtbl;
|
||||
};
|
||||
|
||||
|
||||
#define ISequentialStream_QueryInterface(This,riid,ppvObject) \
|
||||
(This)->lpVtbl -> QueryInterface(This,riid,ppvObject)
|
||||
|
||||
#define ISequentialStream_AddRef(This) \
|
||||
(This)->lpVtbl -> AddRef(This)
|
||||
|
||||
#define ISequentialStream_Release(This) \
|
||||
(This)->lpVtbl -> Release(This)
|
||||
|
||||
|
||||
#define ISequentialStream_Read(This,pv,cb,pcbRead) \
|
||||
(This)->lpVtbl -> Read(This,pv,cb,pcbRead)
|
||||
|
||||
#define ISequentialStream_Write(This,pv,cb,pcbWritten) \
|
||||
(This)->lpVtbl -> Write(This,pv,cb,pcbWritten)
|
||||
|
||||
|
||||
#endif /* __ISequentialStream_INTERFACE_DEFINED__ */
|
||||
|
||||
|
||||
|
||||
#ifndef __IStream_FWD_DEFINED__
|
||||
#define __IStream_FWD_DEFINED__
|
||||
typedef interface IStream IStream;
|
||||
#endif /* __IStream_FWD_DEFINED__ */
|
||||
|
||||
|
||||
#ifndef __IStream_INTERFACE_DEFINED__
|
||||
#define __IStream_INTERFACE_DEFINED__
|
||||
|
||||
/* interface IStream */
|
||||
/* [unique][uuid][object] */
|
||||
|
||||
typedef /* [unique] */ IStream __RPC_FAR *LPSTREAM;
|
||||
|
||||
typedef struct tagSTATSTG
|
||||
{
|
||||
LPOLESTR pwcsName;
|
||||
DWORD type;
|
||||
ULARGE_INTEGER cbSize;
|
||||
FILETIME mtime;
|
||||
FILETIME ctime;
|
||||
FILETIME atime;
|
||||
DWORD grfMode;
|
||||
DWORD grfLocksSupported;
|
||||
CLSID clsid;
|
||||
DWORD grfStateBits;
|
||||
DWORD reserved;
|
||||
} STATSTG;
|
||||
|
||||
typedef
|
||||
enum tagSTGTY
|
||||
{ STGTY_STORAGE = 1,
|
||||
STGTY_STREAM = 2,
|
||||
STGTY_LOCKBYTES = 3,
|
||||
STGTY_PROPERTY = 4
|
||||
} STGTY;
|
||||
|
||||
typedef
|
||||
enum tagSTREAM_SEEK
|
||||
{ STREAM_SEEK_SET = 0,
|
||||
STREAM_SEEK_CUR = 1,
|
||||
STREAM_SEEK_END = 2
|
||||
} STREAM_SEEK;
|
||||
|
||||
typedef
|
||||
enum tagLOCKTYPE
|
||||
{ LOCK_WRITE = 1,
|
||||
LOCK_EXCLUSIVE = 2,
|
||||
LOCK_ONLYONCE = 4
|
||||
} LOCKTYPE;
|
||||
|
||||
|
||||
EXTERN_C const IID IID_IStream;
|
||||
|
||||
|
||||
typedef struct IStreamVtbl
|
||||
{
|
||||
BEGIN_INTERFACE
|
||||
|
||||
HRESULT ( STDMETHODCALLTYPE __RPC_FAR *QueryInterface )(
|
||||
IStream __RPC_FAR * This,
|
||||
/* [in] */ __in REFIID riid,
|
||||
/* [iid_is][out] */ __deref_out void __RPC_FAR *__RPC_FAR *ppvObject);
|
||||
|
||||
ULONG ( STDMETHODCALLTYPE __RPC_FAR *AddRef )(
|
||||
IStream __RPC_FAR * This);
|
||||
|
||||
ULONG ( STDMETHODCALLTYPE __RPC_FAR *Release )(
|
||||
IStream __RPC_FAR * This);
|
||||
|
||||
/* [local] */ HRESULT ( STDMETHODCALLTYPE __RPC_FAR *Read )(
|
||||
IStream __RPC_FAR * This,
|
||||
/* [length_is][size_is][out] */ __out_bcount_part_opt(cb, *pcbRead) void __RPC_FAR *pv,
|
||||
/* [in] */ __in ULONG cb,
|
||||
/* [out] */ __out_opt ULONG __RPC_FAR *pcbRead);
|
||||
|
||||
/* [local] */ HRESULT ( STDMETHODCALLTYPE __RPC_FAR *Write )(
|
||||
IStream __RPC_FAR * This,
|
||||
/* [size_is][in] */ __in_bcount_opt(cb) const void __RPC_FAR *pv,
|
||||
/* [in] */ __in ULONG cb,
|
||||
/* [out] */ __out_opt ULONG __RPC_FAR *pcbWritten);
|
||||
|
||||
/* [local] */ HRESULT ( STDMETHODCALLTYPE __RPC_FAR *Seek )(
|
||||
IStream __RPC_FAR * This,
|
||||
/* [in] */ __in LARGE_INTEGER dlibMove,
|
||||
/* [in] */ __in DWORD dwOrigin,
|
||||
/* [out] */ __out_opt ULARGE_INTEGER __RPC_FAR *plibNewPosition);
|
||||
|
||||
HRESULT ( STDMETHODCALLTYPE __RPC_FAR *SetSize )(
|
||||
IStream __RPC_FAR * This,
|
||||
/* [in] */ __in ULARGE_INTEGER libNewSize);
|
||||
|
||||
/* [local] */ HRESULT ( STDMETHODCALLTYPE __RPC_FAR *CopyTo )(
|
||||
IStream __RPC_FAR * This,
|
||||
/* [unique][in] */ __in IStream __RPC_FAR *pstm,
|
||||
/* [in] */ __in ULARGE_INTEGER cb,
|
||||
/* [out] */ __out_opt ULARGE_INTEGER __RPC_FAR *pcbRead,
|
||||
/* [out] */ __out_opt ULARGE_INTEGER __RPC_FAR *pcbWritten);
|
||||
|
||||
HRESULT ( STDMETHODCALLTYPE __RPC_FAR *Commit )(
|
||||
IStream __RPC_FAR * This,
|
||||
/* [in] */ __in DWORD grfCommitFlags);
|
||||
|
||||
HRESULT ( STDMETHODCALLTYPE __RPC_FAR *Revert )(
|
||||
IStream __RPC_FAR * This);
|
||||
|
||||
HRESULT ( STDMETHODCALLTYPE __RPC_FAR *LockRegion )(
|
||||
IStream __RPC_FAR * This,
|
||||
/* [in] */ __in ULARGE_INTEGER libOffset,
|
||||
/* [in] */ __in ULARGE_INTEGER cb,
|
||||
/* [in] */ __in DWORD dwLockType);
|
||||
|
||||
HRESULT ( STDMETHODCALLTYPE __RPC_FAR *UnlockRegion )(
|
||||
IStream __RPC_FAR * This,
|
||||
/* [in] */ __in ULARGE_INTEGER libOffset,
|
||||
/* [in] */ __in ULARGE_INTEGER cb,
|
||||
/* [in] */ __in DWORD dwLockType);
|
||||
|
||||
HRESULT ( STDMETHODCALLTYPE __RPC_FAR *Stat )(
|
||||
IStream __RPC_FAR * This,
|
||||
/* [out] */ __out STATSTG __RPC_FAR *pstatstg,
|
||||
/* [in] */ __in DWORD grfStatFlag);
|
||||
|
||||
HRESULT ( STDMETHODCALLTYPE __RPC_FAR *Clone )(
|
||||
IStream __RPC_FAR * This,
|
||||
/* [out] */ __deref_out_opt IStream __RPC_FAR *__RPC_FAR *ppstm);
|
||||
|
||||
END_INTERFACE
|
||||
} IStreamVtbl;
|
||||
|
||||
interface IStream
|
||||
{
|
||||
CONST_VTBL struct IStreamVtbl __RPC_FAR *lpVtbl;
|
||||
};
|
||||
|
||||
|
||||
#define IStream_QueryInterface(This,riid,ppvObject) \
|
||||
(This)->lpVtbl -> QueryInterface(This,riid,ppvObject)
|
||||
|
||||
#define IStream_AddRef(This) \
|
||||
(This)->lpVtbl -> AddRef(This)
|
||||
|
||||
#define IStream_Release(This) \
|
||||
(This)->lpVtbl -> Release(This)
|
||||
|
||||
|
||||
#define IStream_Read(This,pv,cb,pcbRead) \
|
||||
(This)->lpVtbl -> Read(This,pv,cb,pcbRead)
|
||||
|
||||
#define IStream_Write(This,pv,cb,pcbWritten) \
|
||||
(This)->lpVtbl -> Write(This,pv,cb,pcbWritten)
|
||||
|
||||
|
||||
#define IStream_Seek(This,dlibMove,dwOrigin,plibNewPosition) \
|
||||
(This)->lpVtbl -> Seek(This,dlibMove,dwOrigin,plibNewPosition)
|
||||
|
||||
#define IStream_SetSize(This,libNewSize) \
|
||||
(This)->lpVtbl -> SetSize(This,libNewSize)
|
||||
|
||||
#define IStream_CopyTo(This,pstm,cb,pcbRead,pcbWritten) \
|
||||
(This)->lpVtbl -> CopyTo(This,pstm,cb,pcbRead,pcbWritten)
|
||||
|
||||
#define IStream_Commit(This,grfCommitFlags) \
|
||||
(This)->lpVtbl -> Commit(This,grfCommitFlags)
|
||||
|
||||
#define IStream_Revert(This) \
|
||||
(This)->lpVtbl -> Revert(This)
|
||||
|
||||
#define IStream_LockRegion(This,libOffset,cb,dwLockType) \
|
||||
(This)->lpVtbl -> LockRegion(This,libOffset,cb,dwLockType)
|
||||
|
||||
#define IStream_UnlockRegion(This,libOffset,cb,dwLockType) \
|
||||
(This)->lpVtbl -> UnlockRegion(This,libOffset,cb,dwLockType)
|
||||
|
||||
#define IStream_Stat(This,pstatstg,grfStatFlag) \
|
||||
(This)->lpVtbl -> Stat(This,pstatstg,grfStatFlag)
|
||||
|
||||
#define IStream_Clone(This,ppstm) \
|
||||
(This)->lpVtbl -> Clone(This,ppstm)
|
||||
|
||||
|
||||
|
||||
|
||||
#endif /* __IStream_INTERFACE_DEFINED__ */
|
||||
|
||||
|
||||
#ifndef __IClassFactory_FWD_DEFINED__
|
||||
#define __IClassFactory_FWD_DEFINED__
|
||||
typedef interface IClassFactory IClassFactory;
|
||||
#endif /* __IClassFactory_FWD_DEFINED__ */
|
||||
|
||||
|
||||
#ifndef __IClassFactory_INTERFACE_DEFINED__
|
||||
#define __IClassFactory_INTERFACE_DEFINED__
|
||||
|
||||
/* interface IClassFactory */
|
||||
/* [unique][uuid][object] */
|
||||
|
||||
typedef /* [unique] */ IClassFactory __RPC_FAR *LPCLASSFACTORY;
|
||||
|
||||
|
||||
EXTERN_C const IID IID_IClassFactory;
|
||||
|
||||
|
||||
typedef struct IClassFactoryVtbl
|
||||
{
|
||||
BEGIN_INTERFACE
|
||||
|
||||
HRESULT ( STDMETHODCALLTYPE __RPC_FAR *QueryInterface )(
|
||||
IClassFactory __RPC_FAR * This,
|
||||
/* [in] */ __in REFIID riid,
|
||||
/* [iid_is][out] */ __deref_out void __RPC_FAR *__RPC_FAR *ppvObject);
|
||||
|
||||
ULONG ( STDMETHODCALLTYPE __RPC_FAR *AddRef )(
|
||||
IClassFactory __RPC_FAR * This);
|
||||
|
||||
ULONG ( STDMETHODCALLTYPE __RPC_FAR *Release )(
|
||||
IClassFactory __RPC_FAR * This);
|
||||
|
||||
/* [local] */ HRESULT ( STDMETHODCALLTYPE __RPC_FAR *CreateInstance )(
|
||||
IClassFactory __RPC_FAR * This,
|
||||
/* [unique][in] */ __in_opt IUnknown __RPC_FAR *pUnkOuter,
|
||||
/* [in] */ __in REFIID riid,
|
||||
/* [iid_is][out] */ __deref_out void __RPC_FAR *__RPC_FAR *ppvObject);
|
||||
|
||||
/* [local] */ HRESULT ( STDMETHODCALLTYPE __RPC_FAR *LockServer )(
|
||||
IClassFactory __RPC_FAR * This,
|
||||
/* [in] */ __in BOOL fLock);
|
||||
|
||||
END_INTERFACE
|
||||
} IClassFactoryVtbl;
|
||||
|
||||
interface IClassFactory
|
||||
{
|
||||
CONST_VTBL struct IClassFactoryVtbl __RPC_FAR *lpVtbl;
|
||||
};
|
||||
|
||||
|
||||
|
||||
#define IClassFactory_QueryInterface(This,riid,ppvObject) \
|
||||
(This)->lpVtbl -> QueryInterface(This,riid,ppvObject)
|
||||
|
||||
#define IClassFactory_AddRef(This) \
|
||||
(This)->lpVtbl -> AddRef(This)
|
||||
|
||||
#define IClassFactory_Release(This) \
|
||||
(This)->lpVtbl -> Release(This)
|
||||
|
||||
|
||||
#define IClassFactory_CreateInstance(This,pUnkOuter,riid,ppvObject) \
|
||||
(This)->lpVtbl -> CreateInstance(This,pUnkOuter,riid,ppvObject)
|
||||
|
||||
#define IClassFactory_LockServer(This,fLock) \
|
||||
(This)->lpVtbl -> LockServer(This,fLock)
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
#endif /* __IClassFactory_INTERFACE_DEFINED__ */
|
||||
|
||||
|
||||
|
||||
#ifndef __IPersist_FWD_DEFINED__
|
||||
#define __IPersist_FWD_DEFINED__
|
||||
typedef interface IPersist IPersist;
|
||||
#endif /* __IPersist_FWD_DEFINED__ */
|
||||
|
||||
|
||||
#ifndef __IPersist_INTERFACE_DEFINED__
|
||||
#define __IPersist_INTERFACE_DEFINED__
|
||||
|
||||
/* interface IPersist */
|
||||
/* [uuid][object] */
|
||||
|
||||
typedef /* [unique] */ IPersist __RPC_FAR *LPPERSIST;
|
||||
|
||||
|
||||
EXTERN_C const IID IID_IPersist;
|
||||
|
||||
|
||||
typedef struct IPersistVtbl
|
||||
{
|
||||
BEGIN_INTERFACE
|
||||
|
||||
HRESULT ( STDMETHODCALLTYPE __RPC_FAR *QueryInterface )(
|
||||
IPersist __RPC_FAR * This,
|
||||
/* [in] */ __in REFIID riid,
|
||||
/* [iid_is][out] */ __deref_out void __RPC_FAR *__RPC_FAR *ppvObject);
|
||||
|
||||
ULONG ( STDMETHODCALLTYPE __RPC_FAR *AddRef )(
|
||||
IPersist __RPC_FAR * This);
|
||||
|
||||
ULONG ( STDMETHODCALLTYPE __RPC_FAR *Release )(
|
||||
IPersist __RPC_FAR * This);
|
||||
|
||||
HRESULT ( STDMETHODCALLTYPE __RPC_FAR *GetClassID )(
|
||||
IPersist __RPC_FAR * This,
|
||||
/* [out] */ __out CLSID __RPC_FAR *pClassID);
|
||||
|
||||
END_INTERFACE
|
||||
} IPersistVtbl;
|
||||
|
||||
interface IPersist
|
||||
{
|
||||
CONST_VTBL struct IPersistVtbl __RPC_FAR *lpVtbl;
|
||||
};
|
||||
|
||||
|
||||
|
||||
#define IPersist_QueryInterface(This,riid,ppvObject) \
|
||||
(This)->lpVtbl -> QueryInterface(This,riid,ppvObject)
|
||||
|
||||
#define IPersist_AddRef(This) \
|
||||
(This)->lpVtbl -> AddRef(This)
|
||||
|
||||
#define IPersist_Release(This) \
|
||||
(This)->lpVtbl -> Release(This)
|
||||
|
||||
|
||||
#define IPersist_GetClassID(This,pClassID) \
|
||||
(This)->lpVtbl -> GetClassID(This,pClassID)
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
#endif /* __IPersist_INTERFACE_DEFINED__ */
|
||||
|
||||
|
||||
|
||||
|
||||
#ifndef __IPersistStream_FWD_DEFINED__
|
||||
#define __IPersistStream_FWD_DEFINED__
|
||||
typedef interface IPersistStream IPersistStream;
|
||||
#endif /* __IPersistStream_FWD_DEFINED__ */
|
||||
|
||||
|
||||
#ifndef __IPersistStream_INTERFACE_DEFINED__
|
||||
#define __IPersistStream_INTERFACE_DEFINED__
|
||||
|
||||
/* interface IPersistStream */
|
||||
/* [unique][uuid][object] */
|
||||
|
||||
typedef /* [unique] */ IPersistStream __RPC_FAR *LPPERSISTSTREAM;
|
||||
|
||||
|
||||
EXTERN_C const IID IID_IPersistStream;
|
||||
|
||||
typedef struct IPersistStreamVtbl
|
||||
{
|
||||
BEGIN_INTERFACE
|
||||
|
||||
HRESULT ( STDMETHODCALLTYPE __RPC_FAR *QueryInterface )(
|
||||
IPersistStream __RPC_FAR * This,
|
||||
/* [in] */ __in REFIID riid,
|
||||
/* [iid_is][out] */ __deref_out void __RPC_FAR *__RPC_FAR *ppvObject);
|
||||
|
||||
ULONG ( STDMETHODCALLTYPE __RPC_FAR *AddRef )(
|
||||
IPersistStream __RPC_FAR * This);
|
||||
|
||||
ULONG ( STDMETHODCALLTYPE __RPC_FAR *Release )(
|
||||
IPersistStream __RPC_FAR * This);
|
||||
|
||||
HRESULT ( STDMETHODCALLTYPE __RPC_FAR *GetClassID )(
|
||||
IPersistStream __RPC_FAR * This,
|
||||
/* [out] */ __out CLSID __RPC_FAR *pClassID);
|
||||
|
||||
HRESULT ( STDMETHODCALLTYPE __RPC_FAR *IsDirty )(
|
||||
IPersistStream __RPC_FAR * This);
|
||||
|
||||
HRESULT ( STDMETHODCALLTYPE __RPC_FAR *Load )(
|
||||
IPersistStream __RPC_FAR * This,
|
||||
/* [unique][in] */ __in_opt IStream __RPC_FAR *pStm);
|
||||
|
||||
HRESULT ( STDMETHODCALLTYPE __RPC_FAR *Save )(
|
||||
IPersistStream __RPC_FAR * This,
|
||||
/* [unique][in] */ __in_opt IStream __RPC_FAR *pStm,
|
||||
/* [in] */ __in BOOL fClearDirty);
|
||||
|
||||
HRESULT ( STDMETHODCALLTYPE __RPC_FAR *GetSizeMax )(
|
||||
IPersistStream __RPC_FAR * This,
|
||||
/* [out] */ __out ULARGE_INTEGER __RPC_FAR *pcbSize);
|
||||
|
||||
END_INTERFACE
|
||||
} IPersistStreamVtbl;
|
||||
|
||||
interface IPersistStream
|
||||
{
|
||||
CONST_VTBL struct IPersistStreamVtbl __RPC_FAR *lpVtbl;
|
||||
};
|
||||
|
||||
|
||||
|
||||
#define IPersistStream_QueryInterface(This,riid,ppvObject) \
|
||||
(This)->lpVtbl -> QueryInterface(This,riid,ppvObject)
|
||||
|
||||
#define IPersistStream_AddRef(This) \
|
||||
(This)->lpVtbl -> AddRef(This)
|
||||
|
||||
#define IPersistStream_Release(This) \
|
||||
(This)->lpVtbl -> Release(This)
|
||||
|
||||
|
||||
#define IPersistStream_GetClassID(This,pClassID) \
|
||||
(This)->lpVtbl -> GetClassID(This,pClassID)
|
||||
|
||||
|
||||
#define IPersistStream_IsDirty(This) \
|
||||
(This)->lpVtbl -> IsDirty(This)
|
||||
|
||||
#define IPersistStream_Load(This,pStm) \
|
||||
(This)->lpVtbl -> Load(This,pStm)
|
||||
|
||||
#define IPersistStream_Save(This,pStm,fClearDirty) \
|
||||
(This)->lpVtbl -> Save(This,pStm,fClearDirty)
|
||||
|
||||
#define IPersistStream_GetSizeMax(This,pcbSize) \
|
||||
(This)->lpVtbl -> GetSizeMax(This,pcbSize)
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
#endif /* __IPersistStream_INTERFACE_DEFINED__ */
|
||||
|
||||
|
||||
|
||||
#include <guiddef.h>
|
||||
|
||||
#ifndef INITGUID
|
||||
#include <cguid.h>
|
||||
#endif
|
||||
|
||||
#ifndef RC_INVOKED
|
||||
#include <poppack.h>
|
||||
#endif // RC_INVOKED
|
||||
|
||||
#endif // _XOBJBASE_H_
|
||||
@@ -0,0 +1,506 @@
|
||||
/*
|
||||
xaudio.h (2010-08-14) / (2012-12-04)
|
||||
authors: OV2, Themaister
|
||||
*/
|
||||
|
||||
// Kinda stripped down. Only contains the bare essentials used in RetroArch.
|
||||
|
||||
#ifndef XAUDIO2_XDK360_H
|
||||
#define XAUDIO2_XDK360_H
|
||||
|
||||
#include <comdecl.h> // For DEFINE_CLSID and DEFINE_IID
|
||||
|
||||
DEFINE_CLSID(XAudio2, 3eda9b49, 2085, 498b, 9b, b2, 39, a6, 77, 84, 93, de);
|
||||
DEFINE_CLSID(XAudio2_Debug, 47199894, 7cc2, 444d, 98, 73, ce, d2, 56, 2c, c6, 0e);
|
||||
DEFINE_IID(IXAudio2, 8bcf1f58, 9fe7, 4583, 8a, c6, e2, ad, c4, 65, c8, bb);
|
||||
|
||||
|
||||
// Ignore the rest of this header if only the GUID definitions were requested
|
||||
#ifndef GUID_DEFS_ONLY
|
||||
|
||||
#include "objbase.h" // Xbox COM declarations (IUnknown, etc)
|
||||
|
||||
#include <audiodefs.h> // Basic audio data types and constants
|
||||
#include <xma2defs.h> // Data types and constants for XMA2 audio
|
||||
|
||||
// All structures defined in this file use tight field packing
|
||||
#pragma pack(push, 1)
|
||||
|
||||
// Numeric boundary values
|
||||
#define XAUDIO2_MAX_BUFFER_BYTES 0x80000000 // Maximum bytes allowed in a source buffer
|
||||
#define XAUDIO2_MAX_QUEUED_BUFFERS 64 // Maximum buffers allowed in a voice queue
|
||||
#define XAUDIO2_MAX_BUFFERS_SYSTEM 2 // Maximum buffers allowed for system threads (Xbox 360 only)
|
||||
#define XAUDIO2_MAX_AUDIO_CHANNELS 64 // Maximum channels in an audio stream
|
||||
#define XAUDIO2_MIN_SAMPLE_RATE 1000 // Minimum audio sample rate supported
|
||||
#define XAUDIO2_MAX_SAMPLE_RATE 200000 // Maximum audio sample rate supported
|
||||
#define XAUDIO2_MAX_VOLUME_LEVEL 16777216.0f // Maximum acceptable volume level (2^24)
|
||||
#define XAUDIO2_MIN_FREQ_RATIO (1/1024.0f) // Minimum SetFrequencyRatio argument
|
||||
#define XAUDIO2_MAX_FREQ_RATIO 1024.0f // Maximum MaxFrequencyRatio argument
|
||||
#define XAUDIO2_DEFAULT_FREQ_RATIO 2.0f // Default MaxFrequencyRatio argument
|
||||
#define XAUDIO2_MAX_FILTER_ONEOVERQ 1.5f // Maximum XAUDIO2_FILTER_PARAMETERS.OneOverQ
|
||||
#define XAUDIO2_MAX_FILTER_FREQUENCY 1.0f // Maximum XAUDIO2_FILTER_PARAMETERS.Frequency
|
||||
#define XAUDIO2_MAX_LOOP_COUNT 254 // Maximum non-infinite XAUDIO2_BUFFER.LoopCount
|
||||
#define XAUDIO2_MAX_INSTANCES 8 // Maximum simultaneous XAudio2 objects on Xbox 360
|
||||
|
||||
#define XAUDIO2_MAX_RATIO_TIMES_RATE_XMA_MONO 600000
|
||||
#define XAUDIO2_MAX_RATIO_TIMES_RATE_XMA_MULTICHANNEL 300000
|
||||
|
||||
// Numeric values with special meanings
|
||||
#define XAUDIO2_COMMIT_NOW 0 // Used as an OperationSet argument
|
||||
#define XAUDIO2_COMMIT_ALL 0 // Used in IXAudio2::CommitChanges
|
||||
#define XAUDIO2_INVALID_OPSET (UINT32)(-1) // Not allowed for OperationSet arguments
|
||||
#define XAUDIO2_NO_LOOP_REGION 0 // Used in XAUDIO2_BUFFER.LoopCount
|
||||
#define XAUDIO2_LOOP_INFINITE 255 // Used in XAUDIO2_BUFFER.LoopCount
|
||||
#define XAUDIO2_DEFAULT_CHANNELS 0 // Used in CreateMasteringVoice
|
||||
#define XAUDIO2_DEFAULT_SAMPLERATE 0 // Used in CreateMasteringVoice
|
||||
|
||||
// Flags
|
||||
#define XAUDIO2_DEBUG_ENGINE 0x0001 // Used in XAudio2Create on Windows only
|
||||
#define XAUDIO2_VOICE_NOPITCH 0x0002 // Used in IXAudio2::CreateSourceVoice
|
||||
#define XAUDIO2_VOICE_NOSRC 0x0004 // Used in IXAudio2::CreateSourceVoice
|
||||
#define XAUDIO2_VOICE_USEFILTER 0x0008 // Used in IXAudio2::CreateSource/SubmixVoice
|
||||
#define XAUDIO2_VOICE_MUSIC 0x0010 // Used in IXAudio2::CreateSourceVoice
|
||||
#define XAUDIO2_PLAY_TAILS 0x0020 // Used in IXAudio2SourceVoice::Stop
|
||||
#define XAUDIO2_END_OF_STREAM 0x0040 // Used in XAUDIO2_BUFFER.Flags
|
||||
#define XAUDIO2_SEND_USEFILTER 0x0080 // Used in XAUDIO2_SEND_DESCRIPTOR.Flags
|
||||
|
||||
// Default parameters for the built-in filter
|
||||
#define XAUDIO2_DEFAULT_FILTER_TYPE LowPassFilter
|
||||
#define XAUDIO2_DEFAULT_FILTER_FREQUENCY XAUDIO2_MAX_FILTER_FREQUENCY
|
||||
#define XAUDIO2_DEFAULT_FILTER_ONEOVERQ 1.0f
|
||||
|
||||
// Internal XAudio2 constants
|
||||
#define XAUDIO2_QUANTUM_NUMERATOR 2 // On Xbox 360, XAudio2 processes audio
|
||||
#define XAUDIO2_QUANTUM_DENOMINATOR 375 // in 5.333ms chunks (= 2/375 seconds)
|
||||
#define XAUDIO2_QUANTUM_MS (1000.0f * XAUDIO2_QUANTUM_NUMERATOR / XAUDIO2_QUANTUM_DENOMINATOR)
|
||||
|
||||
// XAudio2 error codes
|
||||
#define FACILITY_XAUDIO2 0x896
|
||||
#define XAUDIO2_E_INVALID_CALL 0x88960001 // An API call or one of its arguments was illegal
|
||||
#define XAUDIO2_E_XMA_DECODER_ERROR 0x88960002 // The XMA hardware suffered an unrecoverable error
|
||||
#define XAUDIO2_E_XAPO_CREATION_FAILED 0x88960003 // XAudio2 failed to initialize an XAPO effect
|
||||
#define XAUDIO2_E_DEVICE_INVALIDATED 0x88960004 // An audio device became unusable (unplugged, etc)
|
||||
|
||||
#define FWD_DECLARE(x) typedef interface x x
|
||||
|
||||
FWD_DECLARE(IXAudio2);
|
||||
FWD_DECLARE(IXAudio2Voice);
|
||||
FWD_DECLARE(IXAudio2SourceVoice);
|
||||
FWD_DECLARE(IXAudio2SubmixVoice);
|
||||
FWD_DECLARE(IXAudio2MasteringVoice);
|
||||
FWD_DECLARE(IXAudio2EngineCallback);
|
||||
FWD_DECLARE(IXAudio2VoiceCallback);
|
||||
|
||||
typedef enum XAUDIO2_XBOX_HWTHREAD_SPECIFIER
|
||||
{
|
||||
XboxThread0 = 0x01,
|
||||
XboxThread1 = 0x02,
|
||||
XboxThread2 = 0x04,
|
||||
XboxThread3 = 0x08,
|
||||
XboxThread4 = 0x10,
|
||||
XboxThread5 = 0x20,
|
||||
XAUDIO2_ANY_PROCESSOR = XboxThread4,
|
||||
XAUDIO2_DEFAULT_PROCESSOR = XAUDIO2_ANY_PROCESSOR
|
||||
} XAUDIO2_XBOX_HWTHREAD_SPECIFIER, XAUDIO2_PROCESSOR;
|
||||
|
||||
typedef enum XAUDIO2_DEVICE_ROLE
|
||||
{
|
||||
NotDefaultDevice = 0x0,
|
||||
DefaultConsoleDevice = 0x1,
|
||||
DefaultMultimediaDevice = 0x2,
|
||||
DefaultCommunicationsDevice = 0x4,
|
||||
DefaultGameDevice = 0x8,
|
||||
GlobalDefaultDevice = 0xf,
|
||||
InvalidDeviceRole = ~GlobalDefaultDevice
|
||||
} XAUDIO2_DEVICE_ROLE;
|
||||
|
||||
typedef struct XAUDIO2_DEVICE_DETAILS
|
||||
{
|
||||
WCHAR DeviceID[256]; // String identifier for the audio device.
|
||||
WCHAR DisplayName[256]; // Friendly name suitable for display to a human.
|
||||
XAUDIO2_DEVICE_ROLE Role; // Roles that the device should be used for.
|
||||
WAVEFORMATEXTENSIBLE OutputFormat; // The device's native PCM audio output format.
|
||||
} XAUDIO2_DEVICE_DETAILS;
|
||||
|
||||
typedef struct XAUDIO2_VOICE_DETAILS
|
||||
{
|
||||
UINT32 CreationFlags; // Flags the voice was created with.
|
||||
UINT32 InputChannels; // Channels in the voice's input audio.
|
||||
UINT32 InputSampleRate; // Sample rate of the voice's input audio.
|
||||
} XAUDIO2_VOICE_DETAILS;
|
||||
|
||||
// Used in XAUDIO2_VOICE_SENDS below
|
||||
typedef struct XAUDIO2_SEND_DESCRIPTOR
|
||||
{
|
||||
UINT32 Flags; // Either 0 or XAUDIO2_SEND_USEFILTER.
|
||||
IXAudio2Voice* pOutputVoice; // This send's destination voice.
|
||||
} XAUDIO2_SEND_DESCRIPTOR;
|
||||
|
||||
// Used in the voice creation functions and in IXAudio2Voice::SetOutputVoices
|
||||
typedef struct XAUDIO2_VOICE_SENDS
|
||||
{
|
||||
UINT32 SendCount; // Number of sends from this voice.
|
||||
XAUDIO2_SEND_DESCRIPTOR* pSends; // Array of SendCount send descriptors.
|
||||
} XAUDIO2_VOICE_SENDS;
|
||||
|
||||
// Used in XAUDIO2_EFFECT_CHAIN below
|
||||
typedef struct XAUDIO2_EFFECT_DESCRIPTOR
|
||||
{
|
||||
IUnknown* pEffect; // Pointer to the effect object's IUnknown interface.
|
||||
BOOL InitialState; // TRUE if the effect should begin in the enabled state.
|
||||
UINT32 OutputChannels; // How many output channels the effect should produce.
|
||||
} XAUDIO2_EFFECT_DESCRIPTOR;
|
||||
|
||||
// Used in the voice creation functions and in IXAudio2Voice::SetEffectChain
|
||||
typedef struct XAUDIO2_EFFECT_CHAIN
|
||||
{
|
||||
UINT32 EffectCount; // Number of effects in this voice's effect chain.
|
||||
XAUDIO2_EFFECT_DESCRIPTOR* pEffectDescriptors; // Array of effect descriptors.
|
||||
} XAUDIO2_EFFECT_CHAIN;
|
||||
|
||||
// Used in XAUDIO2_FILTER_PARAMETERS below
|
||||
typedef enum XAUDIO2_FILTER_TYPE
|
||||
{
|
||||
LowPassFilter, // Attenuates frequencies above the cutoff frequency.
|
||||
BandPassFilter, // Attenuates frequencies outside a given range.
|
||||
HighPassFilter, // Attenuates frequencies below the cutoff frequency.
|
||||
NotchFilter // Attenuates frequencies inside a given range.
|
||||
} XAUDIO2_FILTER_TYPE;
|
||||
|
||||
// Used in IXAudio2Voice::Set/GetFilterParameters and Set/GetOutputFilterParameters
|
||||
typedef struct XAUDIO2_FILTER_PARAMETERS
|
||||
{
|
||||
XAUDIO2_FILTER_TYPE Type; // Low-pass, band-pass or high-pass.
|
||||
float Frequency; // Radian frequency (2 * sin(pi*CutoffFrequency/SampleRate));
|
||||
// must be >= 0 and <= XAUDIO2_MAX_FILTER_FREQUENCY
|
||||
// (giving a maximum CutoffFrequency of SampleRate/6).
|
||||
float OneOverQ; // Reciprocal of the filter's quality factor Q;
|
||||
// must be > 0 and <= XAUDIO2_MAX_FILTER_ONEOVERQ.
|
||||
} XAUDIO2_FILTER_PARAMETERS;
|
||||
|
||||
// Used in IXAudio2SourceVoice::SubmitSourceBuffer
|
||||
typedef struct XAUDIO2_BUFFER
|
||||
{
|
||||
UINT32 Flags; // Either 0 or XAUDIO2_END_OF_STREAM.
|
||||
UINT32 AudioBytes; // Size of the audio data buffer in bytes.
|
||||
const BYTE* pAudioData; // Pointer to the audio data buffer.
|
||||
UINT32 PlayBegin; // First sample in this buffer to be played.
|
||||
UINT32 PlayLength; // Length of the region to be played in samples,
|
||||
// or 0 to play the whole buffer.
|
||||
UINT32 LoopBegin; // First sample of the region to be looped.
|
||||
UINT32 LoopLength; // Length of the desired loop region in samples,
|
||||
// or 0 to loop the entire buffer.
|
||||
UINT32 LoopCount; // Number of times to repeat the loop region,
|
||||
// or XAUDIO2_LOOP_INFINITE to loop forever.
|
||||
void* pContext; // Context value to be passed back in callbacks.
|
||||
} XAUDIO2_BUFFER;
|
||||
|
||||
typedef struct XAUDIO2_BUFFER_WMA
|
||||
{
|
||||
const UINT32* pDecodedPacketCumulativeBytes; // Decoded packet's cumulative size array.
|
||||
// Each element is the number of bytes accumulated
|
||||
// when the corresponding XWMA packet is decoded in
|
||||
// order. The array must have PacketCount elements.
|
||||
UINT32 PacketCount; // Number of XWMA packets submitted. Must be >= 1 and
|
||||
// divide evenly into XAUDIO2_BUFFER.AudioBytes.
|
||||
} XAUDIO2_BUFFER_WMA;
|
||||
|
||||
// Returned by IXAudio2SourceVoice::GetState
|
||||
typedef struct XAUDIO2_VOICE_STATE
|
||||
{
|
||||
void* pCurrentBufferContext; // The pContext value provided in the XAUDIO2_BUFFER
|
||||
// that is currently being processed, or NULL if
|
||||
// there are no buffers in the queue.
|
||||
UINT32 BuffersQueued; // Number of buffers currently queued on the voice
|
||||
// (including the one that is being processed).
|
||||
UINT64 SamplesPlayed; // Total number of samples produced by the voice since
|
||||
// it began processing the current audio stream.
|
||||
} XAUDIO2_VOICE_STATE;
|
||||
|
||||
#define XAUDIO2_LOG_ERRORS 0x0001 // For handled errors with serious effects.
|
||||
#define XAUDIO2_LOG_WARNINGS 0x0002 // For handled errors that may be recoverable.
|
||||
#define XAUDIO2_LOG_INFO 0x0004 // Informational chit-chat (e.g. state changes).
|
||||
#define XAUDIO2_LOG_DETAIL 0x0008 // More detailed chit-chat.
|
||||
#define XAUDIO2_LOG_API_CALLS 0x0010 // Public API function entries and exits.
|
||||
#define XAUDIO2_LOG_FUNC_CALLS 0x0020 // Internal function entries and exits.
|
||||
#define XAUDIO2_LOG_TIMING 0x0040 // Delays detected and other timing data.
|
||||
#define XAUDIO2_LOG_LOCKS 0x0080 // Usage of critical sections and mutexes.
|
||||
#define XAUDIO2_LOG_MEMORY 0x0100 // Memory heap usage information.
|
||||
#define XAUDIO2_LOG_STREAMING 0x1000 // Audio streaming information.
|
||||
|
||||
#define X2DEFAULT(x)
|
||||
|
||||
#undef INTERFACE
|
||||
#define INTERFACE IXAudio2
|
||||
DECLARE_INTERFACE_(IXAudio2, IUnknown)
|
||||
{
|
||||
STDMETHOD(QueryInterface) (THIS_ REFIID riid, __deref_out void** ppvInterface) PURE;
|
||||
STDMETHOD_(ULONG, AddRef) (THIS) PURE;
|
||||
STDMETHOD_(ULONG, Release) (THIS) PURE;
|
||||
STDMETHOD(GetDeviceCount) (THIS_ __out UINT32* pCount) PURE;
|
||||
STDMETHOD(GetDeviceDetails) (THIS_ UINT32 Index, __out XAUDIO2_DEVICE_DETAILS* pDeviceDetails) PURE;
|
||||
STDMETHOD(Initialize) (THIS_ UINT32 Flags X2DEFAULT(0),
|
||||
XAUDIO2_PROCESSOR XAudio2Processor X2DEFAULT(XAUDIO2_DEFAULT_PROCESSOR)) PURE;
|
||||
STDMETHOD(RegisterForCallbacks) (__in IXAudio2EngineCallback* pCallback) PURE;
|
||||
STDMETHOD_(void, UnregisterForCallbacks) (__in IXAudio2EngineCallback* pCallback) PURE;
|
||||
STDMETHOD(CreateSourceVoice) (THIS_ __deref_out IXAudio2SourceVoice** ppSourceVoice,
|
||||
__in const WAVEFORMATEX* pSourceFormat,
|
||||
UINT32 Flags X2DEFAULT(0),
|
||||
float MaxFrequencyRatio X2DEFAULT(XAUDIO2_DEFAULT_FREQ_RATIO),
|
||||
__in_opt IXAudio2VoiceCallback* pCallback X2DEFAULT(NULL),
|
||||
__in_opt const XAUDIO2_VOICE_SENDS* pSendList X2DEFAULT(NULL),
|
||||
__in_opt const XAUDIO2_EFFECT_CHAIN* pEffectChain X2DEFAULT(NULL)) PURE;
|
||||
STDMETHOD(CreateSubmixVoice) (THIS_ __deref_out IXAudio2SubmixVoice** ppSubmixVoice,
|
||||
UINT32 InputChannels, UINT32 InputSampleRate,
|
||||
UINT32 Flags X2DEFAULT(0), UINT32 ProcessingStage X2DEFAULT(0),
|
||||
__in_opt const XAUDIO2_VOICE_SENDS* pSendList X2DEFAULT(NULL),
|
||||
__in_opt const XAUDIO2_EFFECT_CHAIN* pEffectChain X2DEFAULT(NULL)) PURE;
|
||||
STDMETHOD(CreateMasteringVoice) (THIS_ __deref_out IXAudio2MasteringVoice** ppMasteringVoice,
|
||||
UINT32 InputChannels X2DEFAULT(XAUDIO2_DEFAULT_CHANNELS),
|
||||
UINT32 InputSampleRate X2DEFAULT(XAUDIO2_DEFAULT_SAMPLERATE),
|
||||
UINT32 Flags X2DEFAULT(0), UINT32 DeviceIndex X2DEFAULT(0),
|
||||
__in_opt const XAUDIO2_EFFECT_CHAIN* pEffectChain X2DEFAULT(NULL)) PURE;
|
||||
|
||||
|
||||
STDMETHOD(StartEngine) (THIS) PURE;
|
||||
STDMETHOD_(void, StopEngine) (THIS) PURE;
|
||||
STDMETHOD(CommitChanges) (THIS_ UINT32 OperationSet) PURE;
|
||||
};
|
||||
|
||||
#undef INTERFACE
|
||||
#define INTERFACE IXAudio2Voice
|
||||
DECLARE_INTERFACE(IXAudio2Voice)
|
||||
{
|
||||
#define Declare_IXAudio2Voice_Methods() \
|
||||
STDMETHOD_(void, GetVoiceDetails) (THIS_ __out XAUDIO2_VOICE_DETAILS* pVoiceDetails) PURE; \
|
||||
\
|
||||
STDMETHOD(SetOutputVoices) (THIS_ __in_opt const XAUDIO2_VOICE_SENDS* pSendList) PURE; \
|
||||
\
|
||||
STDMETHOD(SetEffectChain) (THIS_ __in_opt const XAUDIO2_EFFECT_CHAIN* pEffectChain) PURE; \
|
||||
\
|
||||
STDMETHOD(EnableEffect) (THIS_ UINT32 EffectIndex, \
|
||||
UINT32 OperationSet X2DEFAULT(XAUDIO2_COMMIT_NOW)) PURE; \
|
||||
\
|
||||
STDMETHOD(DisableEffect) (THIS_ UINT32 EffectIndex, \
|
||||
UINT32 OperationSet X2DEFAULT(XAUDIO2_COMMIT_NOW)) PURE; \
|
||||
\
|
||||
STDMETHOD_(void, GetEffectState) (THIS_ UINT32 EffectIndex, __out BOOL* pEnabled) PURE; \
|
||||
\
|
||||
STDMETHOD(SetEffectParameters) (THIS_ UINT32 EffectIndex, \
|
||||
__in_bcount(ParametersByteSize) const void* pParameters, \
|
||||
UINT32 ParametersByteSize, \
|
||||
UINT32 OperationSet X2DEFAULT(XAUDIO2_COMMIT_NOW)) PURE; \
|
||||
\
|
||||
STDMETHOD(GetEffectParameters) (THIS_ UINT32 EffectIndex, \
|
||||
__out_bcount(ParametersByteSize) void* pParameters, \
|
||||
UINT32 ParametersByteSize) PURE; \
|
||||
\
|
||||
STDMETHOD(SetFilterParameters) (THIS_ __in const XAUDIO2_FILTER_PARAMETERS* pParameters, \
|
||||
UINT32 OperationSet X2DEFAULT(XAUDIO2_COMMIT_NOW)) PURE; \
|
||||
\
|
||||
STDMETHOD_(void, GetFilterParameters) (THIS_ __out XAUDIO2_FILTER_PARAMETERS* pParameters) PURE; \
|
||||
\
|
||||
STDMETHOD(SetOutputFilterParameters) (THIS_ __in_opt IXAudio2Voice* pDestinationVoice, \
|
||||
__in const XAUDIO2_FILTER_PARAMETERS* pParameters, \
|
||||
UINT32 OperationSet X2DEFAULT(XAUDIO2_COMMIT_NOW)) PURE; \
|
||||
\
|
||||
STDMETHOD_(void, GetOutputFilterParameters) (THIS_ __in_opt IXAudio2Voice* pDestinationVoice, \
|
||||
__out XAUDIO2_FILTER_PARAMETERS* pParameters) PURE; \
|
||||
\
|
||||
STDMETHOD(SetVolume) (THIS_ float Volume, \
|
||||
UINT32 OperationSet X2DEFAULT(XAUDIO2_COMMIT_NOW)) PURE; \
|
||||
\
|
||||
STDMETHOD_(void, GetVolume) (THIS_ __out float* pVolume) PURE; \
|
||||
\
|
||||
STDMETHOD(SetChannelVolumes) (THIS_ UINT32 Channels, __in_ecount(Channels) const float* pVolumes, \
|
||||
UINT32 OperationSet X2DEFAULT(XAUDIO2_COMMIT_NOW)) PURE; \
|
||||
\
|
||||
STDMETHOD_(void, GetChannelVolumes) (THIS_ UINT32 Channels, __out_ecount(Channels) float* pVolumes) PURE; \
|
||||
\
|
||||
STDMETHOD(SetOutputMatrix) (THIS_ __in_opt IXAudio2Voice* pDestinationVoice, \
|
||||
UINT32 SourceChannels, UINT32 DestinationChannels, \
|
||||
__in_ecount(SourceChannels * DestinationChannels) const float* pLevelMatrix, \
|
||||
UINT32 OperationSet X2DEFAULT(XAUDIO2_COMMIT_NOW)) PURE; \
|
||||
\
|
||||
STDMETHOD_(void, GetOutputMatrix) (THIS_ __in_opt IXAudio2Voice* pDestinationVoice, \
|
||||
UINT32 SourceChannels, UINT32 DestinationChannels, \
|
||||
__out_ecount(SourceChannels * DestinationChannels) float* pLevelMatrix) PURE; \
|
||||
\
|
||||
STDMETHOD_(void, DestroyVoice) (THIS) PURE
|
||||
|
||||
Declare_IXAudio2Voice_Methods();
|
||||
};
|
||||
|
||||
#undef INTERFACE
|
||||
#define INTERFACE IXAudio2SourceVoice
|
||||
DECLARE_INTERFACE_(IXAudio2SourceVoice, IXAudio2Voice)
|
||||
{
|
||||
Declare_IXAudio2Voice_Methods();
|
||||
STDMETHOD(Start) (THIS_ UINT32 Flags X2DEFAULT(0), UINT32 OperationSet X2DEFAULT(XAUDIO2_COMMIT_NOW)) PURE;
|
||||
STDMETHOD(Stop) (THIS_ UINT32 Flags X2DEFAULT(0), UINT32 OperationSet X2DEFAULT(XAUDIO2_COMMIT_NOW)) PURE;
|
||||
STDMETHOD(SubmitSourceBuffer) (THIS_ __in const XAUDIO2_BUFFER* pBuffer, __in_opt const XAUDIO2_BUFFER_WMA* pBufferWMA X2DEFAULT(NULL)) PURE;
|
||||
STDMETHOD(FlushSourceBuffers) (THIS) PURE;
|
||||
STDMETHOD(Discontinuity) (THIS) PURE;
|
||||
STDMETHOD(ExitLoop) (THIS_ UINT32 OperationSet X2DEFAULT(XAUDIO2_COMMIT_NOW)) PURE;
|
||||
STDMETHOD_(void, GetState) (THIS_ __out XAUDIO2_VOICE_STATE* pVoiceState) PURE;
|
||||
STDMETHOD(SetFrequencyRatio) (THIS_ float Ratio,
|
||||
UINT32 OperationSet X2DEFAULT(XAUDIO2_COMMIT_NOW)) PURE;
|
||||
STDMETHOD_(void, GetFrequencyRatio) (THIS_ __out float* pRatio) PURE;
|
||||
STDMETHOD(SetSourceSampleRate) (THIS_ UINT32 NewSourceSampleRate) PURE;
|
||||
};
|
||||
|
||||
#undef INTERFACE
|
||||
#define INTERFACE IXAudio2SubmixVoice
|
||||
DECLARE_INTERFACE_(IXAudio2SubmixVoice, IXAudio2Voice)
|
||||
{
|
||||
Declare_IXAudio2Voice_Methods();
|
||||
};
|
||||
|
||||
#undef INTERFACE
|
||||
#define INTERFACE IXAudio2MasteringVoice
|
||||
DECLARE_INTERFACE_(IXAudio2MasteringVoice, IXAudio2Voice)
|
||||
{
|
||||
Declare_IXAudio2Voice_Methods();
|
||||
};
|
||||
|
||||
#undef INTERFACE
|
||||
#define INTERFACE IXAudio2EngineCallback
|
||||
DECLARE_INTERFACE(IXAudio2EngineCallback)
|
||||
{
|
||||
STDMETHOD_(void, OnProcessingPassStart) (THIS) PURE;
|
||||
STDMETHOD_(void, OnProcessingPassEnd) (THIS) PURE;
|
||||
STDMETHOD_(void, OnCriticalError) (THIS_ HRESULT Error) PURE;
|
||||
};
|
||||
|
||||
#undef INTERFACE
|
||||
#define INTERFACE IXAudio2VoiceCallback
|
||||
DECLARE_INTERFACE(IXAudio2VoiceCallback)
|
||||
{
|
||||
STDMETHOD_(void, OnVoiceProcessingPassStart) (THIS_ UINT32 BytesRequired) PURE;
|
||||
STDMETHOD_(void, OnVoiceProcessingPassEnd) (THIS) PURE;
|
||||
STDMETHOD_(void, OnStreamEnd) (THIS) PURE;
|
||||
STDMETHOD_(void, OnBufferStart) (THIS_ void* pBufferContext) PURE;
|
||||
STDMETHOD_(void, OnBufferEnd) (THIS_ void* pBufferContext) PURE;
|
||||
STDMETHOD_(void, OnLoopEnd) (THIS_ void* pBufferContext) PURE;
|
||||
STDMETHOD_(void, OnVoiceError) (THIS_ void* pBufferContext, HRESULT Error) PURE;
|
||||
};
|
||||
|
||||
// IXAudio2
|
||||
#define IXAudio2_QueryInterface(This,riid,ppvInterface) ((This)->lpVtbl->QueryInterface(This,riid,ppvInterface))
|
||||
#define IXAudio2_AddRef(This) ((This)->lpVtbl->AddRef(This))
|
||||
#define IXAudio2_Release(This) ((This)->lpVtbl->Release(This))
|
||||
#define IXAudio2_GetDeviceCount(This,puCount) ((This)->lpVtbl->GetDeviceCount(This,puCount))
|
||||
#define IXAudio2_GetDeviceDetails(This,Index,pDeviceDetails) ((This)->lpVtbl->GetDeviceDetails(This,Index,pDeviceDetails))
|
||||
#define IXAudio2_Initialize(This,Flags,XAudio2Processor) ((This)->lpVtbl->Initialize(This,Flags,XAudio2Processor))
|
||||
#define IXAudio2_CreateSourceVoice(This,ppSourceVoice,pSourceFormat,Flags,MaxFrequencyRatio,pCallback,pSendList,pEffectChain) ((This)->lpVtbl->CreateSourceVoice(This,ppSourceVoice,pSourceFormat,Flags,MaxFrequencyRatio,pCallback,pSendList,pEffectChain))
|
||||
#define IXAudio2_CreateSubmixVoice(This,ppSubmixVoice,InputChannels,InputSampleRate,Flags,ProcessingStage,pSendList,pEffectChain) ((This)->lpVtbl->CreateSubmixVoice(This,ppSubmixVoice,InputChannels,InputSampleRate,Flags,ProcessingStage,pSendList,pEffectChain))
|
||||
#define IXAudio2_CreateMasteringVoice(This,ppMasteringVoice,InputChannels,InputSampleRate,Flags,DeviceIndex,pEffectChain) ((This)->lpVtbl->CreateMasteringVoice(This,ppMasteringVoice,InputChannels,InputSampleRate,Flags,DeviceIndex,pEffectChain))
|
||||
#define IXAudio2_StartEngine(This) ((This)->lpVtbl->StartEngine(This))
|
||||
#define IXAudio2_StopEngine(This) ((This)->lpVtbl->StopEngine(This))
|
||||
#define IXAudio2_CommitChanges(This,OperationSet) ((This)->lpVtbl->CommitChanges(This,OperationSet))
|
||||
|
||||
// IXAudio2Voice
|
||||
#define IXAudio2Voice_GetVoiceDetails(This,pVoiceDetails) ((This)->lpVtbl->GetVoiceDetails(This,pVoiceDetails))
|
||||
#define IXAudio2Voice_SetOutputVoices(This,pSendList) ((This)->lpVtbl->SetOutputVoices(This,pSendList))
|
||||
#define IXAudio2Voice_SetEffectChain(This,pEffectChain) ((This)->lpVtbl->SetEffectChain(This,pEffectChain))
|
||||
#define IXAudio2Voice_EnableEffect(This,EffectIndex,OperationSet) ((This)->lpVtbl->EnableEffect(This,EffectIndex,OperationSet))
|
||||
#define IXAudio2Voice_DisableEffect(This,EffectIndex,OperationSet) ((This)->lpVtbl->DisableEffect(This,EffectIndex,OperationSet))
|
||||
#define IXAudio2Voice_GetEffectState(This,EffectIndex,pEnabled) ((This)->lpVtbl->GetEffectState(This,EffectIndex,pEnabled))
|
||||
#define IXAudio2Voice_SetEffectParameters(This,EffectIndex,pParameters,ParametersByteSize, OperationSet) ((This)->lpVtbl->SetEffectParameters(This,EffectIndex,pParameters,ParametersByteSize,OperationSet))
|
||||
#define IXAudio2Voice_GetEffectParameters(This,EffectIndex,pParameters,ParametersByteSize) ((This)->lpVtbl->GetEffectParameters(This,EffectIndex,pParameters,ParametersByteSize))
|
||||
#define IXAudio2Voice_SetFilterParameters(This,pParameters,OperationSet) ((This)->lpVtbl->SetFilterParameters(This,pParameters,OperationSet))
|
||||
#define IXAudio2Voice_GetFilterParameters(This,pParameters) ((This)->lpVtbl->GetFilterParameters(This,pParameters))
|
||||
#define IXAudio2Voice_SetOutputFilterParameters(This,pDestinationVoice,pParameters,OperationSet) ((This)->lpVtbl->SetOutputFilterParameters(This,pDestinationVoice,pParameters,OperationSet))
|
||||
#define IXAudio2Voice_GetOutputFilterParameters(This,pDestinationVoice,pParameters) ((This)->lpVtbl->GetOutputFilterParameters(This,pDestinationVoice,pParameters))
|
||||
#define IXAudio2Voice_SetVolume(This,Volume,OperationSet) ((This)->lpVtbl->SetVolume(This,Volume,OperationSet))
|
||||
#define IXAudio2Voice_GetVolume(This,pVolume) ((This)->lpVtbl->GetVolume(This,pVolume))
|
||||
#define IXAudio2Voice_SetChannelVolumes(This,Channels,pVolumes,OperationSet) ((This)->lpVtbl->SetChannelVolumes(This,Channels,pVolumes,OperationSet))
|
||||
#define IXAudio2Voice_GetChannelVolumes(This,Channels,pVolumes) ((This)->lpVtbl->GetChannelVolumes(This,Channels,pVolumes))
|
||||
#define IXAudio2Voice_SetOutputMatrix(This,pDestinationVoice,SourceChannels,DestinationChannels,pLevelMatrix,OperationSet) ((This)->lpVtbl->SetOutputMatrix(This,pDestinationVoice,SourceChannels,DestinationChannels,pLevelMatrix,OperationSet))
|
||||
#define IXAudio2Voice_GetOutputMatrix(This,pDestinationVoice,SourceChannels,DestinationChannels,pLevelMatrix) ((This)->lpVtbl->GetOutputMatrix(This,pDestinationVoice,SourceChannels,DestinationChannels,pLevelMatrix))
|
||||
#define IXAudio2Voice_DestroyVoice(This) ((This)->lpVtbl->DestroyVoice(This))
|
||||
|
||||
// IXAudio2SourceVoice
|
||||
#define IXAudio2SourceVoice_GetVoiceDetails IXAudio2Voice_GetVoiceDetails
|
||||
#define IXAudio2SourceVoice_SetOutputVoices IXAudio2Voice_SetOutputVoices
|
||||
#define IXAudio2SourceVoice_SetEffectChain IXAudio2Voice_SetEffectChain
|
||||
#define IXAudio2SourceVoice_EnableEffect IXAudio2Voice_EnableEffect
|
||||
#define IXAudio2SourceVoice_DisableEffect IXAudio2Voice_DisableEffect
|
||||
#define IXAudio2SourceVoice_GetEffectState IXAudio2Voice_GetEffectState
|
||||
#define IXAudio2SourceVoice_SetEffectParameters IXAudio2Voice_SetEffectParameters
|
||||
#define IXAudio2SourceVoice_GetEffectParameters IXAudio2Voice_GetEffectParameters
|
||||
#define IXAudio2SourceVoice_SetFilterParameters IXAudio2Voice_SetFilterParameters
|
||||
#define IXAudio2SourceVoice_GetFilterParameters IXAudio2Voice_GetFilterParameters
|
||||
#define IXAudio2SourceVoice_SetOutputFilterParameters IXAudio2Voice_SetOutputFilterParameters
|
||||
#define IXAudio2SourceVoice_GetOutputFilterParameters IXAudio2Voice_GetOutputFilterParameters
|
||||
#define IXAudio2SourceVoice_SetVolume IXAudio2Voice_SetVolume
|
||||
#define IXAudio2SourceVoice_GetVolume IXAudio2Voice_GetVolume
|
||||
#define IXAudio2SourceVoice_SetChannelVolumes IXAudio2Voice_SetChannelVolumes
|
||||
#define IXAudio2SourceVoice_GetChannelVolumes IXAudio2Voice_GetChannelVolumes
|
||||
#define IXAudio2SourceVoice_SetOutputMatrix IXAudio2Voice_SetOutputMatrix
|
||||
#define IXAudio2SourceVoice_GetOutputMatrix IXAudio2Voice_GetOutputMatrix
|
||||
#define IXAudio2SourceVoice_DestroyVoice IXAudio2Voice_DestroyVoice
|
||||
#define IXAudio2SourceVoice_Start(This,Flags,OperationSet) ((This)->lpVtbl->Start(This,Flags,OperationSet))
|
||||
#define IXAudio2SourceVoice_Stop(This,Flags,OperationSet) ((This)->lpVtbl->Stop(This,Flags,OperationSet))
|
||||
#define IXAudio2SourceVoice_SubmitSourceBuffer(This,pBuffer,pBufferWMA) ((This)->lpVtbl->SubmitSourceBuffer(This,pBuffer,pBufferWMA))
|
||||
#define IXAudio2SourceVoice_FlushSourceBuffers(This) ((This)->lpVtbl->FlushSourceBuffers(This))
|
||||
#define IXAudio2SourceVoice_Discontinuity(This) ((This)->lpVtbl->Discontinuity(This))
|
||||
#define IXAudio2SourceVoice_ExitLoop(This,OperationSet) ((This)->lpVtbl->ExitLoop(This,OperationSet))
|
||||
#define IXAudio2SourceVoice_GetState(This,pVoiceState) ((This)->lpVtbl->GetState(This,pVoiceState))
|
||||
#define IXAudio2SourceVoice_SetFrequencyRatio(This,Ratio,OperationSet) ((This)->lpVtbl->SetFrequencyRatio(This,Ratio,OperationSet))
|
||||
#define IXAudio2SourceVoice_GetFrequencyRatio(This,pRatio) ((This)->lpVtbl->GetFrequencyRatio(This,pRatio))
|
||||
#define IXAudio2SourceVoice_SetSourceSampleRate(This,NewSourceSampleRate) ((This)->lpVtbl->SetSourceSampleRate(This,NewSourceSampleRate))
|
||||
|
||||
// IXAudio2SubmixVoice
|
||||
#define IXAudio2SubmixVoice_GetVoiceDetails IXAudio2Voice_GetVoiceDetails
|
||||
#define IXAudio2SubmixVoice_SetOutputVoices IXAudio2Voice_SetOutputVoices
|
||||
#define IXAudio2SubmixVoice_SetEffectChain IXAudio2Voice_SetEffectChain
|
||||
#define IXAudio2SubmixVoice_EnableEffect IXAudio2Voice_EnableEffect
|
||||
#define IXAudio2SubmixVoice_DisableEffect IXAudio2Voice_DisableEffect
|
||||
#define IXAudio2SubmixVoice_GetEffectState IXAudio2Voice_GetEffectState
|
||||
#define IXAudio2SubmixVoice_SetEffectParameters IXAudio2Voice_SetEffectParameters
|
||||
#define IXAudio2SubmixVoice_GetEffectParameters IXAudio2Voice_GetEffectParameters
|
||||
#define IXAudio2SubmixVoice_SetFilterParameters IXAudio2Voice_SetFilterParameters
|
||||
#define IXAudio2SubmixVoice_GetFilterParameters IXAudio2Voice_GetFilterParameters
|
||||
#define IXAudio2SubmixVoice_SetOutputFilterParameters IXAudio2Voice_SetOutputFilterParameters
|
||||
#define IXAudio2SubmixVoice_GetOutputFilterParameters IXAudio2Voice_GetOutputFilterParameters
|
||||
#define IXAudio2SubmixVoice_SetVolume IXAudio2Voice_SetVolume
|
||||
#define IXAudio2SubmixVoice_GetVolume IXAudio2Voice_GetVolume
|
||||
#define IXAudio2SubmixVoice_SetChannelVolumes IXAudio2Voice_SetChannelVolumes
|
||||
#define IXAudio2SubmixVoice_GetChannelVolumes IXAudio2Voice_GetChannelVolumes
|
||||
#define IXAudio2SubmixVoice_SetOutputMatrix IXAudio2Voice_SetOutputMatrix
|
||||
#define IXAudio2SubmixVoice_GetOutputMatrix IXAudio2Voice_GetOutputMatrix
|
||||
#define IXAudio2SubmixVoice_DestroyVoice IXAudio2Voice_DestroyVoice
|
||||
|
||||
// IXAudio2MasteringVoice
|
||||
#define IXAudio2MasteringVoice_GetVoiceDetails IXAudio2Voice_GetVoiceDetails
|
||||
#define IXAudio2MasteringVoice_SetOutputVoices IXAudio2Voice_SetOutputVoices
|
||||
#define IXAudio2MasteringVoice_SetEffectChain IXAudio2Voice_SetEffectChain
|
||||
#define IXAudio2MasteringVoice_EnableEffect IXAudio2Voice_EnableEffect
|
||||
#define IXAudio2MasteringVoice_DisableEffect IXAudio2Voice_DisableEffect
|
||||
#define IXAudio2MasteringVoice_GetEffectState IXAudio2Voice_GetEffectState
|
||||
#define IXAudio2MasteringVoice_SetEffectParameters IXAudio2Voice_SetEffectParameters
|
||||
#define IXAudio2MasteringVoice_GetEffectParameters IXAudio2Voice_GetEffectParameters
|
||||
#define IXAudio2MasteringVoice_SetFilterParameters IXAudio2Voice_SetFilterParameters
|
||||
#define IXAudio2MasteringVoice_GetFilterParameters IXAudio2Voice_GetFilterParameters
|
||||
#define IXAudio2MasteringVoice_SetOutputFilterParameters IXAudio2Voice_SetOutputFilterParameters
|
||||
#define IXAudio2MasteringVoice_GetOutputFilterParameters IXAudio2Voice_GetOutputFilterParameters
|
||||
#define IXAudio2MasteringVoice_SetVolume IXAudio2Voice_SetVolume
|
||||
#define IXAudio2MasteringVoice_GetVolume IXAudio2Voice_GetVolume
|
||||
#define IXAudio2MasteringVoice_SetChannelVolumes IXAudio2Voice_SetChannelVolumes
|
||||
#define IXAudio2MasteringVoice_GetChannelVolumes IXAudio2Voice_GetChannelVolumes
|
||||
#define IXAudio2MasteringVoice_SetOutputMatrix IXAudio2Voice_SetOutputMatrix
|
||||
#define IXAudio2MasteringVoice_GetOutputMatrix IXAudio2Voice_GetOutputMatrix
|
||||
#define IXAudio2MasteringVoice_DestroyVoice IXAudio2Voice_DestroyVoice
|
||||
|
||||
STDAPI XAudio2Create(__deref_out IXAudio2** ppXAudio2, UINT32 Flags X2DEFAULT(0),
|
||||
XAUDIO2_PROCESSOR XAudio2Processor X2DEFAULT(XAUDIO2_DEFAULT_PROCESSOR));
|
||||
|
||||
|
||||
// Undo the #pragma pack(push, 1) directive at the top of this file
|
||||
#pragma pack(pop)
|
||||
|
||||
#endif // #ifndef GUID_DEFS_ONLY
|
||||
|
||||
#endif
|
||||
|
||||
@@ -0,0 +1,226 @@
|
||||
/* RetroArch - A frontend for libretro.
|
||||
* Copyright (C) 2010-2012 - Hans-Kristian Arntzen
|
||||
*
|
||||
* RetroArch is free software: you can redistribute it and/or modify it under the terms
|
||||
* of the GNU General Public License as published by the Free Software Found-
|
||||
* ation, either version 3 of the License, or (at your option) any later version.
|
||||
*
|
||||
* RetroArch is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
|
||||
* without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
|
||||
* PURPOSE. See the GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along with RetroArch.
|
||||
* If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include "../driver.h"
|
||||
#include <stdlib.h>
|
||||
#include <xtl.h>
|
||||
#include "xaudio-c/xaudio.h"
|
||||
#include "../general.h"
|
||||
|
||||
#define MAX_BUFFERS 16
|
||||
#define MAX_BUFFERS_MASK 15
|
||||
|
||||
struct XAudio : public IXAudio2VoiceCallback
|
||||
{
|
||||
XAudio() :
|
||||
buf(0), pXAudio2(0), pMasteringVoice(0),
|
||||
pSourceVoice(0), nonblock(false), bufsize(0),
|
||||
bufptr(0), write_buffer(0), buffers(0), hEvent(0)
|
||||
{}
|
||||
|
||||
~XAudio()
|
||||
{
|
||||
if (pSourceVoice)
|
||||
{
|
||||
pSourceVoice->Stop(0, XAUDIO2_COMMIT_NOW);
|
||||
pSourceVoice->DestroyVoice();
|
||||
}
|
||||
|
||||
if (pMasteringVoice)
|
||||
pMasteringVoice->DestroyVoice();
|
||||
|
||||
if (pXAudio2)
|
||||
pXAudio2->Release();
|
||||
|
||||
if (hEvent)
|
||||
CloseHandle(hEvent);
|
||||
|
||||
free(buf);
|
||||
}
|
||||
|
||||
bool init(unsigned rate, unsigned latency)
|
||||
{
|
||||
size_t bufsize_ = latency * rate / 1000;
|
||||
size_t size = bufsize_ * 2 * sizeof(int16_t);
|
||||
|
||||
RARCH_LOG("XAudio2: Requesting %d ms latency, using %d ms latency.\n", latency, (int)bufsize_ * 1000 / rate);
|
||||
|
||||
if (FAILED(XAudio2Create(&pXAudio2, 0, XAUDIO2_DEFAULT_PROCESSOR)))
|
||||
return false;
|
||||
|
||||
if (FAILED(pXAudio2->CreateMasteringVoice(&pMasteringVoice, 2, rate, 0, 0, NULL)))
|
||||
return false;
|
||||
|
||||
WAVEFORMATEX wfx = {0};
|
||||
wfx.wFormatTag = WAVE_FORMAT_PCM;
|
||||
wfx.nChannels = 2;
|
||||
wfx.nSamplesPerSec = rate;
|
||||
wfx.nBlockAlign = 2 * sizeof(int16_t);
|
||||
wfx.wBitsPerSample = sizeof(int16_t) * 8;
|
||||
wfx.nAvgBytesPerSec = wfx.nSamplesPerSec * wfx.nBlockAlign;
|
||||
wfx.cbSize = 0;
|
||||
|
||||
if (FAILED(pXAudio2->CreateSourceVoice(&pSourceVoice, &wfx,
|
||||
XAUDIO2_VOICE_NOSRC, XAUDIO2_DEFAULT_FREQ_RATIO, this, 0, 0)))
|
||||
return false;
|
||||
|
||||
hEvent = CreateEvent(0, FALSE, FALSE, 0);
|
||||
|
||||
bufsize = size / MAX_BUFFERS;
|
||||
buf = (uint8_t*)malloc(bufsize * MAX_BUFFERS);
|
||||
memset(buf, 0, bufsize * MAX_BUFFERS);
|
||||
|
||||
if (FAILED(pSourceVoice->Start(0, XAUDIO2_COMMIT_NOW)))
|
||||
return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
// It's really 16-bit, but we have to byteswap.
|
||||
size_t write(const uint8_t *buffer, size_t size)
|
||||
{
|
||||
if (nonblock)
|
||||
{
|
||||
size_t avail = bufsize * (MAX_BUFFERS - buffers - 1);
|
||||
if (avail == 0)
|
||||
return 0;
|
||||
if (avail < size)
|
||||
size = avail;
|
||||
}
|
||||
|
||||
unsigned bytes = size;
|
||||
while (bytes)
|
||||
{
|
||||
unsigned need = min(bytes, bufsize - bufptr);
|
||||
uint8_t *base_write = buf + write_buffer * bufsize + bufptr;
|
||||
memcpy(base_write, buffer, need);
|
||||
|
||||
bufptr += need;
|
||||
buffer += need;
|
||||
bytes -= need;
|
||||
|
||||
if (bufptr == bufsize)
|
||||
{
|
||||
while (buffers == MAX_BUFFERS - 1)
|
||||
WaitForSingleObject(hEvent, INFINITE);
|
||||
|
||||
XAUDIO2_BUFFER xa2buffer = {0};
|
||||
xa2buffer.AudioBytes = bufsize;
|
||||
xa2buffer.pAudioData = buf + write_buffer * bufsize;
|
||||
|
||||
if (FAILED(pSourceVoice->SubmitSourceBuffer(&xa2buffer, NULL)))
|
||||
return 0;
|
||||
|
||||
InterlockedIncrement(&buffers);
|
||||
bufptr = 0;
|
||||
write_buffer = (write_buffer + 1) & MAX_BUFFERS_MASK;
|
||||
}
|
||||
}
|
||||
|
||||
return size;
|
||||
}
|
||||
|
||||
STDMETHOD_(void, OnBufferStart) (void *) {}
|
||||
STDMETHOD_(void, OnBufferEnd) (void *)
|
||||
{
|
||||
InterlockedDecrement(&buffers);
|
||||
SetEvent(hEvent);
|
||||
}
|
||||
STDMETHOD_(void, OnLoopEnd) (void *) {}
|
||||
STDMETHOD_(void, OnStreamEnd) () {}
|
||||
STDMETHOD_(void, OnVoiceError) (void *, HRESULT) {}
|
||||
STDMETHOD_(void, OnVoiceProcessingPassEnd) () {}
|
||||
STDMETHOD_(void, OnVoiceProcessingPassStart) (UINT32) {}
|
||||
|
||||
uint8_t *buf;
|
||||
IXAudio2 *pXAudio2;
|
||||
IXAudio2MasteringVoice *pMasteringVoice;
|
||||
IXAudio2SourceVoice *pSourceVoice;
|
||||
bool nonblock;
|
||||
unsigned bufsize;
|
||||
unsigned bufptr;
|
||||
unsigned write_buffer;
|
||||
volatile long buffers;
|
||||
HANDLE hEvent;
|
||||
};
|
||||
|
||||
static void *xa_init(const char *device, unsigned rate, unsigned latency)
|
||||
{
|
||||
if (latency < 8)
|
||||
latency = 8; // Do not allow shenanigans.
|
||||
|
||||
XAudio *xa = new XAudio;
|
||||
if (!xa->init(rate, latency))
|
||||
goto error;
|
||||
|
||||
return xa;
|
||||
|
||||
error:
|
||||
RARCH_ERR("Failed to init XAudio2.\n");
|
||||
delete xa;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static ssize_t xa_write(void *data, const void *buf, size_t size)
|
||||
{
|
||||
XAudio *xa = (XAudio*)data;
|
||||
size_t ret = xa->write((const uint8_t*)buf, size);
|
||||
|
||||
if (ret == 0 && !xa->nonblock)
|
||||
return -1;
|
||||
return ret;
|
||||
}
|
||||
|
||||
static bool xa_stop(void *data)
|
||||
{
|
||||
(void)data;
|
||||
return true;
|
||||
}
|
||||
|
||||
static void xa_set_nonblock_state(void *data, bool state)
|
||||
{
|
||||
XAudio *xa = (XAudio*)data;
|
||||
xa->nonblock = state;
|
||||
}
|
||||
|
||||
static bool xa_start(void *data)
|
||||
{
|
||||
(void)data;
|
||||
return true;
|
||||
}
|
||||
|
||||
static void xa_free(void *data)
|
||||
{
|
||||
XAudio *xa = (XAudio*)data;
|
||||
if (xa)
|
||||
delete xa;
|
||||
}
|
||||
|
||||
static bool xa_use_float(void *data)
|
||||
{
|
||||
(void)data;
|
||||
return false;
|
||||
}
|
||||
|
||||
const audio_driver_t audio_xdk360 = {
|
||||
xa_init,
|
||||
xa_write,
|
||||
xa_stop,
|
||||
xa_start,
|
||||
xa_set_nonblock_state,
|
||||
xa_free,
|
||||
xa_use_float,
|
||||
"xdk360"
|
||||
};
|
||||
@@ -0,0 +1,205 @@
|
||||
/* RetroArch - A frontend for libretro.
|
||||
* Copyright (C) 2010-2012 - Hans-Kristian Arntzen
|
||||
* Copyright (C) 2011-2012 - Daniel De Matteis
|
||||
*
|
||||
* RetroArch is free software: you can redistribute it and/or modify it under the terms
|
||||
* of the GNU General Public License as published by the Free Software Found-
|
||||
* ation, either version 3 of the License, or (at your option) any later version.
|
||||
*
|
||||
* RetroArch is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
|
||||
* without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
|
||||
* PURPOSE. See the GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along with RetroArch.
|
||||
* If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include <stdint.h>
|
||||
#include <stdlib.h>
|
||||
#include <xtl.h>
|
||||
#include "../driver.h"
|
||||
#include "../general.h"
|
||||
#include "../libretro.h"
|
||||
#include "../console/console_ext.h"
|
||||
#include "xdk360_input.h"
|
||||
#include "menu.h"
|
||||
|
||||
static uint64_t state[4];
|
||||
static unsigned pads_connected;
|
||||
|
||||
static void xdk360_input_poll(void *data)
|
||||
{
|
||||
(void)data;
|
||||
|
||||
pads_connected = 0;
|
||||
|
||||
for (unsigned i = 0; i < 4; i++)
|
||||
{
|
||||
XINPUT_STATE state_tmp;
|
||||
unsigned long retval = XInputGetState(i, &state_tmp);
|
||||
pads_connected += (retval == ERROR_DEVICE_NOT_CONNECTED) ? 0 : 1;
|
||||
state[i] = state_tmp.Gamepad.wButtons;
|
||||
state[i] |= ((state_tmp.Gamepad.sThumbLX < -DEADZONE)) << 16;
|
||||
state[i] |= ((state_tmp.Gamepad.sThumbLX > DEADZONE)) << 17;
|
||||
state[i] |= ((state_tmp.Gamepad.sThumbLY > DEADZONE)) << 18;
|
||||
state[i] |= ((state_tmp.Gamepad.sThumbLY < -DEADZONE)) << 19;
|
||||
state[i] |= ((state_tmp.Gamepad.sThumbRX < -DEADZONE)) << 20;
|
||||
state[i] |= ((state_tmp.Gamepad.sThumbRX > DEADZONE)) << 21;
|
||||
state[i] |= ((state_tmp.Gamepad.sThumbRY > DEADZONE)) << 22;
|
||||
state[i] |= ((state_tmp.Gamepad.sThumbRY < -DEADZONE)) << 23;
|
||||
state[i] |= ((state_tmp.Gamepad.bLeftTrigger > 128 ? 1 : 0)) << 24;
|
||||
state[i] |= ((state_tmp.Gamepad.bRightTrigger > 128 ? 1 : 0)) << 25;
|
||||
}
|
||||
}
|
||||
|
||||
static int16_t xdk360_input_state(void *data, const struct snes_keybind **binds,
|
||||
unsigned port, unsigned device,
|
||||
unsigned index, unsigned id)
|
||||
{
|
||||
(void)data;
|
||||
unsigned player = port;
|
||||
uint64_t button = binds[player][id].joykey;
|
||||
|
||||
return (state[player] & button) ? 1 : 0;
|
||||
}
|
||||
|
||||
static void xdk360_free_input(void *data)
|
||||
{
|
||||
(void)data;
|
||||
}
|
||||
|
||||
static void* xdk360_input_initialize(void)
|
||||
{
|
||||
for(unsigned i = 0; i < 4; i++)
|
||||
xdk360_input_map_dpad_to_stick(g_settings.input.dpad_emulation[i], i);
|
||||
return (void*)-1;
|
||||
}
|
||||
|
||||
void xdk360_input_map_dpad_to_stick(uint32_t map_dpad_enum, uint32_t controller_id)
|
||||
{
|
||||
switch(map_dpad_enum)
|
||||
{
|
||||
case DPAD_EMULATION_NONE:
|
||||
g_settings.input.binds[controller_id][RETRO_DEVICE_ID_JOYPAD_UP].joykey = platform_keys[XDK360_DEVICE_ID_JOYPAD_UP].joykey;
|
||||
g_settings.input.binds[controller_id][RETRO_DEVICE_ID_JOYPAD_DOWN].joykey = platform_keys[XDK360_DEVICE_ID_JOYPAD_DOWN].joykey;
|
||||
g_settings.input.binds[controller_id][RETRO_DEVICE_ID_JOYPAD_LEFT].joykey = platform_keys[XDK360_DEVICE_ID_JOYPAD_LEFT].joykey;
|
||||
g_settings.input.binds[controller_id][RETRO_DEVICE_ID_JOYPAD_RIGHT].joykey = platform_keys[XDK360_DEVICE_ID_JOYPAD_RIGHT].joykey;
|
||||
break;
|
||||
case DPAD_EMULATION_LSTICK:
|
||||
g_settings.input.binds[controller_id][RETRO_DEVICE_ID_JOYPAD_UP].joykey = platform_keys[XDK360_DEVICE_ID_LSTICK_UP_DPAD].joykey;
|
||||
g_settings.input.binds[controller_id][RETRO_DEVICE_ID_JOYPAD_DOWN].joykey = platform_keys[XDK360_DEVICE_ID_LSTICK_DOWN_DPAD].joykey;
|
||||
g_settings.input.binds[controller_id][RETRO_DEVICE_ID_JOYPAD_LEFT].joykey = platform_keys[XDK360_DEVICE_ID_LSTICK_LEFT_DPAD].joykey;
|
||||
g_settings.input.binds[controller_id][RETRO_DEVICE_ID_JOYPAD_RIGHT].joykey = platform_keys[XDK360_DEVICE_ID_LSTICK_RIGHT_DPAD].joykey;
|
||||
break;
|
||||
case DPAD_EMULATION_RSTICK:
|
||||
g_settings.input.binds[controller_id][RETRO_DEVICE_ID_JOYPAD_UP].joykey = platform_keys[XDK360_DEVICE_ID_RSTICK_UP_DPAD].joykey;
|
||||
g_settings.input.binds[controller_id][RETRO_DEVICE_ID_JOYPAD_DOWN].joykey = platform_keys[XDK360_DEVICE_ID_RSTICK_DOWN_DPAD].joykey;
|
||||
g_settings.input.binds[controller_id][RETRO_DEVICE_ID_JOYPAD_LEFT].joykey = platform_keys[XDK360_DEVICE_ID_RSTICK_LEFT_DPAD].joykey;
|
||||
g_settings.input.binds[controller_id][RETRO_DEVICE_ID_JOYPAD_RIGHT].joykey = platform_keys[XDK360_DEVICE_ID_RSTICK_RIGHT_DPAD].joykey;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void xdk360_input_loop(void)
|
||||
{
|
||||
XINPUT_STATE state;
|
||||
|
||||
XInputGetState(0, &state);
|
||||
|
||||
if(state.Gamepad.wButtons & XINPUT_GAMEPAD_DPAD_LEFT || state.Gamepad.sThumbLX < -DEADZONE)
|
||||
g_console.viewports.custom_vp.x -= 1;
|
||||
else if (state.Gamepad.wButtons & XINPUT_GAMEPAD_DPAD_RIGHT || state.Gamepad.sThumbLX > DEADZONE)
|
||||
g_console.viewports.custom_vp.x += 1;
|
||||
|
||||
if (state.Gamepad.wButtons & XINPUT_GAMEPAD_DPAD_UP || state.Gamepad.sThumbLY > DEADZONE)
|
||||
g_console.viewports.custom_vp.y += 1;
|
||||
else if (state.Gamepad.wButtons & XINPUT_GAMEPAD_DPAD_DOWN || state.Gamepad.sThumbLY < -DEADZONE)
|
||||
g_console.viewports.custom_vp.y -= 1;
|
||||
|
||||
if (state.Gamepad.sThumbRX < -DEADZONE || state.Gamepad.wButtons & XINPUT_GAMEPAD_LEFT_THUMB)
|
||||
g_console.viewports.custom_vp.width -= 1;
|
||||
else if (state.Gamepad.sThumbRX > DEADZONE || state.Gamepad.wButtons & XINPUT_GAMEPAD_RIGHT_THUMB)
|
||||
g_console.viewports.custom_vp.width += 1;
|
||||
|
||||
if (state.Gamepad.sThumbRY > DEADZONE || state.Gamepad.wButtons & XINPUT_GAMEPAD_LEFT_SHOULDER)
|
||||
g_console.viewports.custom_vp.height += 1;
|
||||
else if (state.Gamepad.sThumbRY < -DEADZONE || state.Gamepad.wButtons & XINPUT_GAMEPAD_RIGHT_SHOULDER)
|
||||
g_console.viewports.custom_vp.height -= 1;
|
||||
|
||||
if (state.Gamepad.wButtons & XINPUT_GAMEPAD_Y)
|
||||
{
|
||||
g_console.viewports.custom_vp.x = 0;
|
||||
g_console.viewports.custom_vp.y = 0;
|
||||
g_console.viewports.custom_vp.width = 1280; //FIXME: hardcoded
|
||||
g_console.viewports.custom_vp.height = 720; //FIXME: hardcoded
|
||||
}
|
||||
if(state.Gamepad.wButtons & XINPUT_GAMEPAD_B)
|
||||
{
|
||||
g_console.input_loop = INPUT_LOOP_MENU;
|
||||
}
|
||||
}
|
||||
|
||||
static bool xdk360_key_pressed(void *data, int key)
|
||||
{
|
||||
(void)data;
|
||||
XINPUT_STATE state;
|
||||
bool retval;
|
||||
xdk360_video_t *d3d9 = (xdk360_video_t*)driver.video_data;
|
||||
|
||||
XInputGetState(0, &state);
|
||||
retval = false;
|
||||
|
||||
switch(key)
|
||||
{
|
||||
case RARCH_FAST_FORWARD_HOLD_KEY:
|
||||
return ((state.Gamepad.sThumbRY < -DEADZONE) && !(state.Gamepad.bRightTrigger > 128));
|
||||
case RARCH_LOAD_STATE_KEY:
|
||||
return ((state.Gamepad.sThumbRY > DEADZONE) && (state.Gamepad.bRightTrigger > 128));
|
||||
case RARCH_SAVE_STATE_KEY:
|
||||
return ((state.Gamepad.sThumbRY < -DEADZONE) && (state.Gamepad.bRightTrigger > 128));
|
||||
case RARCH_STATE_SLOT_PLUS:
|
||||
return ((state.Gamepad.sThumbRX > DEADZONE) && (state.Gamepad.bRightTrigger > 128));
|
||||
case RARCH_STATE_SLOT_MINUS:
|
||||
return ((state.Gamepad.sThumbRX < -DEADZONE) && (state.Gamepad.bRightTrigger > 128));
|
||||
case RARCH_FRAMEADVANCE:
|
||||
if(g_console.frame_advance_enable)
|
||||
{
|
||||
g_console.menu_enable = true;
|
||||
g_console.ingame_menu_enable = true;
|
||||
g_console.mode_switch = MODE_MENU;
|
||||
}
|
||||
return false;
|
||||
case RARCH_REWIND:
|
||||
return ((state.Gamepad.sThumbRY > DEADZONE) && !(state.Gamepad.bRightTrigger > 128));
|
||||
case RARCH_QUIT_KEY:
|
||||
if(IS_TIMER_EXPIRED(d3d9))
|
||||
{
|
||||
uint32_t left_thumb_pressed = (state.Gamepad.wButtons & XINPUT_GAMEPAD_LEFT_THUMB);
|
||||
uint32_t right_thumb_pressed = (state.Gamepad.wButtons & XINPUT_GAMEPAD_RIGHT_THUMB);
|
||||
|
||||
g_console.menu_enable = right_thumb_pressed && left_thumb_pressed && IS_TIMER_EXPIRED(d3d9);
|
||||
g_console.ingame_menu_enable = right_thumb_pressed && !left_thumb_pressed;
|
||||
|
||||
if(g_console.menu_enable || (g_console.ingame_menu_enable && !g_console.menu_enable))
|
||||
{
|
||||
g_console.mode_switch = MODE_MENU;
|
||||
SET_TIMER_EXPIRATION(d3d9, 30);
|
||||
retval = g_console.menu_enable;
|
||||
}
|
||||
|
||||
retval = g_console.ingame_menu_enable ? g_console.ingame_menu_enable : g_console.menu_enable;
|
||||
}
|
||||
}
|
||||
|
||||
return retval;
|
||||
}
|
||||
|
||||
const input_driver_t input_xdk360 =
|
||||
{
|
||||
xdk360_input_initialize,
|
||||
xdk360_input_poll,
|
||||
xdk360_input_state,
|
||||
xdk360_key_pressed,
|
||||
xdk360_free_input,
|
||||
"xdk360"
|
||||
};
|
||||
@@ -0,0 +1,35 @@
|
||||
/* RetroArch - A frontend for libretro.
|
||||
* Copyright (C) 2010-2012 - Hans-Kristian Arntzen
|
||||
* Copyright (C) 2011-2012 - Daniel De Matteis
|
||||
*
|
||||
* RetroArch is free software: you can redistribute it and/or modify it under the terms
|
||||
* of the GNU General Public License as published by the Free Software Found-
|
||||
* ation, either version 3 of the License, or (at your option) any later version.
|
||||
*
|
||||
* RetroArch is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
|
||||
* without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
|
||||
* PURPOSE. See the GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along with RetroArch.
|
||||
* If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifndef _XDK360_INPUT_H
|
||||
#define _XDK360_INPUT_H
|
||||
|
||||
#define XINPUT_GAMEPAD_LSTICK_LEFT_MASK (65536)
|
||||
#define XINPUT_GAMEPAD_LSTICK_RIGHT_MASK (131072)
|
||||
#define XINPUT_GAMEPAD_LSTICK_UP_MASK (262144)
|
||||
#define XINPUT_GAMEPAD_LSTICK_DOWN_MASK (524288)
|
||||
#define XINPUT_GAMEPAD_RSTICK_LEFT_MASK (1048576)
|
||||
#define XINPUT_GAMEPAD_RSTICK_RIGHT_MASK (2097152)
|
||||
#define XINPUT_GAMEPAD_RSTICK_UP_MASK (4194304)
|
||||
#define XINPUT_GAMEPAD_RSTICK_DOWN_MASK (8388608)
|
||||
#define XINPUT_GAMEPAD_LEFT_TRIGGER (16777216)
|
||||
#define XINPUT_GAMEPAD_RIGHT_TRIGGER (33554432)
|
||||
#define DEADZONE (16000)
|
||||
|
||||
extern void xdk360_input_map_dpad_to_stick(uint32_t map_dpad_enum, uint32_t controller_id);
|
||||
extern void xdk360_input_loop(void);
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,762 @@
|
||||
/* RetroArch - A frontend for libretro.
|
||||
* Copyright (C) 2010-2012 - Hans-Kristian Arntzen
|
||||
* Copyright (C) 2011-2012 - Daniel De Matteis
|
||||
*
|
||||
* RetroArch is free software: you can redistribute it and/or modify it under the terms
|
||||
* of the GNU General Public License as published by the Free Software Found-
|
||||
* ation, either version 3 of the License, or (at your option) any later version.
|
||||
*
|
||||
* RetroArch is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
|
||||
* without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
|
||||
* PURPOSE. See the GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along with RetroArch.
|
||||
* If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifdef _XBOX
|
||||
#include <xtl.h>
|
||||
#include <xgraphics.h>
|
||||
#endif
|
||||
|
||||
#include "../driver.h"
|
||||
#include "xdk360_video.h"
|
||||
#include "xdk360_video_resources.h"
|
||||
|
||||
#ifdef HAVE_HLSL
|
||||
#include "../gfx/shader_hlsl.h"
|
||||
#endif
|
||||
|
||||
#include "./../gfx/gfx_context.h"
|
||||
#include "../console/console_ext.h"
|
||||
#include "../general.h"
|
||||
#include "../message.h"
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
#include "config.h"
|
||||
#endif
|
||||
|
||||
/* Xbox 360 specific code */
|
||||
|
||||
const DWORD g_MapLinearToSrgbGpuFormat[] =
|
||||
{
|
||||
GPUTEXTUREFORMAT_1_REVERSE,
|
||||
GPUTEXTUREFORMAT_1,
|
||||
GPUTEXTUREFORMAT_8,
|
||||
GPUTEXTUREFORMAT_1_5_5_5,
|
||||
GPUTEXTUREFORMAT_5_6_5,
|
||||
GPUTEXTUREFORMAT_6_5_5,
|
||||
GPUTEXTUREFORMAT_8_8_8_8_AS_16_16_16_16,
|
||||
GPUTEXTUREFORMAT_2_10_10_10_AS_16_16_16_16,
|
||||
GPUTEXTUREFORMAT_8_A,
|
||||
GPUTEXTUREFORMAT_8_B,
|
||||
GPUTEXTUREFORMAT_8_8,
|
||||
GPUTEXTUREFORMAT_Cr_Y1_Cb_Y0_REP,
|
||||
GPUTEXTUREFORMAT_Y1_Cr_Y0_Cb_REP,
|
||||
GPUTEXTUREFORMAT_16_16_EDRAM,
|
||||
GPUTEXTUREFORMAT_8_8_8_8_A,
|
||||
GPUTEXTUREFORMAT_4_4_4_4,
|
||||
GPUTEXTUREFORMAT_10_11_11_AS_16_16_16_16,
|
||||
GPUTEXTUREFORMAT_11_11_10_AS_16_16_16_16,
|
||||
GPUTEXTUREFORMAT_DXT1_AS_16_16_16_16,
|
||||
GPUTEXTUREFORMAT_DXT2_3_AS_16_16_16_16,
|
||||
GPUTEXTUREFORMAT_DXT4_5_AS_16_16_16_16,
|
||||
GPUTEXTUREFORMAT_16_16_16_16_EDRAM,
|
||||
GPUTEXTUREFORMAT_24_8,
|
||||
GPUTEXTUREFORMAT_24_8_FLOAT,
|
||||
GPUTEXTUREFORMAT_16,
|
||||
GPUTEXTUREFORMAT_16_16,
|
||||
GPUTEXTUREFORMAT_16_16_16_16,
|
||||
GPUTEXTUREFORMAT_16_EXPAND,
|
||||
GPUTEXTUREFORMAT_16_16_EXPAND,
|
||||
GPUTEXTUREFORMAT_16_16_16_16_EXPAND,
|
||||
GPUTEXTUREFORMAT_16_FLOAT,
|
||||
GPUTEXTUREFORMAT_16_16_FLOAT,
|
||||
GPUTEXTUREFORMAT_16_16_16_16_FLOAT,
|
||||
GPUTEXTUREFORMAT_32,
|
||||
GPUTEXTUREFORMAT_32_32,
|
||||
GPUTEXTUREFORMAT_32_32_32_32,
|
||||
GPUTEXTUREFORMAT_32_FLOAT,
|
||||
GPUTEXTUREFORMAT_32_32_FLOAT,
|
||||
GPUTEXTUREFORMAT_32_32_32_32_FLOAT,
|
||||
GPUTEXTUREFORMAT_32_AS_8,
|
||||
GPUTEXTUREFORMAT_32_AS_8_8,
|
||||
GPUTEXTUREFORMAT_16_MPEG,
|
||||
GPUTEXTUREFORMAT_16_16_MPEG,
|
||||
GPUTEXTUREFORMAT_8_INTERLACED,
|
||||
GPUTEXTUREFORMAT_32_AS_8_INTERLACED,
|
||||
GPUTEXTUREFORMAT_32_AS_8_8_INTERLACED,
|
||||
GPUTEXTUREFORMAT_16_INTERLACED,
|
||||
GPUTEXTUREFORMAT_16_MPEG_INTERLACED,
|
||||
GPUTEXTUREFORMAT_16_16_MPEG_INTERLACED,
|
||||
GPUTEXTUREFORMAT_DXN,
|
||||
GPUTEXTUREFORMAT_8_8_8_8_AS_16_16_16_16,
|
||||
GPUTEXTUREFORMAT_DXT1_AS_16_16_16_16,
|
||||
GPUTEXTUREFORMAT_DXT2_3_AS_16_16_16_16,
|
||||
GPUTEXTUREFORMAT_DXT4_5_AS_16_16_16_16,
|
||||
GPUTEXTUREFORMAT_2_10_10_10_AS_16_16_16_16,
|
||||
GPUTEXTUREFORMAT_10_11_11_AS_16_16_16_16,
|
||||
GPUTEXTUREFORMAT_11_11_10_AS_16_16_16_16,
|
||||
GPUTEXTUREFORMAT_32_32_32_FLOAT,
|
||||
GPUTEXTUREFORMAT_DXT3A,
|
||||
GPUTEXTUREFORMAT_DXT5A,
|
||||
GPUTEXTUREFORMAT_CTX1,
|
||||
GPUTEXTUREFORMAT_DXT3A_AS_1_1_1_1,
|
||||
GPUTEXTUREFORMAT_8_8_8_8_GAMMA_EDRAM,
|
||||
GPUTEXTUREFORMAT_2_10_10_10_FLOAT_EDRAM,
|
||||
};
|
||||
|
||||
struct XPR_HEADER
|
||||
{
|
||||
unsigned long dwMagic;
|
||||
unsigned long dwHeaderSize;
|
||||
unsigned long dwDataSize;
|
||||
};
|
||||
|
||||
#define XPR2_MAGIC_VALUE (0x58505232)
|
||||
|
||||
PackedResource::PackedResource()
|
||||
{
|
||||
m_pSysMemData = NULL;
|
||||
m_dwSysMemDataSize = 0L;
|
||||
m_pVidMemData = NULL;
|
||||
m_dwVidMemDataSize = 0L;
|
||||
m_pResourceTags = NULL;
|
||||
m_dwNumResourceTags = 0L;
|
||||
m_bInitialized = FALSE;
|
||||
}
|
||||
|
||||
PackedResource::~PackedResource()
|
||||
{
|
||||
Destroy();
|
||||
}
|
||||
|
||||
void * PackedResource::GetData( const char * strName ) const
|
||||
{
|
||||
if( m_pResourceTags == NULL || strName == NULL )
|
||||
return NULL;
|
||||
|
||||
for( unsigned long i = 0; i < m_dwNumResourceTags; i++ )
|
||||
{
|
||||
if( !_stricmp( strName, m_pResourceTags[i].strName ) )
|
||||
return &m_pSysMemData[m_pResourceTags[i].dwOffset];
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
HRESULT PackedResource::Create( const char * strFilename )
|
||||
{
|
||||
unsigned long dwNumBytesRead;
|
||||
void * hFile = CreateFile( strFilename, GENERIC_READ, FILE_SHARE_READ, NULL,
|
||||
OPEN_EXISTING, FILE_ATTRIBUTE_READONLY, NULL );
|
||||
|
||||
if( hFile == INVALID_HANDLE_VALUE )
|
||||
{
|
||||
RARCH_ERR( "File <%s> not found.\n", strFilename );
|
||||
return E_FAIL;
|
||||
}
|
||||
|
||||
// Read in and verify the XPR magic header
|
||||
XPR_HEADER xprh;
|
||||
if( !ReadFile( hFile, &xprh, sizeof( XPR_HEADER ), &dwNumBytesRead, NULL ) )
|
||||
{
|
||||
RARCH_ERR( "Error reading XPR header in file <%s>.\n", strFilename );
|
||||
CloseHandle( hFile );
|
||||
return E_FAIL;
|
||||
}
|
||||
|
||||
if( xprh.dwMagic != XPR2_MAGIC_VALUE )
|
||||
{
|
||||
RARCH_ERR( "Invalid Xbox Packed Resource (.xpr) file: Magic = 0x%08lx.\n", xprh.dwMagic );
|
||||
CloseHandle( hFile );
|
||||
return E_FAIL;
|
||||
}
|
||||
|
||||
// Compute memory requirements
|
||||
m_dwSysMemDataSize = xprh.dwHeaderSize;
|
||||
m_dwVidMemDataSize = xprh.dwDataSize;
|
||||
|
||||
// Allocate memory
|
||||
m_pSysMemData = (unsigned char*)malloc(m_dwSysMemDataSize);
|
||||
if( m_pSysMemData == NULL )
|
||||
{
|
||||
RARCH_ERR( "Could not allocate system memory.\n" );
|
||||
m_dwSysMemDataSize = 0;
|
||||
return E_FAIL;
|
||||
}
|
||||
m_pVidMemData = ( unsigned char* )XMemAlloc( m_dwVidMemDataSize, MAKE_XALLOC_ATTRIBUTES( 0, 0, 0, 0, eXALLOCAllocatorId_GameMax,
|
||||
XALLOC_PHYSICAL_ALIGNMENT_4K, XALLOC_MEMPROTECT_WRITECOMBINE, 0, XALLOC_MEMTYPE_PHYSICAL ) );
|
||||
|
||||
if( m_pVidMemData == NULL )
|
||||
{
|
||||
RARCH_ERR( "Could not allocate physical memory.\n" );
|
||||
m_dwSysMemDataSize = 0;
|
||||
m_dwVidMemDataSize = 0;
|
||||
free(m_pSysMemData);
|
||||
m_pSysMemData = NULL;
|
||||
return E_FAIL;
|
||||
}
|
||||
|
||||
// Read in the data from the file
|
||||
if( !ReadFile( hFile, m_pSysMemData, m_dwSysMemDataSize, &dwNumBytesRead, NULL ) ||
|
||||
!ReadFile( hFile, m_pVidMemData, m_dwVidMemDataSize, &dwNumBytesRead, NULL ) )
|
||||
{
|
||||
RARCH_ERR( "Unable to read Xbox Packed Resource (.xpr) file.\n" );
|
||||
CloseHandle( hFile );
|
||||
return E_FAIL;
|
||||
}
|
||||
|
||||
// Done with the file
|
||||
CloseHandle( hFile );
|
||||
|
||||
// Extract resource table from the header data
|
||||
m_dwNumResourceTags = *( unsigned long * )( m_pSysMemData + 0 );
|
||||
m_pResourceTags = ( RESOURCE* )( m_pSysMemData + 4 );
|
||||
|
||||
// Patch up the resources
|
||||
for( unsigned long i = 0; i < m_dwNumResourceTags; i++ )
|
||||
{
|
||||
m_pResourceTags[i].strName = ( char * )( m_pSysMemData + ( unsigned long )m_pResourceTags[i].strName );
|
||||
|
||||
// Fixup the texture memory
|
||||
if( ( m_pResourceTags[i].dwType & 0xffff0000 ) == ( RESOURCETYPE_TEXTURE & 0xffff0000 ) )
|
||||
{
|
||||
D3DTexture* pTexture = ( D3DTexture* )&m_pSysMemData[m_pResourceTags[i].dwOffset];
|
||||
// Adjust Base address according to where memory was allocated
|
||||
XGOffsetBaseTextureAddress( pTexture, m_pVidMemData, m_pVidMemData );
|
||||
}
|
||||
}
|
||||
|
||||
m_bInitialized = TRUE;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
void PackedResource::Destroy()
|
||||
{
|
||||
free(m_pSysMemData);
|
||||
m_pSysMemData = NULL;
|
||||
m_dwSysMemDataSize = 0L;
|
||||
|
||||
if( m_pVidMemData != NULL )
|
||||
XMemFree( m_pVidMemData, MAKE_XALLOC_ATTRIBUTES( 0, 0, 0, 0, eXALLOCAllocatorId_GameMax,
|
||||
0, 0, 0, XALLOC_MEMTYPE_PHYSICAL ) );
|
||||
|
||||
m_pVidMemData = NULL;
|
||||
m_dwVidMemDataSize = 0L;
|
||||
|
||||
m_pResourceTags = NULL;
|
||||
m_dwNumResourceTags = 0L;
|
||||
|
||||
m_bInitialized = FALSE;
|
||||
}
|
||||
|
||||
/* end of Xbox 360 specific code */
|
||||
|
||||
static void check_window(xdk360_video_t *d3d9)
|
||||
{
|
||||
bool quit, resize;
|
||||
|
||||
gfx_ctx_check_window(&quit,
|
||||
&resize, NULL, NULL,
|
||||
d3d9->frame_count);
|
||||
|
||||
if (quit)
|
||||
d3d9->quitting = true;
|
||||
else if (resize)
|
||||
d3d9->should_resize = true;
|
||||
}
|
||||
|
||||
static void xdk360_free(void * data)
|
||||
{
|
||||
#ifdef RARCH_CONSOLE
|
||||
if (driver.video_data)
|
||||
return;
|
||||
#endif
|
||||
|
||||
xdk360_video_t *d3d9 = (xdk360_video_t*)data;
|
||||
|
||||
if (!d3d9)
|
||||
return;
|
||||
|
||||
#ifdef HAVE_HLSL
|
||||
hlsl_deinit();
|
||||
#endif
|
||||
d3d9->d3d_render_device->Release();
|
||||
d3d9->d3d_device->Release();
|
||||
|
||||
free(d3d9);
|
||||
}
|
||||
|
||||
static void xdk360_set_viewport(bool force_full)
|
||||
{
|
||||
xdk360_video_t *d3d9 = (xdk360_video_t*)driver.video_data;
|
||||
|
||||
d3d9->d3d_render_device->Clear(0, NULL, D3DCLEAR_TARGET,
|
||||
0xff000000, 1.0f, 0);
|
||||
|
||||
int width = d3d9->video_mode.fIsHiDef ? 1280 : 640;
|
||||
int height = d3d9->video_mode.fIsHiDef ? 720 : 480;
|
||||
int m_viewport_x_temp, m_viewport_y_temp, m_viewport_width_temp, m_viewport_height_temp;
|
||||
float m_zNear, m_zFar;
|
||||
|
||||
m_viewport_x_temp = 0;
|
||||
m_viewport_y_temp = 0;
|
||||
m_viewport_width_temp = width;
|
||||
m_viewport_height_temp = height;
|
||||
|
||||
m_zNear = 0.0f;
|
||||
m_zFar = 1.0f;
|
||||
|
||||
if (!force_full)
|
||||
{
|
||||
float desired_aspect = g_settings.video.aspect_ratio;
|
||||
float device_aspect = (float)width / height;
|
||||
float delta;
|
||||
|
||||
// If the aspect ratios of screen and desired aspect ratio are sufficiently equal (floating point stuff),
|
||||
if(g_console.aspect_ratio_index == ASPECT_RATIO_CUSTOM)
|
||||
{
|
||||
delta = (desired_aspect / device_aspect - 1.0) / 2.0 + 0.5;
|
||||
m_viewport_x_temp = g_console.viewports.custom_vp.x;
|
||||
m_viewport_y_temp = g_console.viewports.custom_vp.y;
|
||||
m_viewport_width_temp = g_console.viewports.custom_vp.width;
|
||||
m_viewport_height_temp = g_console.viewports.custom_vp.height;
|
||||
}
|
||||
else if (device_aspect > desired_aspect)
|
||||
{
|
||||
delta = (desired_aspect / device_aspect - 1.0) / 2.0 + 0.5;
|
||||
m_viewport_x_temp = (int)(width * (0.5 - delta));
|
||||
m_viewport_width_temp = (int)(2.0 * width * delta);
|
||||
width = (unsigned)(2.0 * width * delta);
|
||||
}
|
||||
else
|
||||
{
|
||||
delta = (device_aspect / desired_aspect - 1.0) / 2.0 + 0.5;
|
||||
m_viewport_y_temp = (int)(height * (0.5 - delta));
|
||||
m_viewport_height_temp = (int)(2.0 * height * delta);
|
||||
height = (unsigned)(2.0 * height * delta);
|
||||
}
|
||||
}
|
||||
|
||||
D3DVIEWPORT9 vp = {0};
|
||||
vp.Width = m_viewport_width_temp;
|
||||
vp.Height = m_viewport_height_temp;
|
||||
vp.X = m_viewport_x_temp;
|
||||
vp.Y = m_viewport_y_temp;
|
||||
vp.MinZ = m_zNear;
|
||||
vp.MaxZ = m_zFar;
|
||||
d3d9->d3d_render_device->SetViewport(&vp);
|
||||
|
||||
//if(gl->overscan_enable && !force_full)
|
||||
//{
|
||||
// m_left = -gl->overscan_amount/2;
|
||||
// m_right = 1 + gl->overscan_amount/2;
|
||||
// m_bottom = -gl->overscan_amount/2;
|
||||
//}
|
||||
}
|
||||
|
||||
static void xdk360_set_rotation(void * data, unsigned orientation)
|
||||
{
|
||||
(void)data;
|
||||
xdk360_video_t *d3d9 = (xdk360_video_t*)data;
|
||||
FLOAT angle;
|
||||
|
||||
switch(orientation)
|
||||
{
|
||||
case ORIENTATION_NORMAL:
|
||||
angle = M_PI * 0 / 180;
|
||||
break;
|
||||
case ORIENTATION_VERTICAL:
|
||||
angle = M_PI * 270 / 180;
|
||||
break;
|
||||
case ORIENTATION_FLIPPED:
|
||||
angle = M_PI * 180 / 180;
|
||||
break;
|
||||
case ORIENTATION_FLIPPED_ROTATED:
|
||||
angle = M_PI * 90 / 180;
|
||||
break;
|
||||
}
|
||||
|
||||
/* TODO: Move to D3DXMATRIX here */
|
||||
hlsl_set_proj_matrix(XMMatrixRotationZ(angle));
|
||||
|
||||
d3d9->should_resize = TRUE;
|
||||
}
|
||||
|
||||
static void xdk360_convert_texture_to_as16_srgb( D3DTexture *pTexture )
|
||||
{
|
||||
pTexture->Format.SignX = GPUSIGN_GAMMA;
|
||||
pTexture->Format.SignY = GPUSIGN_GAMMA;
|
||||
pTexture->Format.SignZ = GPUSIGN_GAMMA;
|
||||
|
||||
XGTEXTURE_DESC desc;
|
||||
XGGetTextureDesc( pTexture, 0, &desc );
|
||||
|
||||
//convert to AS_16_16_16_16 format
|
||||
pTexture->Format.DataFormat = g_MapLinearToSrgbGpuFormat[ (desc.Format & D3DFORMAT_TEXTUREFORMAT_MASK) >> D3DFORMAT_TEXTUREFORMAT_SHIFT ];
|
||||
}
|
||||
|
||||
static void xdk360_init_fbo(xdk360_video_t *d3d9)
|
||||
{
|
||||
if (d3d9->lpTexture_ot)
|
||||
{
|
||||
d3d9->lpTexture_ot->Release();
|
||||
d3d9->lpTexture_ot = NULL;
|
||||
}
|
||||
|
||||
if (d3d9->lpSurface)
|
||||
{
|
||||
d3d9->lpSurface->Release();
|
||||
d3d9->lpSurface = NULL;
|
||||
}
|
||||
|
||||
d3d9->d3d_render_device->CreateTexture(512 * g_settings.video.fbo_scale_x, 512 * g_settings.video.fbo_scale_y,
|
||||
1, 0, g_console.gamma_correction_enable ? ( D3DFORMAT )MAKESRGBFMT( D3DFMT_A8R8G8B8 ) : D3DFMT_A8R8G8B8,
|
||||
0, &d3d9->lpTexture_ot, NULL);
|
||||
|
||||
d3d9->d3d_render_device->CreateRenderTarget(512 * g_settings.video.fbo_scale_x, 512 * g_settings.video.fbo_scale_y,
|
||||
g_console.gamma_correction_enable ? ( D3DFORMAT )MAKESRGBFMT( D3DFMT_A8R8G8B8 ) : D3DFMT_A8R8G8B8, D3DMULTISAMPLE_NONE,
|
||||
0, 0, &d3d9->lpSurface, NULL);
|
||||
|
||||
d3d9->lpTexture_ot_as16srgb = *d3d9->lpTexture_ot;
|
||||
xdk360_convert_texture_to_as16_srgb(d3d9->lpTexture);
|
||||
xdk360_convert_texture_to_as16_srgb(&d3d9->lpTexture_ot_as16srgb);
|
||||
}
|
||||
|
||||
static void *xdk360_init(const video_info_t *video, const input_driver_t **input, void **input_data)
|
||||
{
|
||||
if (driver.video_data)
|
||||
return driver.video_data;
|
||||
|
||||
xdk360_video_t *d3d9 = (xdk360_video_t*)calloc(1, sizeof(xdk360_video_t));
|
||||
if (!d3d9)
|
||||
return NULL;
|
||||
|
||||
d3d9->d3d_device = Direct3DCreate9(D3D_SDK_VERSION);
|
||||
if (!d3d9->d3d_device)
|
||||
{
|
||||
free(d3d9);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
// Get video settings
|
||||
|
||||
memset(&d3d9->video_mode, 0, sizeof(d3d9->video_mode));
|
||||
|
||||
XGetVideoMode(&d3d9->video_mode);
|
||||
|
||||
memset(&d3d9->d3dpp, 0, sizeof(d3d9->d3dpp));
|
||||
|
||||
// no letterboxing in 4:3 mode (if widescreen is
|
||||
// unsupported
|
||||
if(!d3d9->video_mode.fIsWideScreen)
|
||||
d3d9->d3dpp.Flags |= D3DPRESENTFLAG_NO_LETTERBOX;
|
||||
|
||||
g_console.menus_hd_enable = d3d9->video_mode.fIsHiDef;
|
||||
|
||||
d3d9->d3dpp.BackBufferWidth = d3d9->video_mode.fIsHiDef ? 1280 : 640;
|
||||
d3d9->d3dpp.BackBufferHeight = d3d9->video_mode.fIsHiDef ? 720 : 480;
|
||||
|
||||
if(g_console.gamma_correction_enable)
|
||||
{
|
||||
d3d9->d3dpp.BackBufferFormat = g_console.color_format ? (D3DFORMAT)MAKESRGBFMT(D3DFMT_A8R8G8B8) : (D3DFORMAT)MAKESRGBFMT(D3DFMT_LIN_A1R5G5B5);
|
||||
d3d9->d3dpp.FrontBufferFormat = (D3DFORMAT)MAKESRGBFMT(D3DFMT_LE_X8R8G8B8);
|
||||
}
|
||||
else
|
||||
{
|
||||
d3d9->d3dpp.BackBufferFormat = g_console.color_format ? D3DFMT_A8R8G8B8 : D3DFMT_LIN_A1R5G5B5;
|
||||
d3d9->d3dpp.FrontBufferFormat = D3DFMT_LE_X8R8G8B8;
|
||||
}
|
||||
|
||||
d3d9->d3dpp.MultiSampleType = D3DMULTISAMPLE_NONE;
|
||||
d3d9->d3dpp.MultiSampleQuality = 0;
|
||||
d3d9->d3dpp.BackBufferCount = 2;
|
||||
d3d9->d3dpp.EnableAutoDepthStencil = FALSE;
|
||||
d3d9->d3dpp.SwapEffect = D3DSWAPEFFECT_DISCARD;
|
||||
d3d9->d3dpp.PresentationInterval = video->vsync ? D3DPRESENT_INTERVAL_ONE : D3DPRESENT_INTERVAL_IMMEDIATE;
|
||||
|
||||
// D3DCREATE_HARDWARE_VERTEXPROCESSING is ignored on 360
|
||||
d3d9->d3d_device->CreateDevice(0, D3DDEVTYPE_HAL, NULL, D3DCREATE_HARDWARE_VERTEXPROCESSING,
|
||||
&d3d9->d3dpp, &d3d9->d3d_render_device);
|
||||
|
||||
hlsl_init(g_settings.video.cg_shader_path, d3d9->d3d_render_device);
|
||||
|
||||
d3d9->d3d_render_device->CreateTexture(512, 512, 1, 0, D3DFMT_LIN_X1R5G5B5,
|
||||
0, &d3d9->lpTexture, NULL);
|
||||
|
||||
xdk360_init_fbo(d3d9);
|
||||
|
||||
D3DLOCKED_RECT d3dlr;
|
||||
d3d9->lpTexture->LockRect(0, &d3dlr, NULL, D3DLOCK_NOSYSLOCK);
|
||||
memset(d3dlr.pBits, 0, 512 * d3dlr.Pitch);
|
||||
d3d9->lpTexture->UnlockRect(0);
|
||||
|
||||
d3d9->last_width = 512;
|
||||
d3d9->last_height = 512;
|
||||
|
||||
d3d9->d3d_render_device->CreateVertexBuffer(4 * sizeof(DrawVerticeFormats),
|
||||
0, 0, 0, &d3d9->vertex_buf, NULL);
|
||||
|
||||
static const DrawVerticeFormats init_verts[] = {
|
||||
{ -1.0f, -1.0f, 0.0f, 1.0f },
|
||||
{ 1.0f, -1.0f, 1.0f, 1.0f },
|
||||
{ -1.0f, 1.0f, 0.0f, 0.0f },
|
||||
{ 1.0f, 1.0f, 1.0f, 0.0f },
|
||||
};
|
||||
|
||||
void *verts_ptr;
|
||||
d3d9->vertex_buf->Lock(0, 0, &verts_ptr, 0);
|
||||
memcpy(verts_ptr, init_verts, sizeof(init_verts));
|
||||
d3d9->vertex_buf->Unlock();
|
||||
|
||||
static const D3DVERTEXELEMENT9 VertexElements[] =
|
||||
{
|
||||
{ 0, 0 * sizeof(float), D3DDECLTYPE_FLOAT2, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0 },
|
||||
{ 0, 2 * sizeof(float), D3DDECLTYPE_FLOAT2, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 0 },
|
||||
D3DDECL_END()
|
||||
};
|
||||
|
||||
d3d9->d3d_render_device->CreateVertexDeclaration(VertexElements, &d3d9->v_decl);
|
||||
|
||||
d3d9->d3d_render_device->Clear(0, NULL, D3DCLEAR_TARGET,
|
||||
0xff000000, 1.0f, 0);
|
||||
|
||||
d3d9->d3d_render_device->SetRenderState(D3DRS_CULLMODE, D3DCULL_NONE);
|
||||
d3d9->d3d_render_device->SetRenderState(D3DRS_ZENABLE, FALSE);
|
||||
|
||||
D3DVIEWPORT9 vp = {0};
|
||||
vp.Width = d3d9->video_mode.fIsHiDef ? 1280 : 640;
|
||||
vp.Height = d3d9->video_mode.fIsHiDef ? 720 : 480;
|
||||
vp.MinZ = 0.0f;
|
||||
vp.MaxZ = 1.0f;
|
||||
d3d9->d3d_render_device->SetViewport(&vp);
|
||||
|
||||
if(g_console.viewports.custom_vp.width == 0)
|
||||
g_console.viewports.custom_vp.width = vp.Width;
|
||||
|
||||
if(g_console.viewports.custom_vp.height == 0)
|
||||
g_console.viewports.custom_vp.height = vp.Height;
|
||||
|
||||
xdk360_set_rotation(d3d9, g_console.screen_orientation);
|
||||
|
||||
d3d9->fbo_enabled = 1;
|
||||
d3d9->vsync = video->vsync;
|
||||
|
||||
return d3d9;
|
||||
}
|
||||
|
||||
static bool xdk360_frame(void *data, const void *frame,
|
||||
unsigned width, unsigned height, unsigned pitch, const char *msg)
|
||||
{
|
||||
xdk360_video_t *d3d9 = (xdk360_video_t*)data;
|
||||
D3DSurface* pRenderTarget0;
|
||||
bool menu_enabled = g_console.menu_enable;
|
||||
|
||||
if (d3d9->last_width != width || d3d9->last_height != height)
|
||||
{
|
||||
D3DLOCKED_RECT d3dlr;
|
||||
|
||||
d3d9->lpTexture->LockRect(0, &d3dlr, NULL, D3DLOCK_NOSYSLOCK);
|
||||
memset(d3dlr.pBits, 0, 512 * d3dlr.Pitch);
|
||||
d3d9->lpTexture->UnlockRect(0);
|
||||
|
||||
float tex_w = width / 512.0f;
|
||||
float tex_h = height / 512.0f;
|
||||
|
||||
DrawVerticeFormats verts[] = {
|
||||
{ -1.0f, -1.0f, 0.0f, tex_h },
|
||||
{ 1.0f, -1.0f, tex_w, tex_h },
|
||||
{ -1.0f, 1.0f, 0.0f, 0.0f },
|
||||
{ 1.0f, 1.0f, tex_w, 0.0f },
|
||||
};
|
||||
|
||||
// Align texels and vertices (D3D9 quirk).
|
||||
for (unsigned i = 0; i < 4; i++)
|
||||
{
|
||||
verts[i].x -= 0.5f / 512.0f;
|
||||
verts[i].y += 0.5f / 512.0f;
|
||||
}
|
||||
|
||||
void *verts_ptr;
|
||||
d3d9->vertex_buf->Lock(0, 0, &verts_ptr, 0);
|
||||
memcpy(verts_ptr, verts, sizeof(verts));
|
||||
d3d9->vertex_buf->Unlock();
|
||||
|
||||
d3d9->last_width = width;
|
||||
d3d9->last_height = height;
|
||||
}
|
||||
|
||||
if (d3d9->fbo_enabled)
|
||||
{
|
||||
d3d9->d3d_render_device->GetRenderTarget(0, &pRenderTarget0);
|
||||
d3d9->d3d_render_device->SetRenderTarget(0, d3d9->lpSurface);
|
||||
}
|
||||
|
||||
if (d3d9->should_resize)
|
||||
xdk360_set_viewport(false);
|
||||
|
||||
d3d9->d3d_render_device->Clear(0, NULL, D3DCLEAR_TARGET,
|
||||
0xff000000, 1.0f, 0);
|
||||
d3d9->frame_count++;
|
||||
|
||||
d3d9->d3d_render_device->SetTexture(0, d3d9->lpTexture);
|
||||
|
||||
hlsl_use(1);
|
||||
if(d3d9->fbo_enabled)
|
||||
{
|
||||
hlsl_set_params(width, height, 512, 512, g_settings.video.fbo_scale_x * width,
|
||||
g_settings.video.fbo_scale_y * height, d3d9->frame_count);
|
||||
D3DVIEWPORT9 vp = {0};
|
||||
vp.Width = g_settings.video.fbo_scale_x * width;
|
||||
vp.Height = g_settings.video.fbo_scale_y * height;
|
||||
vp.X = 0;
|
||||
vp.Y = 0;
|
||||
vp.MinZ = 0.0f;
|
||||
vp.MaxZ = 1.0f;
|
||||
d3d9->d3d_render_device->SetViewport(&vp);
|
||||
}
|
||||
else
|
||||
{
|
||||
hlsl_set_params(width, height, 512, 512, d3d9->d3dpp.BackBufferWidth,
|
||||
d3d9->d3dpp.BackBufferHeight, d3d9->frame_count);
|
||||
}
|
||||
|
||||
D3DLOCKED_RECT d3dlr;
|
||||
d3d9->lpTexture->LockRect(0, &d3dlr, NULL, D3DLOCK_NOSYSLOCK);
|
||||
for (unsigned y = 0; y < height; y++)
|
||||
{
|
||||
const uint8_t *in = (const uint8_t*)frame + y * pitch;
|
||||
uint8_t *out = (uint8_t*)d3dlr.pBits + y * d3dlr.Pitch;
|
||||
memcpy(out, in, width * sizeof(uint16_t));
|
||||
}
|
||||
d3d9->lpTexture->UnlockRect(0);
|
||||
|
||||
d3d9->d3d_render_device->SetSamplerState(0, D3DSAMP_MINFILTER, g_settings.video.smooth ? D3DTEXF_LINEAR : D3DTEXF_POINT);
|
||||
d3d9->d3d_render_device->SetSamplerState(0, D3DSAMP_MAGFILTER, g_settings.video.smooth ? D3DTEXF_LINEAR : D3DTEXF_POINT);
|
||||
d3d9->d3d_render_device->SetSamplerState(0, D3DSAMP_ADDRESSU, D3DTADDRESS_BORDER);
|
||||
d3d9->d3d_render_device->SetSamplerState(0, D3DSAMP_ADDRESSV, D3DTADDRESS_BORDER);
|
||||
|
||||
d3d9->d3d_render_device->SetVertexDeclaration(d3d9->v_decl);
|
||||
d3d9->d3d_render_device->SetStreamSource(0, d3d9->vertex_buf, 0, sizeof(DrawVerticeFormats));
|
||||
|
||||
d3d9->d3d_render_device->DrawPrimitive(D3DPT_TRIANGLESTRIP, 0, 2);
|
||||
|
||||
if(d3d9->fbo_enabled)
|
||||
{
|
||||
d3d9->d3d_render_device->Resolve(D3DRESOLVE_RENDERTARGET0, NULL, d3d9->lpTexture_ot,
|
||||
NULL, 0, 0, NULL, 0, 0, NULL);
|
||||
|
||||
d3d9->d3d_render_device->SetRenderTarget(0, pRenderTarget0);
|
||||
pRenderTarget0->Release();
|
||||
d3d9->d3d_render_device->SetTexture(0, &d3d9->lpTexture_ot_as16srgb);
|
||||
|
||||
hlsl_use(2);
|
||||
hlsl_set_params(g_settings.video.fbo_scale_x * width, g_settings.video.fbo_scale_y * height, g_settings.video.fbo_scale_x * 512, g_settings.video.fbo_scale_y * 512, d3d9->d3dpp.BackBufferWidth,
|
||||
d3d9->d3dpp.BackBufferHeight, d3d9->frame_count);
|
||||
xdk360_set_viewport(false);
|
||||
|
||||
d3d9->d3d_render_device->SetSamplerState(0, D3DSAMP_MINFILTER, g_settings.video.second_pass_smooth ? D3DTEXF_LINEAR : D3DTEXF_POINT);
|
||||
d3d9->d3d_render_device->SetSamplerState(0, D3DSAMP_MAGFILTER, g_settings.video.second_pass_smooth ? D3DTEXF_LINEAR : D3DTEXF_POINT);
|
||||
d3d9->d3d_render_device->SetSamplerState(0, D3DSAMP_ADDRESSU, D3DTADDRESS_BORDER);
|
||||
d3d9->d3d_render_device->SetSamplerState(0, D3DSAMP_ADDRESSV, D3DTADDRESS_BORDER);
|
||||
d3d9->d3d_render_device->SetVertexDeclaration(d3d9->v_decl);
|
||||
d3d9->d3d_render_device->SetStreamSource(0, d3d9->vertex_buf, 0, sizeof(DrawVerticeFormats));
|
||||
d3d9->d3d_render_device->DrawPrimitive(D3DPT_TRIANGLESTRIP, 0, 2);
|
||||
}
|
||||
|
||||
/* XBox 360 specific font code */
|
||||
if (msg && !menu_enabled)
|
||||
{
|
||||
if(IS_TIMER_EXPIRED(d3d9))
|
||||
{
|
||||
xdk360_console_format(msg);
|
||||
SET_TIMER_EXPIRATION(d3d9, 30);
|
||||
}
|
||||
|
||||
xdk360_console_draw();
|
||||
}
|
||||
|
||||
if(!d3d9->block_swap)
|
||||
gfx_ctx_swap_buffers();
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
static void xdk360_set_nonblock_state(void *data, bool state)
|
||||
{
|
||||
xdk360_video_t *d3d9 = (xdk360_video_t*)data;
|
||||
|
||||
if(d3d9->vsync)
|
||||
{
|
||||
RARCH_LOG("D3D Vsync => %s\n", state ? "off" : "on");
|
||||
gfx_ctx_set_swap_interval(state ? 0 : 1, TRUE);
|
||||
}
|
||||
}
|
||||
|
||||
static bool xdk360_alive(void *data)
|
||||
{
|
||||
xdk360_video_t *d3d9 = (xdk360_video_t*)data;
|
||||
check_window(d3d9);
|
||||
return !d3d9->quitting;
|
||||
}
|
||||
|
||||
static bool xdk360_focus(void *data)
|
||||
{
|
||||
(void)data;
|
||||
return gfx_ctx_window_has_focus();
|
||||
}
|
||||
|
||||
static void xdk360_start(void)
|
||||
{
|
||||
video_info_t video_info = {0};
|
||||
|
||||
video_info.vsync = g_settings.video.vsync;
|
||||
video_info.force_aspect = false;
|
||||
video_info.fullscreen = true;
|
||||
video_info.smooth = g_settings.video.smooth;
|
||||
video_info.input_scale = 2;
|
||||
|
||||
driver.video_data = xdk360_init(&video_info, NULL, NULL);
|
||||
|
||||
xdk360_video_t *d3d9 = (xdk360_video_t*)driver.video_data;
|
||||
|
||||
gfx_ctx_set_swap_interval(d3d9->vsync ? 1 : 0, false);
|
||||
|
||||
/* XBox 360 specific font code */
|
||||
HRESULT hr = xdk360_console_init("game:\\media\\Arial_12.xpr",
|
||||
0xff000000, 0xffffffff );
|
||||
|
||||
if(hr < 0)
|
||||
{
|
||||
RARCH_ERR("Couldn't create debug console.\n");
|
||||
}
|
||||
}
|
||||
|
||||
static void xdk360_restart(void)
|
||||
{
|
||||
}
|
||||
|
||||
static void xdk360_stop(void)
|
||||
{
|
||||
void *data = driver.video_data;
|
||||
driver.video_data = NULL;
|
||||
xdk360_console_deinit();
|
||||
xdk360_free(data);
|
||||
}
|
||||
|
||||
const video_driver_t video_xdk360 = {
|
||||
xdk360_init,
|
||||
xdk360_frame,
|
||||
xdk360_set_nonblock_state,
|
||||
xdk360_alive,
|
||||
xdk360_focus,
|
||||
NULL,
|
||||
xdk360_free,
|
||||
"xdk360",
|
||||
xdk360_start,
|
||||
xdk360_stop,
|
||||
xdk360_restart,
|
||||
xdk360_set_rotation,
|
||||
};
|
||||
@@ -0,0 +1,67 @@
|
||||
/* RetroArch - A frontend for libretro.
|
||||
* Copyright (C) 2010-2012 - Hans-Kristian Arntzen
|
||||
* Copyright (C) 2011-2012 - Daniel De Matteis
|
||||
*
|
||||
* RetroArch is free software: you can redistribute it and/or modify it under the terms
|
||||
* of the GNU General Public License as published by the Free Software Found-
|
||||
* ation, either version 3 of the License, or (at your option) any later version.
|
||||
*
|
||||
* RetroArch is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
|
||||
* without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
|
||||
* PURPOSE. See the GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along with RetroArch.
|
||||
* If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifndef _XDK360_VIDEO_H
|
||||
#define _XDK360_VIDEO_H
|
||||
|
||||
#include <stdint.h>
|
||||
#include "fonts.h"
|
||||
|
||||
#define DFONT_MAX 4096
|
||||
#define PRIM_FVF (D3DFVF_XYZRHW | D3DFVF_TEX1)
|
||||
|
||||
#define MIN_SCALING_FACTOR (1.0f)
|
||||
#define MAX_SCALING_FACTOR (2.0f)
|
||||
|
||||
typedef struct
|
||||
{
|
||||
float x;
|
||||
float y;
|
||||
float z;
|
||||
float rhw;
|
||||
float u;
|
||||
float v;
|
||||
} primitive_t;
|
||||
|
||||
typedef struct DrawVerticeFormats
|
||||
{
|
||||
float x, y;
|
||||
float u, v;
|
||||
} DrawVerticeFormats;
|
||||
|
||||
typedef struct xdk360_video
|
||||
{
|
||||
bool block_swap;
|
||||
bool fbo_enabled;
|
||||
bool should_resize;
|
||||
bool quitting;
|
||||
bool vsync;
|
||||
unsigned frame_count;
|
||||
unsigned last_width;
|
||||
unsigned last_height;
|
||||
IDirect3D9* d3d_device;
|
||||
IDirect3DDevice9* d3d_render_device;
|
||||
IDirect3DVertexBuffer9* vertex_buf;
|
||||
IDirect3DTexture9* lpTexture;
|
||||
D3DTexture lpTexture_ot_as16srgb;
|
||||
LPDIRECT3DTEXTURE9 lpTexture_ot;
|
||||
IDirect3DVertexDeclaration9* v_decl;
|
||||
D3DPRESENT_PARAMETERS d3dpp;
|
||||
XVIDEO_MODE video_mode;
|
||||
LPDIRECT3DSURFACE9 lpSurface;
|
||||
} xdk360_video_t;
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,118 @@
|
||||
/* RetroArch - A frontend for libretro.
|
||||
* Copyright (C) 2010-2012 - Hans-Kristian Arntzen
|
||||
* Copyright (C) 2011-2012 - Daniel De Matteis
|
||||
*
|
||||
* RetroArch is free software: you can redistribute it and/or modify it under the terms
|
||||
* of the GNU General Public License as published by the Free Software Found-
|
||||
* ation, either version 3 of the License, or (at your option) any later version.
|
||||
*
|
||||
* RetroArch is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
|
||||
* without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
|
||||
* PURPOSE. See the GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along with RetroArch.
|
||||
* If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#ifndef RARCH_360_RESOURCES_H
|
||||
#define RARCH_360_RESOURCES_H
|
||||
|
||||
struct RESOURCE
|
||||
{
|
||||
unsigned long dwType;
|
||||
unsigned long dwOffset;
|
||||
unsigned long dwSize;
|
||||
char * strName;
|
||||
};
|
||||
|
||||
// Resource types
|
||||
enum
|
||||
{
|
||||
RESOURCETYPE_USERDATA = ( ( 'U' << 24 ) | ( 'S' << 16 ) | ( 'E' << 8 ) | ( 'R' ) ),
|
||||
RESOURCETYPE_TEXTURE = ( ( 'T' << 24 ) | ( 'X' << 16 ) | ( '2' << 8 ) | ( 'D' ) ),
|
||||
RESOURCETYPE_CUBEMAP = ( ( 'T' << 24 ) | ( 'X' << 16 ) | ( 'C' << 8 ) | ( 'M' ) ),
|
||||
RESOURCETYPE_VOLUMETEXTURE = ( ( 'T' << 24 ) | ( 'X' << 16 ) | ( '3' << 8 ) | ( 'D' ) ),
|
||||
RESOURCETYPE_VERTEXBUFFER = ( ( 'V' << 24 ) | ( 'B' << 16 ) | ( 'U' << 8 ) | ( 'F' ) ),
|
||||
RESOURCETYPE_INDEXBUFFER = ( ( 'I' << 24 ) | ( 'B' << 16 ) | ( 'U' << 8 ) | ( 'F' ) ),
|
||||
RESOURCETYPE_EOF = 0xffffffff
|
||||
};
|
||||
|
||||
|
||||
//--------------------------------------------------------------------------------------
|
||||
// Name: PackedResource
|
||||
//--------------------------------------------------------------------------------------
|
||||
class PackedResource
|
||||
{
|
||||
protected:
|
||||
unsigned char * m_pSysMemData; // Alloc'ed memory for resource headers etc.
|
||||
unsigned long m_dwSysMemDataSize;
|
||||
|
||||
unsigned char * m_pVidMemData; // Alloc'ed memory for resource data, etc.
|
||||
unsigned long m_dwVidMemDataSize;
|
||||
|
||||
RESOURCE* m_pResourceTags; // Tags to associate names with the resources
|
||||
unsigned long m_dwNumResourceTags; // Number of resource tags
|
||||
public:
|
||||
int m_bInitialized; // Resource is fully initialized
|
||||
HRESULT Create( const char * strFilename );
|
||||
void Destroy();
|
||||
|
||||
D3DResource* RegisterResource( D3DResource* pResource ) const
|
||||
{
|
||||
return pResource;
|
||||
}
|
||||
|
||||
void * GetData( unsigned long dwOffset ) const
|
||||
{
|
||||
return &m_pSysMemData[dwOffset];
|
||||
}
|
||||
|
||||
D3DResource* GetResource( unsigned long dwOffset ) const
|
||||
{
|
||||
return (( D3DResource* )GetData( dwOffset ) );
|
||||
}
|
||||
|
||||
D3DTexture* GetTexture( unsigned long dwOffset ) const
|
||||
{
|
||||
return ( D3DTexture* )GetResource( dwOffset );
|
||||
}
|
||||
|
||||
D3DArrayTexture* GetArrayTexture( unsigned long dwOffset ) const
|
||||
{
|
||||
return ( D3DArrayTexture* )GetResource( dwOffset );
|
||||
}
|
||||
|
||||
D3DVertexBuffer* GetVertexBuffer( unsigned long dwOffset ) const
|
||||
{
|
||||
return ( D3DVertexBuffer* )GetResource( dwOffset );
|
||||
}
|
||||
|
||||
void * GetData( const char * strName ) const;
|
||||
|
||||
D3DResource* GetResource( const char * strName ) const
|
||||
{
|
||||
return ( ( D3DResource* )GetData( strName ) );
|
||||
}
|
||||
|
||||
D3DTexture* GetTexture( const char * strName ) const
|
||||
{
|
||||
return ( D3DTexture* )GetResource( strName );
|
||||
}
|
||||
|
||||
D3DArrayTexture* GetArrayTexture( const char * strName ) const
|
||||
{
|
||||
return ( D3DArrayTexture* )GetResource( strName );
|
||||
}
|
||||
|
||||
D3DVertexBuffer* GetVertexBuffer( const char * strName ) const
|
||||
{
|
||||
return ( D3DVertexBuffer* )GetResource( strName );
|
||||
}
|
||||
|
||||
PackedResource();
|
||||
~PackedResource();
|
||||
};
|
||||
|
||||
#endif
|
||||
@@ -3,3 +3,14 @@ Hans-Kristian Arntzen - <[email protected]>
|
||||
|
||||
Devin J. Pohly - <[email protected]>
|
||||
- Joypad axis support
|
||||
|
||||
Chris Moeller - <[email protected]>
|
||||
- CoreAudio audio driver
|
||||
|
||||
Daniel De Matteis - <[email protected]>
|
||||
- PlayStation 3 port
|
||||
- XBox 360 XDK port
|
||||
|
||||
tukuyomi - <[email protected]>
|
||||
- Cleanups in quickbuild
|
||||
|
||||
@@ -1,52 +1,123 @@
|
||||
include config.mk
|
||||
|
||||
TARGET = ssnes tools/ssnes-joyconfig
|
||||
TARGET = retroarch tools/retroarch-joyconfig
|
||||
|
||||
OBJ = ssnes.o file.o driver.o settings.o dynamic.o message.o
|
||||
JOYCONFIG_OBJ = tools/ssnes-joyconfig.o conf/config_file.o
|
||||
OBJ = retroarch.o file.o file_path.o hash.o driver.o settings.o dynamic.o message.o rewind.o gfx/gfx_common.o patch.o compat/compat.o screenshot.o audio/utils.o
|
||||
JOYCONFIG_OBJ = tools/retroarch-joyconfig.o conf/config_file.o compat/compat.o
|
||||
HEADERS = $(wildcard */*.h) $(wildcard *.h)
|
||||
|
||||
LIBS =
|
||||
DEFINES = -DHAVE_CONFIG_H
|
||||
LIBS = -lm
|
||||
DEFINES = -DHAVE_CONFIG_H -DHAVE_SCREENSHOTS
|
||||
|
||||
ifeq ($(HAVE_SRC), 1)
|
||||
LIBS += $(SRC_LIBS)
|
||||
DEFINES += $(SRC_CFLAGS)
|
||||
ifeq ($(REENTRANT_TEST), 1)
|
||||
DEFINES += -Dmain=retroarch_main
|
||||
OBJ += console/test.o
|
||||
endif
|
||||
|
||||
ifneq ($(findstring Darwin,$(OS)),)
|
||||
OSX := 1
|
||||
LIBS += -framework AppKit
|
||||
else
|
||||
OSX := 0
|
||||
endif
|
||||
|
||||
BSD_LOCAL_INC =
|
||||
DYLIB_LIB = -ldl
|
||||
ifneq ($(findstring BSD,$(OS)),)
|
||||
BSD_LOCAL_INC = -I/usr/local/include
|
||||
DYLIB_LIB = -lc
|
||||
endif
|
||||
|
||||
ifneq ($(findstring Linux,$(OS)),)
|
||||
LIBS += -lrt
|
||||
endif
|
||||
|
||||
ifeq ($(HAVE_THREADS), 1)
|
||||
OBJ += autosave.o thread.o
|
||||
LIBS += -lpthread
|
||||
endif
|
||||
|
||||
ifeq ($(HAVE_CONFIGFILE), 1)
|
||||
OBJ += conf/config_file.o
|
||||
endif
|
||||
|
||||
ifeq ($(HAVE_BSV_MOVIE), 1)
|
||||
OBJ += movie.o
|
||||
endif
|
||||
|
||||
ifeq ($(HAVE_NETPLAY), 1)
|
||||
OBJ += netplay.o network_cmd.o
|
||||
endif
|
||||
|
||||
ifeq ($(HAVE_RSOUND), 1)
|
||||
OBJ += audio/rsound.o
|
||||
LIBS += -lrsound
|
||||
LIBS += $(RSOUND_LIBS)
|
||||
DEFINES += $(RSOUND_CFLAGS)
|
||||
endif
|
||||
|
||||
ifeq ($(HAVE_OSS), 1)
|
||||
OBJ += audio/oss.o
|
||||
endif
|
||||
ifeq ($(HAVE_OSS_BSD), 1)
|
||||
OBJ += audio/oss.o
|
||||
endif
|
||||
ifeq ($(HAVE_OSS_LIB), 1)
|
||||
LIBS += -lossaudio
|
||||
endif
|
||||
|
||||
ifeq ($(HAVE_ALSA), 1)
|
||||
OBJ += audio/alsa.o
|
||||
LIBS += -lasound
|
||||
LIBS += $(ALSA_LIBS)
|
||||
DEFINES += $(ALSA_CFLAGS)
|
||||
endif
|
||||
ifeq ($(HAVE_ROAR), 1)
|
||||
OBJ += audio/roar.o
|
||||
LIBS += -lroar
|
||||
LIBS += $(ROAR_LIBS)
|
||||
DEFINES += $(ROAR_CFLAGS)
|
||||
endif
|
||||
ifeq ($(HAVE_AL), 1)
|
||||
OBJ += audio/openal.o
|
||||
ifeq ($(OSX),1)
|
||||
LIBS += -framework OpenAL
|
||||
else
|
||||
LIBS += -lopenal
|
||||
endif
|
||||
endif
|
||||
ifeq ($(HAVE_JACK),1)
|
||||
OBJ += audio/jack.o
|
||||
LIBS += -ljack
|
||||
LIBS += $(JACK_LIBS)
|
||||
DEFINES += $(JACK_CFLAGS)
|
||||
endif
|
||||
ifeq ($(HAVE_PULSE), 1)
|
||||
OBJ += audio/pulse.o
|
||||
LIBS += $(PULSE_LIBS)
|
||||
DEFINES += $(PULSE_CFLAGS)
|
||||
endif
|
||||
|
||||
ifeq ($(HAVE_COREAUDIO), 1)
|
||||
OBJ += audio/coreaudio.o
|
||||
LIBS += -framework CoreServices -framework CoreAudio -framework AudioUnit
|
||||
endif
|
||||
|
||||
ifeq ($(HAVE_SDL), 1)
|
||||
OBJ += gfx/gl.o input/sdl.o audio/sdl.o audio/buffer.o
|
||||
LIBS += $(SDL_LIBS) -lGL
|
||||
DEFINES += $(SDL_CFLAGS)
|
||||
OBJ += gfx/sdl_gfx.o gfx/context/sdl_ctx.o input/sdl_input.o audio/sdl_audio.o fifo_buffer.o
|
||||
DEFINES += $(SDL_CFLAGS) $(BSD_LOCAL_INC)
|
||||
LIBS += $(SDL_LIBS)
|
||||
|
||||
ifeq ($(HAVE_OPENGL), 1)
|
||||
OBJ += gfx/gl.o gfx/fonts/freetype.o
|
||||
ifeq ($(OSX),1)
|
||||
LIBS += -framework OpenGL
|
||||
else
|
||||
LIBS += -lGL
|
||||
endif
|
||||
endif
|
||||
endif
|
||||
|
||||
ifeq ($(HAVE_XVIDEO), 1)
|
||||
OBJ += gfx/xvideo.o input/x11_input.o
|
||||
LIBS += $(XVIDEO_LIBS) $(X11_LIBS) $(XEXT_LIBS)
|
||||
DEFINES += $(XVIDEO_CFLAGS) $(X11_CFLAGS) $(XEXT_CFLAGS)
|
||||
endif
|
||||
|
||||
ifeq ($(HAVE_CG), 1)
|
||||
@@ -55,42 +126,84 @@ ifeq ($(HAVE_CG), 1)
|
||||
endif
|
||||
|
||||
ifeq ($(HAVE_XML), 1)
|
||||
OBJ += gfx/shader_glsl.o
|
||||
OBJ += cheats.o
|
||||
LIBS += $(XML_LIBS)
|
||||
DEFINES += $(XML_CFLAGS)
|
||||
|
||||
ifeq ($(HAVE_OPENGL), 1)
|
||||
OBJ += gfx/shader_glsl.o
|
||||
endif
|
||||
endif
|
||||
|
||||
ifeq ($(HAVE_FILTER), 1)
|
||||
OBJ += hqflt/hq.o
|
||||
OBJ += hqflt/grayscale.o
|
||||
OBJ += hqflt/bleed.o
|
||||
OBJ += hqflt/ntsc.o
|
||||
OBJ += hqflt/snes_ntsc/snes_ntsc.o
|
||||
ifeq ($(HAVE_XML), 1)
|
||||
OBJ += gfx/state_tracker.o gfx/image.o
|
||||
else ifeq ($(HAVE_CG), 1)
|
||||
OBJ += gfx/state_tracker.o gfx/image.o
|
||||
endif
|
||||
|
||||
ifeq ($(HAVE_DYLIB), 1)
|
||||
OBJ += gfx/ext_gfx.o audio/ext_audio.o
|
||||
LIBS += $(DYLIB_LIB)
|
||||
endif
|
||||
|
||||
ifeq ($(HAVE_FREETYPE), 1)
|
||||
OBJ += gfx/fonts.o
|
||||
OBJ += gfx/fonts/fonts.o
|
||||
LIBS += $(FREETYPE_LIBS)
|
||||
DEFINES += $(FREETYPE_CFLAGS)
|
||||
endif
|
||||
|
||||
ifeq ($(HAVE_SDL_IMAGE), 1)
|
||||
LIBS += $(SDL_IMAGE_LIBS)
|
||||
DEFINES += $(SDL_IMAGE_CFLAGS)
|
||||
endif
|
||||
|
||||
ifeq ($(HAVE_FFMPEG), 1)
|
||||
OBJ += record/ffemu.o
|
||||
LIBS += $(AVCODEC_LIBS) $(AVCORE_LIBS) $(AVFORMAT_LIBS) $(AVUTIL_LIBS) $(SWSCALE_LIBS)
|
||||
DEFINES += $(AVCODEC_CFLAGS) $(AVCORE_CFLAGS) $(AVFORMAT_CFLAGS) $(AVUTIL_CFLAGS) $(SWSCALE_CFLAGS)
|
||||
LIBS += $(AVCODEC_LIBS) $(AVFORMAT_LIBS) $(AVUTIL_LIBS) $(SWSCALE_LIBS)
|
||||
DEFINES += $(AVCODEC_CFLAGS) $(AVFORMAT_CFLAGS) $(AVUTIL_CFLAGS) $(SWSCALE_CFLAGS)
|
||||
endif
|
||||
|
||||
ifeq ($(HAVE_DYNAMIC), 1)
|
||||
LIBS += -ldl
|
||||
LIBS += $(DYLIB_LIB)
|
||||
else
|
||||
LIBS += $(libsnes)
|
||||
LIBS += $(libretro)
|
||||
endif
|
||||
|
||||
ifeq ($(HAVE_PYTHON), 1)
|
||||
DEFINES += $(PYTHON_CFLAGS) -Wno-unused-parameter
|
||||
LIBS += $(PYTHON_LIBS)
|
||||
OBJ += gfx/py_state/py_state.o
|
||||
endif
|
||||
|
||||
ifeq ($(HAVE_SINC), 1)
|
||||
OBJ += audio/sinc.o
|
||||
else
|
||||
OBJ += audio/hermite.o
|
||||
endif
|
||||
|
||||
ifneq ($(V),1)
|
||||
Q := @
|
||||
endif
|
||||
|
||||
CFLAGS = -Wall -O3 -g -std=gnu99 -I.
|
||||
OPTIMIZE_FLAG = -O3
|
||||
ifeq ($(DEBUG), 1)
|
||||
OPTIMIZE_FLAG = -O0
|
||||
endif
|
||||
|
||||
CFLAGS += -Wall $(OPTIMIZE_FLAG) -g -I. -pedantic
|
||||
ifeq ($(CXX_BUILD), 1)
|
||||
CFLAGS += -std=c++0x -xc++ -D__STDC_CONSTANT_MACROS
|
||||
else
|
||||
ifneq ($(findstring icc,$(CC)),)
|
||||
CFLAGS += -std=c99 -D_GNU_SOURCE
|
||||
else
|
||||
CFLAGS += -std=gnu99
|
||||
endif
|
||||
endif
|
||||
|
||||
ifeq ($(NOUNUSED), yes)
|
||||
CFLAGS += -Wno-unused-result
|
||||
endif
|
||||
|
||||
all: $(TARGET) config.mk
|
||||
|
||||
@@ -98,12 +211,16 @@ config.mk: configure qb/*
|
||||
@echo "config.mk is outdated or non-existing. Run ./configure again."
|
||||
@exit 1
|
||||
|
||||
ssnes: $(OBJ)
|
||||
$(Q)$(CXX) -o $@ $(OBJ) $(LIBS) $(LDFLAGS)
|
||||
retroarch: $(OBJ)
|
||||
$(Q)$(CXX) -o $@ $(OBJ) $(LIBS) $(LDFLAGS) $(LIBRARY_DIRS)
|
||||
@$(if $(Q), $(shell echo echo LD $@),)
|
||||
|
||||
tools/ssnes-joyconfig: $(JOYCONFIG_OBJ)
|
||||
$(Q)$(CC) -o $@ $(JOYCONFIG_OBJ) $(SDL_LIBS) $(LDFLAGS)
|
||||
tools/retroarch-joyconfig: $(JOYCONFIG_OBJ)
|
||||
ifeq ($(CXX_BUILD), 1)
|
||||
$(Q)$(CXX) -o $@ $(JOYCONFIG_OBJ) $(SDL_LIBS) $(LDFLAGS) $(LIBRARY_DIRS)
|
||||
else
|
||||
$(Q)$(CC) -o $@ $(JOYCONFIG_OBJ) $(SDL_LIBS) $(LDFLAGS) $(LIBRARY_DIRS)
|
||||
endif
|
||||
@$(if $(Q), $(shell echo echo LD $@),)
|
||||
|
||||
%.o: %.c config.h config.mk $(HEADERS)
|
||||
@@ -111,26 +228,30 @@ tools/ssnes-joyconfig: $(JOYCONFIG_OBJ)
|
||||
@$(if $(Q), $(shell echo echo CC $<),)
|
||||
|
||||
install: $(TARGET)
|
||||
mkdir -p $(DESTDIR)$(PREFIX)/bin
|
||||
mkdir -p $(DESTDIR)/etc
|
||||
mkdir -p $(DESTDIR)$(PREFIX)/share/man/man1
|
||||
mkdir -p $(DESTDIR)$(PREFIX)/bin 2>/dev/null || /bin/true
|
||||
mkdir -p $(DESTDIR)/etc 2>/dev/null || /bin/true
|
||||
mkdir -p $(DESTDIR)$(PREFIX)/share/man/man1 2>/dev/null || /bin/true
|
||||
install -m755 $(TARGET) $(DESTDIR)$(PREFIX)/bin
|
||||
install -m644 ssnes.cfg $(DESTDIR)/etc/ssnes.cfg
|
||||
install -m644 docs/{ssnes,ssnes-joyconfig}.1 $(DESTDIR)$(PREFIX)/share/man/man1
|
||||
install -m644 retroarch.cfg $(DESTDIR)/etc/retroarch.cfg
|
||||
install -m644 docs/retroarch.1 $(DESTDIR)$(PREFIX)/share/man/man1
|
||||
install -m644 docs/retroarch-joyconfig.1 $(DESTDIR)$(PREFIX)/share/man/man1
|
||||
install -m755 retroarch-zip $(DESTDIR)$(PREFIX)/bin
|
||||
|
||||
uninstall:
|
||||
rm -f $(DESTDIR)$(PREFIX)/bin/{ssnes,ssnes-joyconfig}
|
||||
rm -f $(DESTDIR)/etc/ssnes.cfg
|
||||
rm -f $(DESTDIR)$(PREFIX)/share/man/man1/{ssnes,ssnes-joyconfig}.1
|
||||
rm -f $(DESTDIR)$(PREFIX)/bin/retroarch
|
||||
rm -f $(DESTDIR)$(PREFIX)/bin/retroarch-joyconfig
|
||||
rm -f $(DESTDIR)$(PREFIX)/bin/retroarch-zip
|
||||
rm -f $(DESTDIR)/etc/retroarch.cfg
|
||||
rm -f $(DESTDIR)$(PREFIX)/share/man/man1/retroarch.1
|
||||
rm -f $(DESTDIR)$(PREFIX)/share/man/man1/retroarch-joyconfig.1
|
||||
|
||||
clean:
|
||||
rm -f *.o
|
||||
rm -f audio/*.o
|
||||
rm -f conf/*.o
|
||||
rm -f gfx/*.o
|
||||
rm -f gfx/py_state/*.o
|
||||
rm -f record/*.o
|
||||
rm -f hqflt/*.o
|
||||
rm -f hqflt/snes_ntsc/*.o
|
||||
rm -f input/*.o
|
||||
rm -f tools/*.o
|
||||
rm -f $(TARGET)
|
||||
|
||||
+157
@@ -0,0 +1,157 @@
|
||||
RARCH_VERSION = "0.9.6"
|
||||
|
||||
#which compiler to build with - GCC or SNC
|
||||
#set to GCC for debug builds for use with debugger
|
||||
CELL_BUILD_TOOLS = SNC
|
||||
CELL_GPU_TYPE = RSX
|
||||
CELL_PSGL_VERSION = ultra-opt
|
||||
|
||||
DEBUG = 0
|
||||
DOWNLOAD_SHADERS = 1
|
||||
STRIPPING_ENABLE = 0
|
||||
HAVE_RGL = 1
|
||||
HAVE_LOGGER = 0
|
||||
|
||||
CONTENT_ID_FULL = UP0001-SSNE10000_00-0000000000000001
|
||||
CONTENT_ID = SSNE10000
|
||||
|
||||
PC_DEVELOPMENT_IP_ADDRESS = "192.168.1.7"
|
||||
PC_DEVELOPMENT_UDP_PORT = 3490
|
||||
|
||||
CELL_MK_DIR ?= $(CELL_SDK)/samples/mk
|
||||
include $(CELL_MK_DIR)/sdk.makedef.mk
|
||||
|
||||
PPU_TARGET = retroarch.elf
|
||||
SALAMANDER_TARGET = retroarch-salamander.elf
|
||||
|
||||
EBOOT_PATH = ps3/pkg/USRDIR/EBOOT.BIN
|
||||
CORE_PATH = ps3/pkg/USRDIR/cores/CORE.SELF
|
||||
|
||||
LDDIRS = -L. -L$(CELL_SDK)/target/ppu/lib/PSGL/RSX/ultra-opt
|
||||
INCDIRS = -I. -Ips3 -Icommon
|
||||
|
||||
PKG_SCRIPT = ps3/ps3py/pkg.py
|
||||
ifeq ($(shell uname), Linux)
|
||||
PKG_FINALIZE = package_finalize
|
||||
MAKE_SELF_WC = make_self_wc
|
||||
MAKE_SELF = make_self_npdrm
|
||||
PYTHON2 = python2
|
||||
GIT = git
|
||||
else
|
||||
PKG_FINALIZE = package_finalize.exe
|
||||
MAKE_SELF_WC = make_self_wc.exe
|
||||
MAKE_SELF = make_self_npdrm.exe
|
||||
PYTHON2 = python2.exe
|
||||
GIT = git.exe
|
||||
endif
|
||||
|
||||
PPU_SRCS = console/griffin/griffin.c \
|
||||
console/rzlib/rzlib.c
|
||||
|
||||
ifeq ($(HAVE_RGL), 1)
|
||||
DEFINES = -DHAVE_RGL
|
||||
GL_LIBS := -lrgl
|
||||
else
|
||||
GL_LIBS := -L$(CELL_SDK)/target/ppu/lib/PSGL/RSX/ultra-opt -lPSGL -lPSGLcgc
|
||||
endif
|
||||
|
||||
ifeq ($(CELL_BUILD_TOOLS), SNC)
|
||||
PPU_CXXLD = $(CELL_SDK)/host-win32/sn/bin/ps3ppuld.exe
|
||||
PPU_CXX = $(CELL_SDK)/host-win32/sn/bin/ps3ppusnc.exe
|
||||
PPU_CC = $(CELL_SDK)/host-win32/sn/bin/ps3ppusnc.exe
|
||||
else
|
||||
PPU_CXX = $(CELL_SDK)/host-win32/ppu/bin/ppu-lv2-g++.exe
|
||||
PPU_CC = $(CELL_SDK)/host-win32/ppu/bin/ppu-lv2-gcc.exe
|
||||
PPU_CXXLD = $(CELL_SDK)/host-win32/ppu/bin/ppu-lv2-ld.exe
|
||||
endif
|
||||
|
||||
|
||||
PPU_LDLIBS = -ldbgfont $(GL_LIBS) -lretro -lcgc -lgcm_cmd -lgcm_sys_stub -lresc_stub -lm -lio_stub -lfs_stub -lsysutil_stub -lsysutil_game_stub -lsysutil_screenshot_stub -lsysutil_np_stub -lpngdec_stub -ljpgdec_stub -lsysmodule_stub -laudio_stub -lnet_stub -lnetctl_stub -lpthread
|
||||
|
||||
DEFINES += -DRARCH_CONSOLE -DHAVE_OPENGL -DHAVE_OPENGL_TEXREF -DHAVE_HEADSET -DHAVE_VID_CONTEXT -DHAVE_OPENGLES -DHAVE_CG -DHAVE_CG_MENU -DHAVE_FILEBROWSER -DHAVE_FBO -DHAVE_RARCH_MAIN_WRAP -DHAVE_SYSMODULES -DHAVE_SYSUTILS -DHAVE_RARCH_EXEC -DHAVE_RGL -DHAVE_LIBRETRO_MANAGEMENT -DHAVE_RSOUND -DHAVE_ZLIB -D__CELLOS_LV2__ -DHAVE_CONFIGFILE=1 -DHAVE_NETPLAY=1 -DHAVE_SOCKET_LEGACY=1 -DHAVE_GRIFFIN=1 -DHAVE_MULTIMAN=1 -DPACKAGE_VERSION=\"$(RARCH_VERSION)\" -Dmain=rarch_main -DPC_DEVELOPMENT_IP_ADDRESS=\"$(PC_DEVELOPMENT_IP_ADDRESS)\" -DPC_DEVELOPMENT_UDP_PORT=$(PC_DEVELOPMENT_UDP_PORT)
|
||||
|
||||
ifeq ($(DEBUG), 1)
|
||||
PPU_OPTIMIZE_LV := -O0 -g
|
||||
else
|
||||
PPU_OPTIMIZE_LV := -O3 -g
|
||||
endif
|
||||
|
||||
PPU_CFLAGS = $(PPU_OPTIMIZE_LV) $(INCDIRS) $(DEFINES)
|
||||
PPU_CXXFLAGS = $(PPU_OPTIMIZE_LV) $(INCDIRS) $(DEFINES)
|
||||
|
||||
ifeq ($(HAVE_LOGGER), 1)
|
||||
PPU_CFLAGS += -DHAVE_LOGGER
|
||||
PPU_SRCS += console/logger/logger.c
|
||||
endif
|
||||
|
||||
EXIST_EBOOT_WILDCARD := $(wildcard $(EBOOT_PATH))
|
||||
EXIST_CORE_WILDCARD := $(wildcard $(CORE_PATH))
|
||||
|
||||
EBOOT_EXISTS = 1
|
||||
CORE_EXISTS = 1
|
||||
|
||||
ifneq ($(strip $(EXIST_EBOOT_WILDCARD)),)
|
||||
EBOOT_EXISTS = 0
|
||||
endif
|
||||
|
||||
ifneq ($(strip $(EXIST_CORE_WILDCARD)),)
|
||||
CORE_EXISTS = 0
|
||||
endif
|
||||
|
||||
include $(CELL_MK_DIR)/sdk.target.mk
|
||||
|
||||
MAKE_FSELF = $(CELL_SDK)/host-win32/bin/make_fself.exe
|
||||
MAKE_FSELF_NPDRM = $(CELL_SDK)/host-win32/bin/make_fself_npdrm.exe
|
||||
MAKE_PACKAGE_NPDRM = $(CELL_SDK)/host-win32/bin/make_package_npdrm.exe
|
||||
|
||||
.PHONY: create-selfs-npdrm create-npdrm-core create-core create-npdrm-salamander create-npdrm-salamander create-shaders clean-selfs
|
||||
|
||||
create-npdrm-core:
|
||||
$(MAKE_FSELF_NPDRM) $(PPU_TARGET) $(CORE_PATH)
|
||||
|
||||
create-core:
|
||||
$(MAKE_SELF_WC) $(PPU_TARGET) $(CORE_PATH)
|
||||
|
||||
create-npdrm-salamander:
|
||||
$(MAKE_FSELF_NPDRM) $(SALAMANDER_TARGET) $(EBOOT_PATH)
|
||||
|
||||
create-salamander:
|
||||
$(MAKE_SELF) $(SALAMANDER_TARGET) $(EBOOT_PATH) $(CONTENT_ID_FULL)
|
||||
|
||||
|
||||
create-shaders:
|
||||
ifeq ($(DOWNLOAD_SHADERS),1)
|
||||
$(RM) -rf ps3/pkg/USRDIR/cores/shaders
|
||||
$(GIT) clone git://github.com/libretro/common-shaders.git ps3/pkg/USRDIR/cores/shaders
|
||||
endif
|
||||
|
||||
pkg: $(PPU_TARGET) create-shaders create-npdrm-salamander create-npdrm-core
|
||||
$(MAKE_PACKAGE_NPDRM) ps3/pkg/package.conf ps3/pkg
|
||||
|
||||
pkg-signed: $(PPU_TARGET) create-shaders create-salamander create-core
|
||||
$(PYTHON2) $(PKG_SCRIPT) --contentid $(CONTENT_ID_FULL) ps3/pkg/ retroarch-ps3-cfw-$(RARCH_VERSION).pkg
|
||||
|
||||
pkg-signed-standalone: $(PPU_TARGET) create-shaders create-core
|
||||
$(MAKE_SELF) $(PPU_TARGET) $(EBOOT_PATH) $(CONTENT_ID)
|
||||
$(PYTHON2) $(PKG_SCRIPT) --contentid $(CONTENT_ID_FULL) ps3/pkg/ retroarch-ps3-cfw-$(RARCH_VERSION).pkg
|
||||
|
||||
pkg-signed-cfw: $(PPU_TARGET) create-shaders create-salamander create-core
|
||||
$(PYTHON2) $(PKG_SCRIPT) --contentid $(CONTENT_ID_FULL) ps3/pkg/ retroarch-ps3-cfw-$(RARCH_VERSION)-kmeaw.pkg
|
||||
$(PKG_FINALIZE) retroarch-ps3-cfw-$(RARCH_VERSION)-kmeaw.pkg
|
||||
|
||||
pkg-signed-cfw-standalone: $(PPU_TARGET) create-shaders create-core
|
||||
$(MAKE_SELF) $(PPU_TARGET) $(EBOOT_PATH) $(CONTENT_ID)
|
||||
$(PYTHON2) $(PKG_SCRIPT) --contentid $(CONTENT_ID_FULL) ps3/pkg/ retroarch-ps3-cfw-$(RARCH_VERSION).pkg
|
||||
$(PKG_FINALIZE) retroarch-ps3-cfw-$(RARCH_VERSION)-kmeaw.pkg
|
||||
|
||||
clean-selfs:
|
||||
ifeq ($(EBOOT_EXISTS),1)
|
||||
@echo "WARNING: Couldn't find file to delete: [$(EBOOT_PATH)], skipping this step."
|
||||
else
|
||||
rm $(EBOOT_PATH)
|
||||
endif
|
||||
ifeq ($(CORE_EXISTS),1)
|
||||
@echo "WARNING: Couldn't find file to delete: [$(CORE_PATH)], skipping this step."
|
||||
else
|
||||
rm $(CORE_PATH)
|
||||
endif
|
||||
@@ -0,0 +1,51 @@
|
||||
#which compiler to build with - GCC or SNC
|
||||
#set to GCC for debug builds for use with debugger
|
||||
CELL_BUILD_TOOLS = SNC
|
||||
CELL_GPU_TYPE = RSX
|
||||
|
||||
DEBUG = 0
|
||||
STRIPPING_ENABLE = 0
|
||||
|
||||
PC_DEVELOPMENT_IP_ADDRESS = "192.168.1.7"
|
||||
PC_DEVELOPMENT_UDP_PORT = 3490
|
||||
|
||||
CELL_MK_DIR ?= $(CELL_SDK)/samples/mk
|
||||
include $(CELL_MK_DIR)/sdk.makedef.mk
|
||||
|
||||
PPU_LIB_TARGET = librgl.a
|
||||
|
||||
LDDIRS = -L.
|
||||
INCDIRS = -I.
|
||||
|
||||
PPU_SRCS = console/rgl/ps3/device_ctx.cpp \
|
||||
console/rgl/ps3/rgl.cpp \
|
||||
console/rgl/ps3/cgbio.cpp \
|
||||
console/rgl/ps3/cgnv2rt.cpp
|
||||
|
||||
ifeq ($(CELL_BUILD_TOOLS), SNC)
|
||||
PPU_CXXLD = $(CELL_SDK)/host-win32/sn/bin/ps3ppuld.exe
|
||||
PPU_CXX = $(CELL_SDK)/host-win32/sn/bin/ps3ppusnc.exe
|
||||
PPU_CC = $(CELL_SDK)/host-win32/sn/bin/ps3ppusnc.exe
|
||||
SNC_PPU_AR = $(CELL_SDK)/host-win32/sn/bin/ps3snarl.exe
|
||||
else
|
||||
PPU_CXX = $(CELL_SDK)/host-win32/ppu/bin/ppu-lv2-g++.exe
|
||||
PPU_CC = $(CELL_SDK)/host-win32/ppu/bin/ppu-lv2-gcc.exe
|
||||
PPU_CXXLD = $(CELL_SDK)/host-win32/ppu/bin/ppu-lv2-ld.exe
|
||||
PPU_AR = $(CELL_SDK)/host-win32/ppu/bin/ppu-lv2-ar.exe
|
||||
endif
|
||||
|
||||
|
||||
PPU_LDLIBS = -lio_stub
|
||||
|
||||
DEFINES += -D__CELLOS_LV2__
|
||||
|
||||
ifeq ($(DEBUG), 1)
|
||||
PPU_OPTIMIZE_LV := -O0 -g
|
||||
else
|
||||
PPU_OPTIMIZE_LV := -O3
|
||||
endif
|
||||
|
||||
PPU_CFLAGS = $(PPU_OPTIMIZE_LV) $(INCDIRS) $(DEFINES)
|
||||
PPU_CXXFLAGS = $(PPU_OPTIMIZE_LV) $(INCDIRS) $(DEFINES)
|
||||
|
||||
include $(CELL_MK_DIR)/sdk.target.mk
|
||||
@@ -0,0 +1,35 @@
|
||||
CELL_BUILD_TOOLS = SNC
|
||||
CELL_SDK ?= /usr/local/cell
|
||||
HAVE_LOGGER = 0
|
||||
|
||||
include $(CELL_MK_DIR)/sdk.makedef.mk
|
||||
|
||||
STRIP = $(CELL_SDK)/host-win32/ppu/bin/ppu-lv2-strip.exe
|
||||
|
||||
PPU_CFLAGS += -I. -D__CELLOS_LV2__
|
||||
PPU_SRCS = console/salamander/main.c file_path.c compat/compat.c conf/config_file.c
|
||||
|
||||
ifeq ($(HAVE_LOGGER), 1)
|
||||
PPU_CFLAGS += -DHAVE_LOGGER
|
||||
PPU_SRCS += console/logger/logger.c
|
||||
endif
|
||||
|
||||
PPU_TARGET = retroarch-salamander.elf
|
||||
|
||||
ifeq ($(CELL_BUILD_TOOLS),SNC)
|
||||
PPU_CFLAGS += -Xbranchless=1 -Xfastmath=1 -Xassumecorrectsign=1 -Xassumecorrectalignment=1 -Xunroll=1 -Xautovecreg=1
|
||||
PPU_CXXFLAGS += -Xbranchless=1 -Xfastmath=1 -Xassumecorrectsign=1 -Xassumecorrectalignment=1 -Xunroll=1 -Xautovecreg=1
|
||||
PPU_CXXLD = $(CELL_SDK)/host-win32/sn/bin/ps3ppuld.exe
|
||||
PPU_CXX = $(CELL_SDK)/host-win32/sn/bin/ps3ppusnc.exe
|
||||
PPU_CC = $(CELL_SDK)/host-win32/sn/bin/ps3ppusnc.exe
|
||||
else
|
||||
PPU_CXX = $(CELL_SDK)/host-win32/ppu/bin/ppu-lv2-g++.exe
|
||||
PPU_CC = $(CELL_SDK)/host-win32/ppu/bin/ppu-lv2-gcc.exe
|
||||
PPU_CXXLD = $(CELL_SDK)/host-win32/ppu/bin/ppu-lv2-ld.exe
|
||||
endif
|
||||
|
||||
PPU_LDLIBS += -lm -lnet_stub -lnetctl_stub -lio_stub -lsysmodule_stub -lsysutil_stub -lsysutil_game_stub -lfs_stub -lsysutil_np_stub
|
||||
|
||||
PPU_OPTIMIZE_LV := -O2
|
||||
|
||||
include $(CELL_MK_DIR)/sdk.target.mk
|
||||
@@ -0,0 +1,70 @@
|
||||
###
|
||||
##
|
||||
# Makefile for RetroArch Wii.
|
||||
##
|
||||
|
||||
DEBUG = 0
|
||||
HAVE_LOGGER = 0
|
||||
HAVE_FILE_LOGGER = 0
|
||||
|
||||
PC_DEVELOPMENT_IP_ADDRESS = "192.168.1.7"
|
||||
PC_DEVELOPMENT_UDP_PORT = 3490
|
||||
|
||||
CC = $(DEVKITPPC)/bin/powerpc-eabi-gcc
|
||||
CXX = $(DEVKITPPC)/bin/powerpc-eabi-g++
|
||||
LD = $(DEVKITPPC)/bin/powerpc-eabi-ld
|
||||
|
||||
DOL_TARGET := ssnes.dol
|
||||
ELF_TARGET := ssnes.elf
|
||||
|
||||
INCLUDE := -I. -I$(DEVKITPRO)/libogc/include
|
||||
LIBDIRS := -L$(DEVKITPRO)/libogc/lib/wii -L.
|
||||
|
||||
MACHDEP := -DGEKKO -DHW_RVL -mrvl -mcpu=750 -meabi -mhard-float
|
||||
CFLAGS += -Wall -std=gnu99 $(MACHDEP) $(INCLUDE)
|
||||
CXXFLAGS += -Wall -std=gnu99 $(MACHDEP) $(INCLUDE)
|
||||
LDFLAGS := $(MACHDEP)
|
||||
LIBS := -lfat -lretro -lwiiuse -logc -lbte -lfreetype
|
||||
|
||||
OBJ = console/griffin/griffin.o console/font.bmpobj console/rzlib/rzlib.o
|
||||
|
||||
ifeq ($(HAVE_LOGGER), 1)
|
||||
CFLAGS += -DHAVE_LOGGER
|
||||
OBJ += console/logger/logger.o
|
||||
endif
|
||||
|
||||
ifeq ($(HAVE_FILE_LOGGER), 1)
|
||||
CFLAGS += -DHAVE_FILE_LOGGER
|
||||
endif
|
||||
|
||||
CFLAGS += -std=gnu99 -DRARCH_CONSOLE -DHAVE_CONFIGFILE=1 -DGEKKO -DHW_RVL -DHAVE_ZLIB -DHAVE_RARCH_MAIN_WRAP -DHAVE_FREETYPE -DHAVE_GRIFFIN=1 -DPACKAGE_VERSION=\"0.9.6\" -Dmain=ssnes_main -Wno-char-subscripts -DPC_DEVELOPMENT_IP_ADDRESS=\"$(PC_DEVELOPMENT_IP_ADDRESS)\" -DPC_DEVELOPMENT_UDP_PORT=$(PC_DEVELOPMENT_UDP_PORT)
|
||||
|
||||
ifeq ($(DEBUG), 1)
|
||||
CFLAGS += -O0 -g
|
||||
CXXFLAGS += -O0 -g
|
||||
else
|
||||
CLFAGS += -O3
|
||||
CXXFLAGS += -O3
|
||||
endif
|
||||
|
||||
all: $(DOL_TARGET)
|
||||
|
||||
%.dol: %.elf
|
||||
$(DEVKITPPC)/bin/elf2dol $< $@
|
||||
|
||||
$(ELF_TARGET): $(OBJ)
|
||||
$(CXX) -o $@ $(LDFLAGS) $(LIBDIRS) $(OBJ) $(LIBS)
|
||||
|
||||
%.o: %.c
|
||||
$(CC) $(CFLAGS) -c -o $@ $<
|
||||
|
||||
%.bmpobj: %.bmp
|
||||
$(LD) -r -b binary -o $@ $<
|
||||
|
||||
clean:
|
||||
rm -f $(DOL_TARGET)
|
||||
rm -f $(ELF_TARGET)
|
||||
rm -f $(OBJ)
|
||||
|
||||
.PHONY: clean
|
||||
|
||||
+213
@@ -0,0 +1,213 @@
|
||||
TARGET = retroarch.exe
|
||||
JTARGET = retroarch-joyconfig.exe
|
||||
OBJ = retroarch.o file.o file_path.o driver.o conf/config_file.o settings.o hash.o dynamic.o message.o rewind.o movie.o gfx/gfx_common.o patch.o compat/compat.o screenshot.o audio/utils.o
|
||||
JOBJ = conf/config_file.o tools/retroarch-joyconfig.o compat/compat.o
|
||||
|
||||
CC = gcc
|
||||
CXX = g++
|
||||
|
||||
HAVE_DINPUT = 1
|
||||
HAVE_XAUDIO = 1
|
||||
HAVE_DSOUND = 1
|
||||
HAVE_SDL = 1
|
||||
HAVE_OPENGL = 1
|
||||
HAVE_DYLIB = 1
|
||||
HAVE_NETPLAY = 1
|
||||
HAVE_THREADS = 1
|
||||
DYNAMIC = 1
|
||||
|
||||
ifeq ($(SLIM),)
|
||||
HAVE_SDL_IMAGE = 1
|
||||
HAVE_XML = 1
|
||||
HAVE_FREETYPE = 1
|
||||
HAVE_RSOUND = 1
|
||||
HAVE_FBO = 1
|
||||
HAVE_CG = 1
|
||||
HAVE_PYTHON = 1
|
||||
HAVE_FFMPEG = 1
|
||||
endif
|
||||
|
||||
libretro ?= -lretro
|
||||
|
||||
LIBS = -lm
|
||||
DEFINES = -I. -DHAVE_CONFIGFILE -DHAVE_SDL -DHAVE_SCREENSHOTS -DHAVE_BSV_MOVIE -DPACKAGE_VERSION=\"0.9.6\"
|
||||
LDFLAGS = -L. -static-libgcc
|
||||
LDCXXFLAGS = -s
|
||||
|
||||
ifeq ($(TDM_GCC),)
|
||||
LDCXXFLAGS += -static-libstdc++
|
||||
endif
|
||||
|
||||
ifeq ($(HAVE_SDL), 1)
|
||||
OBJ += gfx/sdl_gfx.o gfx/gl.o gfx/fonts/freetype.o gfx/context/sdl_ctx.o input/sdl_input.o audio/sdl_audio.o fifo_buffer.o
|
||||
LIBS += -lSDL
|
||||
DEFINES += -ISDL -DHAVE_SDL
|
||||
endif
|
||||
|
||||
ifeq ($(HAVE_THREADS), 1)
|
||||
OBJ += autosave.o thread.o
|
||||
DEFINES += -DHAVE_THREADS
|
||||
endif
|
||||
|
||||
ifeq ($(HAVE_OPENGL), 1)
|
||||
DEFINES += -DHAVE_OPENGL
|
||||
LIBS += -lopengl32
|
||||
endif
|
||||
|
||||
ifeq ($(HAVE_SDL_IMAGE), 1)
|
||||
LIBS += -lSDL_image
|
||||
DEFINES += -DHAVE_SDL_IMAGE
|
||||
endif
|
||||
|
||||
ifeq ($(HAVE_CG), 1)
|
||||
OBJ += gfx/shader_cg.o
|
||||
LIBS += -lcg -lcgGL
|
||||
DEFINES += -DHAVE_CG
|
||||
endif
|
||||
|
||||
ifeq ($(HAVE_XAUDIO), 1)
|
||||
OBJ += audio/xaudio.o audio/xaudio-c/xaudio-c.o
|
||||
DEFINES += -DHAVE_XAUDIO
|
||||
LIBS += -lole32
|
||||
endif
|
||||
|
||||
ifeq ($(HAVE_DSOUND), 1)
|
||||
OBJ += audio/dsound.o
|
||||
DEFINES += -DHAVE_DSOUND
|
||||
LIBS += -ldxguid -ldsound
|
||||
endif
|
||||
|
||||
ifeq ($(HAVE_RSOUND), 1)
|
||||
OBJ += audio/rsound.o
|
||||
DEFINES += -DHAVE_RSOUND
|
||||
LIBS += -lrsound
|
||||
endif
|
||||
|
||||
ifeq ($(HAVE_XML), 1)
|
||||
OBJ += gfx/shader_glsl.o gfx/image.o gfx/state_tracker.o cheats.o
|
||||
DEFINES += -Ilibxml2 -DHAVE_XML
|
||||
LIBS += -lxml2 -liconv
|
||||
endif
|
||||
|
||||
ifeq ($(HAVE_DYLIB), 1)
|
||||
DEFINES += -DHAVE_DYLIB
|
||||
endif
|
||||
|
||||
ifeq ($(HAVE_NETPLAY), 1)
|
||||
DEFINES += -DHAVE_NETPLAY
|
||||
OBJ += netplay.o network_cmd.o
|
||||
LIBS += -lws2_32
|
||||
endif
|
||||
|
||||
ifeq ($(HAVE_FREETYPE), 1)
|
||||
OBJ += gfx/fonts/fonts.o
|
||||
DEFINES += -DHAVE_FREETYPE -Ifreetype2
|
||||
LIBS += -lfreetype -lz
|
||||
endif
|
||||
|
||||
ifeq ($(DYNAMIC), 1)
|
||||
DEFINES += -DHAVE_DYNAMIC
|
||||
else
|
||||
LIBS += $(libretro)
|
||||
endif
|
||||
|
||||
ifeq ($(HAVE_FBO), 1)
|
||||
DEFINES += -DHAVE_FBO
|
||||
endif
|
||||
|
||||
ifeq ($(HAVE_DYLIB), 1)
|
||||
OBJ += gfx/ext_gfx.o audio/ext_audio.o
|
||||
endif
|
||||
|
||||
ifeq ($(HAVE_PYTHON), 1)
|
||||
LIBS += -lpython32
|
||||
DEFINES += -DHAVE_PYTHON -Ipython
|
||||
OBJ += gfx/py_state/py_state.o
|
||||
endif
|
||||
|
||||
ifeq ($(HAVE_DINPUT), 1)
|
||||
LIBS += -ldinput8 -ldxguid -lole32
|
||||
DEFINES += -DHAVE_DINPUT
|
||||
OBJ += input/dinput.o
|
||||
endif
|
||||
|
||||
ifeq ($(HAVE_FFMPEG), 1)
|
||||
LIBS += -lavformat -lavcodec -lavutil -lswscale -lws2_32 -lz
|
||||
DEFINES += -DHAVE_FFMPEG -Iffmpeg
|
||||
DEFINES += -DHAVE_FFMPEG_ALLOC_CONTEXT3
|
||||
DEFINES += -DHAVE_FFMPEG_AVCODEC_OPEN2
|
||||
DEFINES += -DHAVE_FFMPEG_AVIO_OPEN
|
||||
DEFINES += -DHAVE_FFMPEG_AVFORMAT_WRITE_HEADER
|
||||
DEFINES += -DHAVE_FFMPEG_AVFORMAT_NEW_STREAM
|
||||
DEFINES += -DHAVE_X264RGB
|
||||
OBJ += record/ffemu.o
|
||||
endif
|
||||
|
||||
ifeq ($(HAVE_SINC), 1)
|
||||
OBJ += audio/sinc.o
|
||||
else
|
||||
OBJ += audio/hermite.o
|
||||
endif
|
||||
|
||||
ifneq ($(V), 1)
|
||||
Q := @
|
||||
endif
|
||||
|
||||
CFLAGS += -Wall -Wno-unused-result -O3 -I.
|
||||
ifeq ($(CXX_BUILD), 1)
|
||||
CFLAGS += -std=c++0x -xc++ -D__STDC_CONSTANT_MACROS
|
||||
else
|
||||
CFLAGS += -std=gnu99
|
||||
endif
|
||||
|
||||
all: $(TARGET) $(JTARGET)
|
||||
|
||||
$(TARGET): $(OBJ)
|
||||
$(Q)$(CXX) -o $@ $(OBJ) $(LIBS) $(LDFLAGS) $(LDCXXFLAGS)
|
||||
@$(if $(Q), $(shell echo echo LD $@),)
|
||||
|
||||
%.o: %.c
|
||||
$(Q)$(CC) $(CFLAGS) $(DEFINES) -c -o $@ $<
|
||||
@$(if $(Q), $(shell echo echo CC $<),)
|
||||
|
||||
$(JTARGET): $(JOBJ)
|
||||
ifeq ($(CXX_BUILD), 1)
|
||||
$(Q)$(CXX) -o $@ $(JOBJ) -lSDL $(LDFLAGS)
|
||||
else
|
||||
$(Q)$(CC) -o $@ $(JOBJ) -lSDL $(LDFLAGS)
|
||||
endif
|
||||
@$(if $(Q), $(shell echo echo LD $@),)
|
||||
|
||||
clean:
|
||||
rm -f *.o
|
||||
rm -f audio/*.o
|
||||
rm -f audio/xaudio-c/*.o
|
||||
rm -f conf/*.o
|
||||
rm -f gfx/*.o
|
||||
rm -f gfx/py_state/*.o
|
||||
rm -f record/*.o
|
||||
rm -f input/*.o
|
||||
rm -f $(TARGET)
|
||||
rm -f retroarch-joyconfig.exe
|
||||
rm -f tools/*.o
|
||||
|
||||
dist_x86: all
|
||||
zip -r retroarch-win32-0.9.6.zip $(TARGET) $(JTARGET) retroarch.cfg SDL.dll
|
||||
|
||||
dist_x86_64: all
|
||||
zip -r retroarch-win64-0.9.6.zip $(TARGET) $(JTARGET) retroarch.cfg SDL.dll
|
||||
|
||||
libs_x86:
|
||||
wget https://github.com/downloads/Themaister/RetroArch/RetroArch-win32-libs.zip --no-check-certificate
|
||||
unzip RetroArch-win32-libs.zip
|
||||
wget https://github.com/downloads/Themaister/RetroArch/RetroArch-win32-headers.zip --no-check-certificate
|
||||
unzip RetroArch-win32-headers.zip
|
||||
|
||||
libs_x86_64:
|
||||
wget https://github.com/downloads/Themaister/RetroArch/RetroArch-win64-libs.zip --no-check-certificate
|
||||
unzip RetroArch-win64-libs.zip
|
||||
wget https://github.com/downloads/Themaister/RetroArch/RetroArch-win64-headers.zip --no-check-certificate
|
||||
unzip RetroArch-win64-headers.zip
|
||||
|
||||
.PHONY: all install uninstall clean dist_x86 dist_x86_64 libs_x86 libs_x86_64
|
||||
|
||||
@@ -1,93 +0,0 @@
|
||||
TARGET = ssnes.exe
|
||||
JTARGET = ssnes-joyconfig.exe
|
||||
OBJ = ssnes.o file.o driver.o conf/config_file.o settings.o dynamic.o message.o
|
||||
JOBJ = conf/config_file.o tools/main-stub.o tools/ssnes-joyconfig.o
|
||||
|
||||
CC = gcc
|
||||
CXX = g++
|
||||
|
||||
HAVE_SRC = 1
|
||||
HAVE_SDL = 1
|
||||
HAVE_XML = 1
|
||||
HAVE_FREETYPE = 1
|
||||
libsnes ?= -lsnes
|
||||
|
||||
LIBS =
|
||||
DEFINES = -I. -DHAVE_CONFIGFILE
|
||||
LDFLAGS = -L. -static-libgcc -s
|
||||
|
||||
SRC_LIBS = -lsamplerate-0
|
||||
SDL_LIBS = -lSDL
|
||||
SDL_CFLAGS = -ISDL
|
||||
|
||||
ifeq ($(HAVE_SRC), 1)
|
||||
LIBS += $(SRC_LIBS)
|
||||
DEFINES += $(SRC_CFLAGS) -DHAVE_SRC
|
||||
endif
|
||||
|
||||
ifeq ($(HAVE_SDL), 1)
|
||||
OBJ += gfx/gl.o input/sdl.o audio/sdl.o audio/buffer.o
|
||||
LIBS += $(SDL_LIBS) -lopengl32
|
||||
DEFINES += $(SDL_CFLAGS) -DHAVE_SDL
|
||||
endif
|
||||
|
||||
ifeq ($(HAVE_XML), 1)
|
||||
OBJ += gfx/shader_glsl.o
|
||||
DEFINES += $(XML_CFLAGS) -DHAVE_XML
|
||||
LIBS += -lxml2
|
||||
endif
|
||||
|
||||
ifeq ($(HAVE_FREETYPE), 1)
|
||||
OBJ += gfx/fonts.o
|
||||
DEFINES += -DHAVE_FREETYPE -Ifreetype2
|
||||
LIBS += -lz -lfreetype6
|
||||
endif
|
||||
|
||||
ifeq ($(DYNAMIC), 1)
|
||||
DEFINES += -DHAVE_DYNAMIC
|
||||
else
|
||||
LIBS += $(libsnes)
|
||||
endif
|
||||
|
||||
ifneq ($(V),1)
|
||||
Q := @
|
||||
endif
|
||||
|
||||
|
||||
CFLAGS = -Wall -O3 -std=gnu99 -I.
|
||||
|
||||
all: $(TARGET) $(JTARGET)
|
||||
|
||||
$(TARGET): $(OBJ)
|
||||
$(Q)$(CXX) -o $@ $(OBJ) $(LIBS) $(LDFLAGS)
|
||||
@$(if $(Q), $(shell echo echo LD $@),)
|
||||
|
||||
%.o: %.c
|
||||
$(Q)$(CC) $(CFLAGS) $(DEFINES) -c -o $@ $<
|
||||
@$(if $(Q), $(shell echo echo CC $<),)
|
||||
|
||||
$(JTARGET): $(JOBJ)
|
||||
$(Q)$(CC) -o $@ $(JOBJ) $(SDL_LIBS) $(LDFLAGS)
|
||||
@$(if $(Q), $(shell echo echo LD $@),)
|
||||
|
||||
clean:
|
||||
rm -f *.o
|
||||
rm -f audio/*.o
|
||||
rm -f conf/*.o
|
||||
rm -f gfx/*.o
|
||||
rm -f record/*.o
|
||||
rm -f hqflt/*.o
|
||||
rm -f input/*.o
|
||||
rm -f hqflt/snes_ntsc/*.o
|
||||
rm -f $(TARGET)
|
||||
rm -f ssnes-joyconfig.exe
|
||||
rm -f tools/*.o
|
||||
|
||||
dist: all
|
||||
zip -r ssnes-win32-0.2.zip $(TARGET) ssnes.cfg snes.dll libxml2.dll iconv.dll zlib1.dll SDL.dll libsamplerate-0.dll freetype6.dll $(JTARGET)
|
||||
|
||||
libs:
|
||||
wget https://github.com/downloads/Themaister/SSNES/SSNES-win32-libs.zip --no-check-certificate
|
||||
unzip SSNES-win32-libs.zip
|
||||
|
||||
.PHONY: all install uninstall clean dist libs
|
||||
@@ -0,0 +1,54 @@
|
||||
###
|
||||
##
|
||||
# Makefile for RetroArch libxenon.
|
||||
##
|
||||
###
|
||||
##
|
||||
|
||||
DEBUG = 0
|
||||
|
||||
CC = xenon-gcc
|
||||
CXX = xenon-g++
|
||||
OBJCOPY = xenon-objcopy
|
||||
STRIP = xenon-strip
|
||||
|
||||
PPU_TARGET := retroarch-libxenon.elf
|
||||
PPU_TARGET_ADJUSTED := retroarch-libxenon.elf32
|
||||
|
||||
LDDIRS = -L. -L$(DEVKITXENON)/usr/lib -L$(DEVKITXENON)/xenon/lib/32
|
||||
INCDIRS = -I. -I$(DEVKITXENON)/usr/include
|
||||
|
||||
OBJ = fifo_buffer.o retroarch.o driver.o file.o file_path.o settings.o message.o rewind.o movie.o gfx/gfx_common.o patch.o compat/compat.o screenshot.o audio/hermite.o dynamic.o audio/utils.o conf/config_file.o xenon/main.o xenon/xenon360_audio.o xenon/xenon360_input.o xenon/xenon360_video.o
|
||||
|
||||
LIBS = -lretro -lxenon -lm -lc
|
||||
DEFINES = -std=gnu99 -DHAVE_CONFIGFILE=1 -DPACKAGE_VERSION=\"0.9.6\" -DRARCH_CONSOLE -DHAVE_GETOPT_LONG=1 -Dmain=rarch_main
|
||||
DEFINES += -maltivec -mhard-float -m32 -mpowerpc64 -mcpu=cell -mtune=cell -fno-pic -g -Wall -DXENON $(INCDIRS)
|
||||
DEFINES += -u read -u _start -u exc_base
|
||||
|
||||
ifeq ($(DEBUG), 1)
|
||||
OPTIMIZE_LV := -O0 -g
|
||||
else
|
||||
OPTIMIZE_LV := -O3
|
||||
endif
|
||||
|
||||
all: $(PPU_TARGET_ADJUSTED)
|
||||
|
||||
CFLAGS := $(OPTIMIZE_LV) $(DEFINES)
|
||||
|
||||
LDFLAGS := -m32 -n -T $(DEVKITXENON)/app.lds
|
||||
|
||||
$(PPU_TARGET_ADJUSTED): $(PPU_TARGET)
|
||||
$(OBJCOPY) -O elf32-powerpc --adjust-vma 0x80000000 $< $@
|
||||
$(STRIP) $@
|
||||
|
||||
$(PPU_TARGET): $(OBJ)
|
||||
$(CXX) -o $@ $(OBJ) $(LDFLAGS) $(LDDIRS) $(LIBS)
|
||||
|
||||
%.o: %.c config.h
|
||||
$(CC) $(CFLAGS) -c -o $@ $<
|
||||
|
||||
clean:
|
||||
rm -f $(PPU_TARGET)
|
||||
rm -f $(OBJ)
|
||||
|
||||
.PHONY: clean
|
||||
@@ -1,32 +1,56 @@
|
||||
# SSNES
|
||||
# RetroArch
|
||||
|
||||
SSNES is a simple frontend for the libsnes library.
|
||||
RetroArch (formerly known as SSNES) is a simple frontend for the libretro API. An API that attempts to generalize
|
||||
a retro gaming system, such as SNES, NES, GameBoy, Arcade machines, etc.
|
||||
Emulator/game cores are instantiated as loadable plugins.
|
||||
|
||||
# libsnes
|
||||
# libretro
|
||||
|
||||
libsnes is the emulator core of [bSNES](http://www.byuu.org), the most accurate SNES emulator to date, in library form. The libsnes API has been implemented by SNES9x as well, allowing multiple different cores to be used for an emulator that supports libsnes.
|
||||
This enables the possibility of custom front-ends for the emulator.
|
||||
libretro is an API that exposes the core of a retro gaming system.
|
||||
A frontend for libretro handles video output, audio output and input.
|
||||
A libretro core written in portable C or C++ can run seamlessly on many platforms.
|
||||
|
||||
[libretro API header](https://github.com/Themaister/RetroArch/blob/master/libretro.h)
|
||||
|
||||
# Binaries
|
||||
|
||||
Latest Windows binaries are currently hosted on my [homepage](http://themaister.net/retroarch.html).
|
||||
|
||||
# Related projects
|
||||
|
||||
- GUI frontend for PC: [RetroArch-Phoenix](https://github.com/Themaister/RetroArch-Phoenix)
|
||||
- Cg/HLSL shaders: [common-shaders](https://github.com/twinaphex/common-shaders)
|
||||
- More Cg shaders: [Emulator-Shader-Pack](https://github.com/Themaister/Emulator-Shader-Pack)
|
||||
- Helper scripts to build libretro implementations: [libretro-super](https://github.com/libretro/libretro-super)
|
||||
|
||||
# Philosophy
|
||||
|
||||
SSNES attempts to be very small and lean, while still having all the useful core features expected from an emulator.
|
||||
It is used through command-line.
|
||||
RetroArch attempts to be very small and lean,
|
||||
while still having all the useful core features expected from an emulator.
|
||||
It is used through command-line. It is also designed to be portable.
|
||||
|
||||
# Dependencies
|
||||
# Platforms
|
||||
|
||||
SSNES requires these libraries to build:
|
||||
RetroArch has been ported to the following platforms outside PC:
|
||||
|
||||
- PlayStation3
|
||||
- Xbox 360 (Libxenon/XeXDK)
|
||||
- Wii (Libogc)
|
||||
|
||||
# Dependencies (PC)
|
||||
|
||||
RetroArch requires these libraries to build:
|
||||
|
||||
- [libsnes](http://byuu.org/bsnes/)
|
||||
- SDL
|
||||
- libsamplerate
|
||||
|
||||
SSNES can utilize these libraries if enabled:
|
||||
RetroArch can utilize these libraries if enabled:
|
||||
|
||||
- nvidia-cg-toolkit
|
||||
- libxml2 (bSNES XML shaders)
|
||||
- libfreetype2 (TTF font rendering on screen)
|
||||
- libsamplerate
|
||||
|
||||
SSNES needs one of these audio driver libraries:
|
||||
RetroArch needs at least one of these audio driver libraries:
|
||||
|
||||
- ALSA
|
||||
- OSS
|
||||
@@ -35,61 +59,90 @@ SSNES needs one of these audio driver libraries:
|
||||
- OpenAL
|
||||
- JACK
|
||||
- SDL
|
||||
- XAudio2 (Win32)
|
||||
- PulseAudio
|
||||
|
||||
# Building libsnes
|
||||
To run properly, RetroArch requires a libretro implementation present, however, as it's typically loaded
|
||||
dynamically, it's not required at build time.
|
||||
|
||||
- Download bSNES source (link over).
|
||||
- Add -fPIC to flags in Makefile.
|
||||
- <tt>$ make library profile=performance</tt> (accuracy, compatibility are the other profiles. compatibility is a great choice for decent PCs. :D)
|
||||
- <tt># make prefix=/usr library-install</tt>
|
||||
- <tt># cp snes/libsnes/libsnes.hpp /usr/include/</tt>
|
||||
- ?!?!
|
||||
- Profit!
|
||||
# Dependencies (Console ports)
|
||||
|
||||
Console ports have their own dependencies, but generally do not require
|
||||
anything other than what the respective SDKs provide.
|
||||
|
||||
# Configuring
|
||||
|
||||
The default configuration is defined in config.def.h.
|
||||
These can later be tweaked by using the ssnes config file.
|
||||
A sample configuration file is installed to /etc/ssnes.cfg.
|
||||
These can later be tweaked by using a config file.
|
||||
A sample configuration file is installed to /etc/retroarch.cfg.
|
||||
This is the system-wide config file.
|
||||
Each user should create a config file in $XDG\_CONFIG\_HOME/ssnes/ssnes.cfg.
|
||||
Each user should create a config file in $XDG\_CONFIG\_HOME/retroarch/retroarch.cfg.
|
||||
The users only need to configure a certain option if the desired value deviates from the value defined in config.def.h.
|
||||
|
||||
To configure joypads, start up <tt>jstest /dev/input/js0</tt> to determine which joypad buttons (and axis) to use. It is also possible to use the <tt>ssnes-joyconfig</tt> tool as well for simple configuration.
|
||||
To configure joypads, use the <tt>retroarch-joyconfig</tt> tool.
|
||||
It is also possible to configure joypads using the RetroArch-Phoenix GUI frontend.
|
||||
|
||||
# Compiling and installing
|
||||
|
||||
<b>Linux/Unix</b><br/>
|
||||
As most packages, SSNES is built using the standard <tt>./configure && make && make install</tt>
|
||||
Do note that the build system is not autotools based, but resembles it.
|
||||
<b>PC</b><br/>
|
||||
Instructions for compiling on PC can be found in the [wiki](https://github.com/Themaister/RetroArch/wiki).
|
||||
|
||||
Notable options for ./configure:
|
||||
--with-libsnes=: Normally libsnes is located with -lsnes, however, this can be overridden.
|
||||
--enable-dynamic: Do not link to libsnes at compile time, but load libsnes dynamically at runtime. libsnes\_path in config file defines which library to load. Useful for development.
|
||||
<b>PlayStation3</b><br/>
|
||||
|
||||
Do note that these two options are mutually exclusive.
|
||||
RetroArch PS3 needs to be compiled in the following order:
|
||||
|
||||
<b>Win32</b><br/>
|
||||
It is possible with MinGW to compile for Windows in either msys or Linux/Unix based systems. Do note that Windows build uses a static Makefile since configuration scripts create more harm than good on this platform. Libraries, headers, etc, needed to compile and run SSNES can be fetched with a Makefile target.
|
||||
1) Compile RetroArch Salamander
|
||||
|
||||
In Linux/Unix:<br/>
|
||||
<tt>make -f Makefile.win32 libs</tt></br>
|
||||
<tt>make -f Makefile.win32 CC=i486-mingw32-gcc CXX=i486-mingw32-g++</tt></br>
|
||||
<tt>make -f Makefile.ps3.salamander</tt>
|
||||
|
||||
In MSYS:
|
||||
<tt>mingw32-make -f Makefile.win32 libs</tt>. # You will need to have wget in your patch for this command! MSYS should provide this.</br>
|
||||
<tt>mingw32-make -f Makefile.win32</tt>
|
||||
2) Compile the RGL video driver
|
||||
|
||||
<tt>make -f Makefile.ps3.rgl</tt>
|
||||
|
||||
3) Finally, compile RetroArch itself
|
||||
|
||||
# Filters, bSNES XML shaders and Cg shader support
|
||||
<tt>make -f Makefile.ps3</tt>
|
||||
|
||||
This is not strictly not necessary for an emulator, but it can be enabled if desired.
|
||||
For best performance, Cg shaders or bSNES XML shaders are recommended as they do not eat up valuable CPU time (assuming your GPU can handle the shaders).
|
||||
Cg shaders and XML shaders (GLSL) are compiled at run-time.
|
||||
All shaders share a common interface to pass some essential arguments such as texture size and viewport size. (Common for pixel art scalers)
|
||||
Some Cg shaders are included in hqflt/cg/ and could be used as an example.
|
||||
bSNES XML shaders can be found on various places on the net. Best place to start looking are the bSNES forums.
|
||||
Finally, you can add one of the following parameters to the above line in order to make a PKG file:
|
||||
|
||||
The Cg shaders closely resemble the GLSL shaders found in bSNES shader pack, so porting them is trivial if desired.
|
||||
<tt>make -f Makefile.ps3 pkg</tt>
|
||||
|
||||
This creates an NPDRM package. This can be installed on debug PS3s.
|
||||
|
||||
To make a non-NPDRM package that can be installed on a jailbroken/CFW PS3 (such as PSGroove or PS3 CFWs and other 3.55 CFW derivatives), do:
|
||||
|
||||
<tt>make -f Makefile.ps3 pkg-signed</tt>
|
||||
|
||||
If you're using Kmeaw 3.55 firmware, the package needs to be signed:
|
||||
|
||||
<tt>make -f Makefile.ps3 pkg-signed-cfw</tt>
|
||||
|
||||
NOTE: A pre-existing libretro library needs to be present in the root directory in order to link RetroArch PS3. This file needs to be called 'libretro.a'.
|
||||
|
||||
<b> Xbox 360 (XeXDK)</b><br />
|
||||
|
||||
You will need Microsoft Visual Studio 2010 installed (or higher) in order to compile RetroArch 360.
|
||||
|
||||
The solution file can be found at the following location:
|
||||
|
||||
<tt>msvc-360/RetroArch-360.sln</tt>
|
||||
|
||||
NOTE: A pre-existing libretro library needs to be present in the 'msvc-360/RetroArch-360/Release' directory in order to link RetroArch 360. This file needs to be
|
||||
called 'libretro.lib'.
|
||||
|
||||
<b> Xbox 360 (Libxenon)</b><br />
|
||||
|
||||
You will need to have the libxenon libraries and a working Devkit Xenon toolchain installed in order to compile RetroArch 360 Libxenon.
|
||||
|
||||
<tt>make -f Makefile.xenon</tt>
|
||||
|
||||
NOTE: A pre-existing libretro library needs to be present in the root directory in order to link RetroArch 360 Libxenon. This file needs to be called 'libretro.a'.
|
||||
|
||||
<b> Wii</b><br >
|
||||
|
||||
You will need to have the libogc libraries and a working Devkit PPC toolchain installed in order to compile RetroArch Wii.
|
||||
|
||||
<tt>make -f Makefile.wii</tt>
|
||||
|
||||
NOTE: A pre-existing libretro library needs to be present in the root directory in order to link RetroArch Wii. This file needs to be called 'libretro.a'.
|
||||
|
||||
+78
-65
@@ -1,27 +1,25 @@
|
||||
/* SSNES - A Super Nintendo Entertainment System (SNES) Emulator frontend for libsnes.
|
||||
* Copyright (C) 2010-2011 - Hans-Kristian Arntzen
|
||||
*
|
||||
* Some code herein may be based on code found in BSNES.
|
||||
/* RetroArch - A frontend for libretro.
|
||||
* Copyright (C) 2010-2012 - Hans-Kristian Arntzen
|
||||
*
|
||||
* SSNES is free software: you can redistribute it and/or modify it under the terms
|
||||
* RetroArch is free software: you can redistribute it and/or modify it under the terms
|
||||
* of the GNU General Public License as published by the Free Software Found-
|
||||
* ation, either version 3 of the License, or (at your option) any later version.
|
||||
*
|
||||
* SSNES is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
|
||||
* RetroArch is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
|
||||
* without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
|
||||
* PURPOSE. See the GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along with SSNES.
|
||||
* You should have received a copy of the GNU General Public License along with RetroArch.
|
||||
* If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
|
||||
#include "driver.h"
|
||||
#include "../driver.h"
|
||||
#include <stdlib.h>
|
||||
#include <alsa/asoundlib.h>
|
||||
#include "general.h"
|
||||
#include <asoundlib.h>
|
||||
#include "../general.h"
|
||||
|
||||
#define TRY_ALSA(x) if ( x < 0 ) { \
|
||||
#define TRY_ALSA(x) if (x < 0) { \
|
||||
goto error; \
|
||||
}
|
||||
|
||||
@@ -30,11 +28,13 @@ typedef struct alsa
|
||||
snd_pcm_t *pcm;
|
||||
bool nonblock;
|
||||
bool has_float;
|
||||
|
||||
size_t buffer_size;
|
||||
} alsa_t;
|
||||
|
||||
static bool __alsa_use_float(void *data)
|
||||
static bool alsa_use_float(void *data)
|
||||
{
|
||||
alsa_t *alsa = data;
|
||||
alsa_t *alsa = (alsa_t*)data;
|
||||
return alsa->has_float;
|
||||
}
|
||||
|
||||
@@ -42,34 +42,37 @@ static bool find_float_format(snd_pcm_t *pcm, snd_pcm_hw_params_t *params)
|
||||
{
|
||||
if (snd_pcm_hw_params_test_format(pcm, params, SND_PCM_FORMAT_FLOAT) == 0)
|
||||
{
|
||||
SSNES_LOG("ALSA: Using floating point format.\n");
|
||||
RARCH_LOG("ALSA: Using floating point format.\n");
|
||||
return true;
|
||||
}
|
||||
SSNES_LOG("ALSA: Using signed 16-bit format.\n");
|
||||
RARCH_LOG("ALSA: Using signed 16-bit format.\n");
|
||||
return false;
|
||||
}
|
||||
|
||||
static void* __alsa_init(const char* device, int rate, int latency)
|
||||
static void *alsa_init(const char *device, unsigned rate, unsigned latency)
|
||||
{
|
||||
alsa_t *alsa = calloc(1, sizeof(alsa_t));
|
||||
if ( alsa == NULL )
|
||||
alsa_t *alsa = (alsa_t*)calloc(1, sizeof(alsa_t));
|
||||
if (!alsa)
|
||||
return NULL;
|
||||
|
||||
snd_pcm_hw_params_t *params = NULL;
|
||||
snd_pcm_sw_params_t *sw_params = NULL;
|
||||
|
||||
const char *alsa_dev = "default";
|
||||
if ( device != NULL )
|
||||
if (device)
|
||||
alsa_dev = device;
|
||||
|
||||
unsigned latency_usec = latency * 1000;
|
||||
unsigned channels = 2;
|
||||
unsigned periods = 4;
|
||||
snd_pcm_uframes_t buffer_size;
|
||||
snd_pcm_format_t format;
|
||||
|
||||
TRY_ALSA(snd_pcm_open(&alsa->pcm, alsa_dev, SND_PCM_STREAM_PLAYBACK, SND_PCM_NONBLOCK));
|
||||
|
||||
unsigned int latency_usec = latency * 1000;
|
||||
|
||||
TRY_ALSA(snd_pcm_hw_params_malloc(¶ms));
|
||||
alsa->has_float = find_float_format(alsa->pcm, params);
|
||||
snd_pcm_format_t format = alsa->has_float ? SND_PCM_FORMAT_FLOAT : SND_PCM_FORMAT_S16;
|
||||
unsigned int channels = 2;
|
||||
format = alsa->has_float ? SND_PCM_FORMAT_FLOAT : SND_PCM_FORMAT_S16;
|
||||
|
||||
TRY_ALSA(snd_pcm_hw_params_any(alsa->pcm, params));
|
||||
TRY_ALSA(snd_pcm_hw_params_set_access(alsa->pcm, params, SND_PCM_ACCESS_RW_INTERLEAVED));
|
||||
@@ -78,16 +81,15 @@ static void* __alsa_init(const char* device, int rate, int latency)
|
||||
TRY_ALSA(snd_pcm_hw_params_set_rate(alsa->pcm, params, rate, 0));
|
||||
|
||||
TRY_ALSA(snd_pcm_hw_params_set_buffer_time_near(alsa->pcm, params, &latency_usec, NULL));
|
||||
unsigned periods = 4;
|
||||
TRY_ALSA(snd_pcm_hw_params_set_periods_near(alsa->pcm, params, &periods, NULL));
|
||||
|
||||
TRY_ALSA(snd_pcm_hw_params(alsa->pcm, params));
|
||||
|
||||
snd_pcm_uframes_t buffer_size;
|
||||
snd_pcm_hw_params_get_period_size(params, &buffer_size, NULL);
|
||||
SSNES_LOG("ALSA: Period size: %d frames\n", (int)buffer_size);
|
||||
RARCH_LOG("ALSA: Period size: %d frames\n", (int)buffer_size);
|
||||
snd_pcm_hw_params_get_buffer_size(params, &buffer_size);
|
||||
SSNES_LOG("ALSA: Buffer size: %d frames\n", (int)buffer_size);
|
||||
RARCH_LOG("ALSA: Buffer size: %d frames\n", (int)buffer_size);
|
||||
alsa->buffer_size = snd_pcm_frames_to_bytes(alsa->pcm, buffer_size);
|
||||
|
||||
TRY_ALSA(snd_pcm_sw_params_malloc(&sw_params));
|
||||
TRY_ALSA(snd_pcm_sw_params_current(alsa->pcm, sw_params));
|
||||
@@ -100,7 +102,7 @@ static void* __alsa_init(const char* device, int rate, int latency)
|
||||
return alsa;
|
||||
|
||||
error:
|
||||
SSNES_ERR("ALSA: Failed to initialize...\n");
|
||||
RARCH_ERR("ALSA: Failed to initialize...\n");
|
||||
if (params)
|
||||
snd_pcm_hw_params_free(params);
|
||||
|
||||
@@ -117,21 +119,20 @@ error:
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static ssize_t __alsa_write(void* data, const void* buf, size_t size)
|
||||
static ssize_t alsa_write(void *data, const void *buf_, size_t size_)
|
||||
{
|
||||
alsa_t *alsa = data;
|
||||
alsa_t *alsa = (alsa_t*)data;
|
||||
const uint8_t *buf = (const uint8_t*)buf_;
|
||||
|
||||
snd_pcm_sframes_t frames;
|
||||
snd_pcm_sframes_t written = 0;
|
||||
int rc;
|
||||
size = snd_pcm_bytes_to_frames(alsa->pcm, size); // Frames to write
|
||||
snd_pcm_sframes_t size = snd_pcm_bytes_to_frames(alsa->pcm, size_);
|
||||
|
||||
while (written < size)
|
||||
while (size)
|
||||
{
|
||||
if (!alsa->nonblock)
|
||||
{
|
||||
rc = snd_pcm_wait(alsa->pcm, -1);
|
||||
if (rc == -EPIPE || rc == -ESTRPIPE)
|
||||
int rc = snd_pcm_wait(alsa->pcm, -1);
|
||||
if (rc == -EPIPE || rc == -ESTRPIPE || rc == -EINTR)
|
||||
{
|
||||
if (snd_pcm_recover(alsa->pcm, rc, 1) < 0)
|
||||
return -1;
|
||||
@@ -139,48 +140,51 @@ static ssize_t __alsa_write(void* data, const void* buf, size_t size)
|
||||
}
|
||||
}
|
||||
|
||||
frames = snd_pcm_writei(alsa->pcm, (const char*)buf + written * 2 * (alsa->has_float ? sizeof(float) : sizeof(int16_t)), size - written);
|
||||
snd_pcm_sframes_t frames = snd_pcm_writei(alsa->pcm, buf, size);
|
||||
|
||||
if ( frames == -EPIPE || frames == -EINTR || frames == -ESTRPIPE )
|
||||
if (frames == -EPIPE || frames == -EINTR || frames == -ESTRPIPE)
|
||||
{
|
||||
if ( snd_pcm_recover(alsa->pcm, frames, 1) < 0 )
|
||||
if (snd_pcm_recover(alsa->pcm, frames, 1) < 0)
|
||||
return -1;
|
||||
|
||||
return 0;
|
||||
break;
|
||||
}
|
||||
else if ( frames == -EAGAIN && alsa->nonblock )
|
||||
return 0;
|
||||
else if ( frames < 0 )
|
||||
else if (frames == -EAGAIN && alsa->nonblock)
|
||||
break;
|
||||
else if (frames < 0)
|
||||
return -1;
|
||||
|
||||
written += frames;
|
||||
buf += (frames << 1) * (alsa->has_float ? sizeof(float) : sizeof(int16_t));
|
||||
size -= frames;
|
||||
}
|
||||
|
||||
return snd_pcm_frames_to_bytes(alsa->pcm, size);
|
||||
return written;
|
||||
}
|
||||
|
||||
static bool __alsa_stop(void *data)
|
||||
static bool alsa_stop(void *data)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
static void __alsa_set_nonblock_state(void *data, bool state)
|
||||
static void alsa_set_nonblock_state(void *data, bool state)
|
||||
{
|
||||
alsa_t *alsa = data;
|
||||
alsa_t *alsa = (alsa_t*)data;
|
||||
alsa->nonblock = state;
|
||||
}
|
||||
|
||||
static bool __alsa_start(void *data)
|
||||
static bool alsa_start(void *data)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
static void __alsa_free(void *data)
|
||||
static void alsa_free(void *data)
|
||||
{
|
||||
alsa_t *alsa = data;
|
||||
if ( alsa )
|
||||
alsa_t *alsa = (alsa_t*)data;
|
||||
|
||||
if (alsa)
|
||||
{
|
||||
if ( alsa->pcm )
|
||||
if (alsa->pcm)
|
||||
{
|
||||
snd_pcm_drop(alsa->pcm);
|
||||
snd_pcm_close(alsa->pcm);
|
||||
@@ -189,19 +193,28 @@ static void __alsa_free(void *data)
|
||||
}
|
||||
}
|
||||
|
||||
static size_t alsa_write_avail(void *data)
|
||||
{
|
||||
alsa_t *alsa = (alsa_t*)data;
|
||||
return snd_pcm_frames_to_bytes(alsa->pcm, snd_pcm_avail_update(alsa->pcm));
|
||||
}
|
||||
|
||||
static size_t alsa_buffer_size(void *data)
|
||||
{
|
||||
alsa_t *alsa = (alsa_t*)data;
|
||||
return alsa->buffer_size;
|
||||
}
|
||||
|
||||
const audio_driver_t audio_alsa = {
|
||||
.init = __alsa_init,
|
||||
.write = __alsa_write,
|
||||
.stop = __alsa_stop,
|
||||
.start = __alsa_start,
|
||||
.use_float = __alsa_use_float,
|
||||
.set_nonblock_state = __alsa_set_nonblock_state,
|
||||
.free = __alsa_free,
|
||||
.ident = "alsa"
|
||||
alsa_init,
|
||||
alsa_write,
|
||||
alsa_stop,
|
||||
alsa_start,
|
||||
alsa_set_nonblock_state,
|
||||
alsa_free,
|
||||
alsa_use_float,
|
||||
"alsa",
|
||||
alsa_write_avail,
|
||||
alsa_buffer_size,
|
||||
};
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -0,0 +1,300 @@
|
||||
/* RetroArch - A frontend for libretro.
|
||||
* Copyright (C) 2010-2012 - Hans-Kristian Arntzen
|
||||
* Copyright (C) 2011-2012 - Chris Moeller
|
||||
*
|
||||
* RetroArch is free software: you can redistribute it and/or modify it under the terms
|
||||
* of the GNU General Public License as published by the Free Software Found-
|
||||
* ation, either version 3 of the License, or (at your option) any later version.
|
||||
*
|
||||
* RetroArch is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
|
||||
* without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
|
||||
* PURPOSE. See the GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along with RetroArch.
|
||||
* If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
|
||||
#include "driver.h"
|
||||
#include "general.h"
|
||||
#include "fifo_buffer.h"
|
||||
#include <stdlib.h>
|
||||
#include "../boolean.h"
|
||||
#include <pthread.h>
|
||||
|
||||
#include <CoreAudio/CoreAudio.h>
|
||||
#include <CoreServices/CoreServices.h>
|
||||
#include <AudioUnit/AudioUnit.h>
|
||||
#include <AudioUnit/AUComponent.h>
|
||||
|
||||
typedef struct coreaudio
|
||||
{
|
||||
pthread_mutex_t lock;
|
||||
pthread_cond_t cond;
|
||||
|
||||
ComponentInstance dev;
|
||||
bool dev_alive;
|
||||
|
||||
fifo_buffer_t *buffer;
|
||||
bool nonblock;
|
||||
size_t buffer_size;
|
||||
} coreaudio_t;
|
||||
|
||||
static void coreaudio_free(void *data)
|
||||
{
|
||||
coreaudio_t *dev = (coreaudio_t*)data;
|
||||
if (!dev)
|
||||
return;
|
||||
|
||||
if (dev->dev_alive)
|
||||
{
|
||||
AudioOutputUnitStop(dev->dev);
|
||||
CloseComponent(dev->dev);
|
||||
}
|
||||
|
||||
if (dev->buffer)
|
||||
fifo_free(dev->buffer);
|
||||
|
||||
pthread_mutex_destroy(&dev->lock);
|
||||
pthread_cond_destroy(&dev->cond);
|
||||
|
||||
free(dev);
|
||||
}
|
||||
|
||||
static OSStatus audio_cb(void *userdata, AudioUnitRenderActionFlags *action_flags,
|
||||
const AudioTimeStamp *time_stamp, UInt32 bus_number,
|
||||
UInt32 number_frames, AudioBufferList *io_data)
|
||||
{
|
||||
coreaudio_t *dev = (coreaudio_t*)userdata;
|
||||
(void)time_stamp;
|
||||
(void)bus_number;
|
||||
(void)number_frames;
|
||||
|
||||
if (!io_data)
|
||||
return noErr;
|
||||
if (io_data->mNumberBuffers != 1)
|
||||
return noErr;
|
||||
|
||||
unsigned write_avail = io_data->mBuffers[0].mDataByteSize;
|
||||
void *outbuf = io_data->mBuffers[0].mData;
|
||||
|
||||
pthread_mutex_lock(&dev->lock);
|
||||
if (fifo_read_avail(dev->buffer) < write_avail)
|
||||
{
|
||||
*action_flags = kAudioUnitRenderAction_OutputIsSilence;
|
||||
memset(outbuf, 0, write_avail); // Seems to be needed.
|
||||
pthread_mutex_unlock(&dev->lock);
|
||||
pthread_cond_signal(&dev->cond); // Technically possible to deadlock without.
|
||||
return noErr;
|
||||
}
|
||||
|
||||
fifo_read(dev->buffer, outbuf, write_avail);
|
||||
pthread_mutex_unlock(&dev->lock);
|
||||
pthread_cond_signal(&dev->cond);
|
||||
return noErr;
|
||||
}
|
||||
|
||||
static void *coreaudio_init(const char *device, unsigned rate, unsigned latency)
|
||||
{
|
||||
(void)device;
|
||||
|
||||
coreaudio_t *dev = (coreaudio_t*)calloc(1, sizeof(*dev));
|
||||
if (!dev)
|
||||
return NULL;
|
||||
|
||||
CFRunLoopRef run_loop = NULL;
|
||||
AudioObjectPropertyAddress addr = {
|
||||
kAudioHardwarePropertyRunLoop,
|
||||
kAudioObjectPropertyScopeGlobal,
|
||||
kAudioObjectPropertyElementMaster
|
||||
};
|
||||
|
||||
pthread_mutex_init(&dev->lock, NULL);
|
||||
pthread_cond_init(&dev->cond, NULL);
|
||||
AudioObjectSetPropertyData(kAudioObjectSystemObject, &addr, 0, NULL,
|
||||
sizeof(CFRunLoopRef), &run_loop);
|
||||
|
||||
ComponentDescription desc = {0};
|
||||
desc.componentType = kAudioUnitType_Output;
|
||||
desc.componentSubType = kAudioUnitSubType_HALOutput;
|
||||
desc.componentManufacturer = kAudioUnitManufacturer_Apple;
|
||||
|
||||
AudioStreamBasicDescription stream_desc = {0};
|
||||
AudioStreamBasicDescription real_desc;
|
||||
AudioChannelLayout layout = {0};
|
||||
AURenderCallbackStruct cb = {0};
|
||||
|
||||
Component comp = NULL;
|
||||
OSStatus res = noErr;
|
||||
UInt32 i_size = 0;
|
||||
size_t fifo_size;
|
||||
|
||||
comp = FindNextComponent(NULL, &desc);
|
||||
if (comp == NULL)
|
||||
goto error;
|
||||
|
||||
res = OpenAComponent(comp, &dev->dev);
|
||||
if (res != noErr)
|
||||
goto error;
|
||||
|
||||
dev->dev_alive = true;
|
||||
|
||||
stream_desc.mSampleRate = rate;
|
||||
stream_desc.mBitsPerChannel = sizeof(float) * CHAR_BIT;
|
||||
stream_desc.mChannelsPerFrame = 2;
|
||||
stream_desc.mBytesPerPacket = 2 * sizeof(float);
|
||||
stream_desc.mBytesPerFrame = 2 * sizeof(float);
|
||||
stream_desc.mFramesPerPacket = 1;
|
||||
stream_desc.mFormatID = kAudioFormatLinearPCM;
|
||||
stream_desc.mFormatFlags = kAudioFormatFlagIsFloat | kAudioFormatFlagIsPacked | (is_little_endian() ? 0 : kAudioFormatFlagIsBigEndian);
|
||||
|
||||
res = AudioUnitSetProperty(dev->dev, kAudioUnitProperty_StreamFormat,
|
||||
kAudioUnitScope_Input, 0, &stream_desc, sizeof(stream_desc));
|
||||
if (res != noErr)
|
||||
goto error;
|
||||
|
||||
i_size = sizeof(real_desc);
|
||||
res = AudioUnitGetProperty(dev->dev, kAudioUnitProperty_StreamFormat, kAudioUnitScope_Input, 0, &real_desc, &i_size);
|
||||
if (res != noErr)
|
||||
goto error;
|
||||
|
||||
RARCH_LOG("[CoreAudio]: Using output sample rate of %.1f Hz\n", (float)real_desc.mSampleRate);
|
||||
g_settings.audio.out_rate = real_desc.mSampleRate;
|
||||
|
||||
if (real_desc.mChannelsPerFrame != stream_desc.mChannelsPerFrame)
|
||||
goto error;
|
||||
if (real_desc.mBitsPerChannel != stream_desc.mBitsPerChannel)
|
||||
goto error;
|
||||
if (real_desc.mFormatFlags != stream_desc.mFormatFlags)
|
||||
goto error;
|
||||
if (real_desc.mFormatID != stream_desc.mFormatID)
|
||||
goto error;
|
||||
|
||||
layout.mChannelLayoutTag = kAudioChannelLayoutTag_UseChannelBitmap;
|
||||
layout.mChannelBitmap = 0x03;
|
||||
|
||||
res = AudioUnitSetProperty(dev->dev, kAudioUnitProperty_AudioChannelLayout,
|
||||
kAudioUnitScope_Input, 0, &layout, sizeof(layout));
|
||||
if (res != noErr)
|
||||
goto error;
|
||||
|
||||
cb.inputProc = audio_cb;
|
||||
cb.inputProcRefCon = dev;
|
||||
|
||||
res = AudioUnitSetProperty(dev->dev, kAudioUnitProperty_SetRenderCallback,
|
||||
kAudioUnitScope_Input, 0, &cb, sizeof(cb));
|
||||
if (res != noErr)
|
||||
goto error;
|
||||
|
||||
res = AudioUnitInitialize(dev->dev);
|
||||
if (res != noErr)
|
||||
goto error;
|
||||
|
||||
fifo_size = (latency * g_settings.audio.out_rate) / 1000;
|
||||
fifo_size *= 2 * sizeof(float);
|
||||
dev->buffer_size = fifo_size;
|
||||
|
||||
dev->buffer = fifo_new(fifo_size);
|
||||
if (!dev->buffer)
|
||||
goto error;
|
||||
|
||||
RARCH_LOG("[CoreAudio]: Using buffer size of %u bytes: (latency = %u ms)\n", (unsigned)fifo_size, latency);
|
||||
|
||||
res = AudioOutputUnitStart(dev->dev);
|
||||
if (res != noErr)
|
||||
goto error;
|
||||
|
||||
return dev;
|
||||
|
||||
error:
|
||||
RARCH_ERR("[CoreAudio]: Failed to initialize driver ...\n");
|
||||
coreaudio_free(dev);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static ssize_t coreaudio_write(void *data, const void *buf_, size_t size)
|
||||
{
|
||||
coreaudio_t *dev = (coreaudio_t*)data;
|
||||
|
||||
const uint8_t *buf = (const uint8_t*)buf_;
|
||||
size_t written = 0;
|
||||
|
||||
while (size > 0)
|
||||
{
|
||||
pthread_mutex_lock(&dev->lock);
|
||||
|
||||
size_t write_avail = fifo_write_avail(dev->buffer);
|
||||
if (write_avail > size)
|
||||
write_avail = size;
|
||||
|
||||
fifo_write(dev->buffer, buf, write_avail);
|
||||
buf += write_avail;
|
||||
written += write_avail;
|
||||
size -= write_avail;
|
||||
|
||||
if (dev->nonblock)
|
||||
{
|
||||
pthread_mutex_unlock(&dev->lock);
|
||||
break;
|
||||
}
|
||||
|
||||
if (write_avail == 0)
|
||||
pthread_cond_wait(&dev->cond, &dev->lock);
|
||||
pthread_mutex_unlock(&dev->lock);
|
||||
}
|
||||
|
||||
return written;
|
||||
}
|
||||
|
||||
static bool coreaudio_stop(void *data)
|
||||
{
|
||||
coreaudio_t *dev = (coreaudio_t*)data;
|
||||
return AudioOutputUnitStop(dev->dev) == noErr;
|
||||
}
|
||||
|
||||
static void coreaudio_set_nonblock_state(void *data, bool state)
|
||||
{
|
||||
coreaudio_t *dev = (coreaudio_t*)data;
|
||||
dev->nonblock = state;
|
||||
}
|
||||
|
||||
static bool coreaudio_start(void *data)
|
||||
{
|
||||
coreaudio_t *dev = (coreaudio_t*)data;
|
||||
return AudioOutputUnitStart(dev->dev) == noErr;
|
||||
}
|
||||
|
||||
static bool coreaudio_use_float(void *data)
|
||||
{
|
||||
(void)data;
|
||||
return true;
|
||||
}
|
||||
|
||||
static size_t coreaudio_write_avail(void *data)
|
||||
{
|
||||
coreaudio_t *dev = (coreaudio_t*)data;
|
||||
pthread_mutex_lock(&dev->lock);
|
||||
size_t avail = fifo_write_avail(dev->buffer);
|
||||
pthread_mutex_unlock(&dev->lock);
|
||||
return avail;
|
||||
}
|
||||
|
||||
static size_t coreaudio_buffer_size(void *data)
|
||||
{
|
||||
coreaudio_t *dev = (coreaudio_t*)data;
|
||||
return dev->buffer_size;
|
||||
}
|
||||
|
||||
const audio_driver_t audio_coreaudio = {
|
||||
coreaudio_init,
|
||||
coreaudio_write,
|
||||
coreaudio_stop,
|
||||
coreaudio_start,
|
||||
coreaudio_set_nonblock_state,
|
||||
coreaudio_free,
|
||||
coreaudio_use_float,
|
||||
"coreaudio",
|
||||
coreaudio_write_avail,
|
||||
coreaudio_buffer_size,
|
||||
};
|
||||
|
||||
+424
@@ -0,0 +1,424 @@
|
||||
/* RetroArch - A frontend for libretro.
|
||||
* Copyright (C) 2010-2012 - Hans-Kristian Arntzen
|
||||
*
|
||||
* RetroArch is free software: you can redistribute it and/or modify it under the terms
|
||||
* of the GNU General Public License as published by the Free Software Found-
|
||||
* ation, either version 3 of the License, or (at your option) any later version.
|
||||
*
|
||||
* RetroArch is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
|
||||
* without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
|
||||
* PURPOSE. See the GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along with RetroArch.
|
||||
* If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include "../driver.h"
|
||||
#include <stdlib.h>
|
||||
#include "../boolean.h"
|
||||
#include <stddef.h>
|
||||
#include <stdint.h>
|
||||
#include <string.h>
|
||||
|
||||
#include <dsound.h>
|
||||
#include "../fifo_buffer.h"
|
||||
#include "../general.h"
|
||||
|
||||
typedef struct dsound
|
||||
{
|
||||
LPDIRECTSOUND ds;
|
||||
LPDIRECTSOUNDBUFFER dsb;
|
||||
HANDLE event;
|
||||
bool nonblock;
|
||||
|
||||
fifo_buffer_t *buffer;
|
||||
CRITICAL_SECTION crit;
|
||||
|
||||
volatile bool thread_alive;
|
||||
HANDLE thread;
|
||||
unsigned buffer_size;
|
||||
} dsound_t;
|
||||
|
||||
static inline unsigned write_avail(unsigned read_ptr, unsigned write_ptr, unsigned buffer_size)
|
||||
{
|
||||
return (read_ptr + buffer_size - write_ptr) % buffer_size;
|
||||
}
|
||||
|
||||
static inline void get_positions(dsound_t *ds, DWORD *read_ptr, DWORD *write_ptr)
|
||||
{
|
||||
IDirectSoundBuffer_GetCurrentPosition(ds->dsb, read_ptr, write_ptr);
|
||||
}
|
||||
|
||||
#define CHUNK_SIZE 256
|
||||
|
||||
struct audio_lock
|
||||
{
|
||||
void *chunk1;
|
||||
DWORD size1;
|
||||
void *chunk2;
|
||||
DWORD size2;
|
||||
};
|
||||
|
||||
static inline bool grab_region(dsound_t *ds, DWORD write_ptr, struct audio_lock *region)
|
||||
{
|
||||
HRESULT res = IDirectSoundBuffer_Lock(ds->dsb, write_ptr, CHUNK_SIZE, ®ion->chunk1, ®ion->size1, ®ion->chunk2, ®ion->size2, 0);
|
||||
if (res == DSERR_BUFFERLOST)
|
||||
{
|
||||
res = IDirectSoundBuffer_Restore(ds->dsb);
|
||||
if (res != DS_OK)
|
||||
return false;
|
||||
|
||||
res = IDirectSoundBuffer_Lock(ds->dsb, write_ptr, CHUNK_SIZE, ®ion->chunk1, ®ion->size1, ®ion->chunk2, ®ion->size2, 0);
|
||||
if (res != DS_OK)
|
||||
return false;
|
||||
}
|
||||
|
||||
const char *err;
|
||||
switch (res)
|
||||
{
|
||||
case DSERR_BUFFERLOST:
|
||||
err = "DSERR_BUFFERLOST";
|
||||
break;
|
||||
case DSERR_INVALIDCALL:
|
||||
err = "DSERR_INVALIDCALL";
|
||||
break;
|
||||
case DSERR_INVALIDPARAM:
|
||||
err = "DSERR_INVALIDPARAM";
|
||||
break;
|
||||
case DSERR_PRIOLEVELNEEDED:
|
||||
err = "DSERR_PRIOLEVELNEEDED";
|
||||
break;
|
||||
|
||||
default:
|
||||
err = NULL;
|
||||
}
|
||||
|
||||
if (err)
|
||||
{
|
||||
RARCH_WARN("[DirectSound error]: %s\n", err);
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
static inline void release_region(dsound_t *ds, const struct audio_lock *region)
|
||||
{
|
||||
IDirectSoundBuffer_Unlock(ds->dsb, region->chunk1, region->size1, region->chunk2, region->size2);
|
||||
}
|
||||
|
||||
static DWORD CALLBACK dsound_thread(PVOID data)
|
||||
{
|
||||
dsound_t *ds = (dsound_t*)data;
|
||||
SetThreadPriority(GetCurrentThread(), THREAD_PRIORITY_TIME_CRITICAL);
|
||||
|
||||
DWORD write_ptr;
|
||||
get_positions(ds, NULL, &write_ptr);
|
||||
write_ptr = (write_ptr + ds->buffer_size / 2) % ds->buffer_size;
|
||||
|
||||
while (ds->thread_alive)
|
||||
{
|
||||
DWORD read_ptr;
|
||||
get_positions(ds, &read_ptr, NULL);
|
||||
|
||||
DWORD avail = write_avail(read_ptr, write_ptr, ds->buffer_size);
|
||||
|
||||
EnterCriticalSection(&ds->crit);
|
||||
DWORD fifo_avail = fifo_read_avail(ds->buffer);
|
||||
LeaveCriticalSection(&ds->crit);
|
||||
|
||||
// No space to write, or we don't have data in our fifo, but we can wait some time before it underruns ...
|
||||
if (avail < CHUNK_SIZE || ((fifo_avail < CHUNK_SIZE) && (avail < ds->buffer_size / 2)))
|
||||
{
|
||||
Sleep(1);
|
||||
// We could opt for using the notification interface,
|
||||
// but it is not guaranteed to work, so use high priority sleeping patterns. :(
|
||||
}
|
||||
else if (fifo_avail < CHUNK_SIZE) // Got space to write, but nothing in FIFO (underrun), fill block with silence.
|
||||
{
|
||||
struct audio_lock region;
|
||||
if (!grab_region(ds, write_ptr, ®ion))
|
||||
{
|
||||
ds->thread_alive = false;
|
||||
SetEvent(ds->event);
|
||||
break;
|
||||
}
|
||||
|
||||
memset(region.chunk1, 0, region.size1);
|
||||
memset(region.chunk2, 0, region.size2);
|
||||
|
||||
release_region(ds, ®ion);
|
||||
write_ptr = (write_ptr + region.size1 + region.size2) % ds->buffer_size;
|
||||
}
|
||||
else // All is good. Pull from it and notify FIFO :D
|
||||
{
|
||||
struct audio_lock region;
|
||||
if (!grab_region(ds, write_ptr, ®ion))
|
||||
{
|
||||
ds->thread_alive = false;
|
||||
SetEvent(ds->event);
|
||||
break;
|
||||
}
|
||||
|
||||
EnterCriticalSection(&ds->crit);
|
||||
if (region.chunk1)
|
||||
fifo_read(ds->buffer, region.chunk1, region.size1);
|
||||
if (region.chunk2)
|
||||
fifo_read(ds->buffer, region.chunk2, region.size2);
|
||||
LeaveCriticalSection(&ds->crit);
|
||||
|
||||
release_region(ds, ®ion);
|
||||
write_ptr = (write_ptr + region.size1 + region.size2) % ds->buffer_size;
|
||||
|
||||
SetEvent(ds->event);
|
||||
}
|
||||
}
|
||||
|
||||
ExitThread(0);
|
||||
}
|
||||
|
||||
static void dsound_stop_thread(dsound_t *ds)
|
||||
{
|
||||
if (ds->thread)
|
||||
{
|
||||
ds->thread_alive = false;
|
||||
WaitForSingleObject(ds->thread, INFINITE);
|
||||
CloseHandle(ds->thread);
|
||||
ds->thread = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
static bool dsound_start_thread(dsound_t *ds)
|
||||
{
|
||||
if (!ds->thread)
|
||||
{
|
||||
ds->thread_alive = true;
|
||||
ds->thread = CreateThread(NULL, 0, dsound_thread, ds, 0, NULL);
|
||||
if (ds->thread == NULL)
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
static void dsound_clear_buffer(dsound_t *ds)
|
||||
{
|
||||
IDirectSoundBuffer_SetCurrentPosition(ds->dsb, 0);
|
||||
void *ptr;
|
||||
DWORD size;
|
||||
|
||||
if (IDirectSoundBuffer_Lock(ds->dsb, 0, 0, &ptr, &size, NULL, NULL, DSBLOCK_ENTIREBUFFER) == DS_OK)
|
||||
{
|
||||
memset(ptr, 0, size);
|
||||
IDirectSoundBuffer_Unlock(ds->dsb, ptr, size, NULL, 0);
|
||||
}
|
||||
}
|
||||
|
||||
static void dsound_free(void *data)
|
||||
{
|
||||
dsound_t *ds = (dsound_t*)data;
|
||||
if (ds)
|
||||
{
|
||||
if (ds->thread)
|
||||
{
|
||||
ds->thread_alive = false;
|
||||
WaitForSingleObject(ds->thread, INFINITE);
|
||||
CloseHandle(ds->thread);
|
||||
}
|
||||
|
||||
DeleteCriticalSection(&ds->crit);
|
||||
|
||||
if (ds->dsb)
|
||||
{
|
||||
IDirectSoundBuffer_Stop(ds->dsb);
|
||||
IDirectSoundBuffer_Release(ds->dsb);
|
||||
}
|
||||
|
||||
if (ds)
|
||||
IDirectSound_Release(ds->ds);
|
||||
|
||||
if (ds->event)
|
||||
CloseHandle(ds->event);
|
||||
|
||||
if (ds->buffer)
|
||||
fifo_free(ds->buffer);
|
||||
|
||||
free(ds);
|
||||
}
|
||||
}
|
||||
|
||||
struct dsound_dev
|
||||
{
|
||||
unsigned device;
|
||||
unsigned total_count;
|
||||
LPGUID guid;
|
||||
};
|
||||
|
||||
static BOOL CALLBACK enumerate_cb(LPGUID guid, LPCSTR desc, LPCSTR module, LPVOID context)
|
||||
{
|
||||
struct dsound_dev *dev = (struct dsound_dev*)context;
|
||||
RARCH_LOG("\t%u: %s\n", dev->total_count, desc);
|
||||
if (dev->device == dev->total_count)
|
||||
dev->guid = guid;
|
||||
dev->total_count++;
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static void *dsound_init(const char *device, unsigned rate, unsigned latency)
|
||||
{
|
||||
WAVEFORMATEX wfx = {0};
|
||||
DSBUFFERDESC bufdesc = {0};
|
||||
struct dsound_dev dev = {0};
|
||||
|
||||
dsound_t *ds = (dsound_t*)calloc(1, sizeof(*ds));
|
||||
if (!ds)
|
||||
goto error;
|
||||
|
||||
InitializeCriticalSection(&ds->crit);
|
||||
|
||||
if (device)
|
||||
dev.device = strtoul(device, NULL, 0);
|
||||
|
||||
RARCH_LOG("DirectSound devices:\n");
|
||||
DirectSoundEnumerate(enumerate_cb, &dev);
|
||||
|
||||
if (DirectSoundCreate(dev.guid, &ds->ds, NULL) != DS_OK)
|
||||
goto error;
|
||||
|
||||
if (IDirectSound_SetCooperativeLevel(ds->ds, GetDesktopWindow(), DSSCL_PRIORITY) != DS_OK)
|
||||
goto error;
|
||||
|
||||
wfx.wFormatTag = WAVE_FORMAT_PCM;
|
||||
wfx.nChannels = 2;
|
||||
wfx.nSamplesPerSec = rate;
|
||||
wfx.wBitsPerSample = 16;
|
||||
wfx.nBlockAlign = 2 * sizeof(int16_t);
|
||||
wfx.nAvgBytesPerSec = rate * 2 * sizeof(int16_t);
|
||||
|
||||
ds->buffer_size = (latency * wfx.nAvgBytesPerSec) / 1000;
|
||||
ds->buffer_size /= CHUNK_SIZE;
|
||||
ds->buffer_size *= CHUNK_SIZE;
|
||||
if (ds->buffer_size < 4 * CHUNK_SIZE)
|
||||
ds->buffer_size = 4 * CHUNK_SIZE;
|
||||
|
||||
RARCH_LOG("[DirectSound]: Setting buffer size of %u bytes\n", ds->buffer_size);
|
||||
RARCH_LOG("[DirectSound]: Latency = %u ms\n", (unsigned)((1000 * ds->buffer_size) / wfx.nAvgBytesPerSec));
|
||||
|
||||
bufdesc.dwSize = sizeof(DSBUFFERDESC);
|
||||
bufdesc.dwFlags = DSBCAPS_GETCURRENTPOSITION2 | DSBCAPS_GLOBALFOCUS;
|
||||
bufdesc.dwBufferBytes = ds->buffer_size;
|
||||
bufdesc.lpwfxFormat = &wfx;
|
||||
|
||||
ds->event = CreateEvent(NULL, false, false, NULL);
|
||||
if (!ds->event)
|
||||
goto error;
|
||||
|
||||
ds->buffer = fifo_new(4 * 1024);
|
||||
if (!ds->buffer)
|
||||
goto error;
|
||||
|
||||
if (IDirectSound_CreateSoundBuffer(ds->ds, &bufdesc, &ds->dsb, 0) != DS_OK)
|
||||
goto error;
|
||||
|
||||
IDirectSoundBuffer_SetCurrentPosition(ds->dsb, 0);
|
||||
|
||||
dsound_clear_buffer(ds);
|
||||
|
||||
if (IDirectSoundBuffer_Play(ds->dsb, 0, 0, DSBPLAY_LOOPING) != DS_OK)
|
||||
goto error;
|
||||
|
||||
if (!dsound_start_thread(ds))
|
||||
goto error;
|
||||
|
||||
return ds;
|
||||
|
||||
error:
|
||||
RARCH_ERR("[DirectSound] Error occured in init.\n");
|
||||
dsound_free(ds);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static bool dsound_stop(void *data)
|
||||
{
|
||||
dsound_t *ds = (dsound_t*)data;
|
||||
dsound_stop_thread(ds);
|
||||
return IDirectSoundBuffer_Stop(ds->dsb) == DS_OK;
|
||||
}
|
||||
|
||||
static bool dsound_start(void *data)
|
||||
{
|
||||
dsound_t *ds = (dsound_t*)data;
|
||||
dsound_clear_buffer(ds);
|
||||
|
||||
if (!dsound_start_thread(ds))
|
||||
return false;
|
||||
|
||||
return IDirectSoundBuffer_Play(ds->dsb, 0, 0, DSBPLAY_LOOPING) == DS_OK;
|
||||
}
|
||||
|
||||
static void dsound_set_nonblock_state(void *data, bool state)
|
||||
{
|
||||
dsound_t *ds = (dsound_t*)data;
|
||||
ds->nonblock = state;
|
||||
}
|
||||
|
||||
static ssize_t dsound_write(void *data, const void *buf_, size_t size)
|
||||
{
|
||||
dsound_t *ds = (dsound_t*)data;
|
||||
const uint8_t *buf = (const uint8_t*)buf_;
|
||||
|
||||
if (!ds->thread_alive)
|
||||
return -1;
|
||||
|
||||
size_t written = 0;
|
||||
while (size > 0)
|
||||
{
|
||||
EnterCriticalSection(&ds->crit);
|
||||
size_t avail = fifo_write_avail(ds->buffer);
|
||||
if (avail > size)
|
||||
avail = size;
|
||||
|
||||
fifo_write(ds->buffer, buf, avail);
|
||||
LeaveCriticalSection(&ds->crit);
|
||||
|
||||
buf += avail;
|
||||
size -= avail;
|
||||
written += avail;
|
||||
|
||||
if (ds->nonblock || !ds->thread_alive)
|
||||
break;
|
||||
|
||||
if (avail == 0)
|
||||
WaitForSingleObject(ds->event, INFINITE);
|
||||
}
|
||||
|
||||
return written;
|
||||
}
|
||||
|
||||
static size_t dsound_write_avail(void *data)
|
||||
{
|
||||
dsound_t *ds = (dsound_t*)data;
|
||||
EnterCriticalSection(&ds->crit);
|
||||
size_t avail = fifo_write_avail(ds->buffer);
|
||||
LeaveCriticalSection(&ds->crit);
|
||||
return avail;
|
||||
}
|
||||
|
||||
static size_t dsound_buffer_size(void *data)
|
||||
{
|
||||
return 4 * 1024;
|
||||
}
|
||||
|
||||
const audio_driver_t audio_dsound = {
|
||||
dsound_init,
|
||||
dsound_write,
|
||||
dsound_stop,
|
||||
dsound_start,
|
||||
dsound_set_nonblock_state,
|
||||
dsound_free,
|
||||
NULL,
|
||||
"dsound",
|
||||
dsound_write_avail,
|
||||
dsound_buffer_size,
|
||||
};
|
||||
|
||||
@@ -0,0 +1,128 @@
|
||||
/////
|
||||
// API header for external RetroArch audio driver plugins.
|
||||
//
|
||||
//
|
||||
|
||||
#ifndef __RARCH_AUDIO_DRIVER_PLUGIN_H
|
||||
#define __RARCH_AUDIO_DRIVER_PLUGIN_H
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#ifdef _WIN32
|
||||
#ifdef RARCH_DLL_IMPORT
|
||||
#define RARCH_API_EXPORT __declspec(dllimport)
|
||||
#else
|
||||
#define RARCH_API_EXPORT __declspec(dllexport)
|
||||
#endif
|
||||
#define RARCH_API_CALLTYPE __cdecl
|
||||
#else
|
||||
#define RARCH_API_EXPORT
|
||||
#define RARCH_API_CALLTYPE
|
||||
#endif
|
||||
|
||||
#ifndef RARCH_TRUE
|
||||
#define RARCH_TRUE 1
|
||||
#endif
|
||||
|
||||
#ifndef RARCH_FALSE
|
||||
#define RARCH_FALSE 0
|
||||
#endif
|
||||
|
||||
#ifndef RARCH_OK
|
||||
#define RARCH_OK 1
|
||||
#endif
|
||||
|
||||
#ifndef RARCH_ERROR
|
||||
#define RARCH_ERROR 0
|
||||
#endif
|
||||
|
||||
#define RARCH_AUDIO_API_VERSION 2
|
||||
|
||||
typedef struct rarch_audio_driver_info
|
||||
{
|
||||
// A hint for a subdevice of the audio driver.
|
||||
// This is driver independent, and not relevant for all
|
||||
// audio drivers. I.e. ALSA driver might use "hw:0",
|
||||
// OSS "/dev/audio", etc.
|
||||
const char *device;
|
||||
|
||||
// Audio sample rate.
|
||||
unsigned sample_rate;
|
||||
|
||||
// Maximum audio latency requested for output,
|
||||
// measured in milliseconds.
|
||||
// If driver is not able to provide this latency, it can
|
||||
// be disregarded.
|
||||
unsigned latency;
|
||||
} rarch_audio_driver_info_t;
|
||||
|
||||
typedef struct rarch_audio_driver
|
||||
{
|
||||
// Initializes the device.
|
||||
void *(*init)(const rarch_audio_driver_info_t *info);
|
||||
|
||||
// Write data in buffer to audio driver.
|
||||
// A frame here is defined as one combined sample of left and right
|
||||
// channels. (I.e. 44.1kHz, 16-bit stereo has 88.2k samples/s, and
|
||||
// 44.1k frames/s.)
|
||||
//
|
||||
// Samples are interleaved in format LRLRLRLRLR ...
|
||||
// If the driver returns true in use_float(), a floating point
|
||||
// format will be used, with range [-1.0, 1.0].
|
||||
// If not, signed 16-bit samples in native byte ordering will be used.
|
||||
//
|
||||
// This function returns the number of frames successfully written.
|
||||
// If an error occurs, -1 should be returned.
|
||||
// Note that non-blocking behavior that cannot write at this time
|
||||
// should return 0 as returning -1 will terminate the driver.
|
||||
//
|
||||
// Unless said otherwise with set_nonblock_state(), all writes
|
||||
// are blocking, and it should block till it has written all frames.
|
||||
int (*write)(void *data, const void *buffer, unsigned frames);
|
||||
|
||||
// Temporarily pauses the audio driver.
|
||||
int (*stop)(void *data);
|
||||
|
||||
// Resumes audio driver from the paused state.
|
||||
int (*start)(void *data);
|
||||
|
||||
// If state is true, nonblocking operation is assumed.
|
||||
// This is typically used for fast-forwarding. If driver cannot
|
||||
// implement nonblocking writes, this can be disregarded, but should
|
||||
// log a message to stderr.
|
||||
void (*set_nonblock_state)(void *data, int state);
|
||||
|
||||
// Stops and frees the audio driver.
|
||||
void (*free)(void *data);
|
||||
|
||||
// If true is returned, the audio driver is capable of using
|
||||
// floating point data. This will likely increase performance as the
|
||||
// resampler unit uses floating point. The sample range is
|
||||
// [-1.0, 1.0].
|
||||
int (*use_float)(void *data);
|
||||
|
||||
// The driver might be forced to use a certain output frequency
|
||||
// (i.e. Jack), and thus to avoid double resampling, the driver
|
||||
// can request RetroArch to resample to a different sample rate.
|
||||
// This function can be set to NULL if the driver does not
|
||||
// desire to override the sample rate.
|
||||
unsigned (*sample_rate)(void *data);
|
||||
|
||||
// Human readable identification string for the driver.
|
||||
const char *ident;
|
||||
|
||||
// Must be set to RARCH_AUDIO_API_VERSION.
|
||||
// Used for detecting API mismatch.
|
||||
int api_version;
|
||||
} rarch_audio_driver_t;
|
||||
|
||||
RARCH_API_EXPORT const rarch_audio_driver_t* RARCH_API_CALLTYPE
|
||||
rarch_audio_driver_init(void);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,129 @@
|
||||
/////
|
||||
// API header for external RetroArch DSP plugins.
|
||||
//
|
||||
//
|
||||
|
||||
#ifndef __RARCH_DSP_PLUGIN_H
|
||||
#define __RARCH_DSP_PLUGIN_H
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#ifdef _WIN32
|
||||
#ifdef RARCH_DLL_IMPORT
|
||||
#define RARCH_API_EXPORT __declspec(dllimport)
|
||||
#else
|
||||
#define RARCH_API_EXPORT __declspec(dllexport)
|
||||
#endif
|
||||
#define RARCH_API_CALLTYPE __cdecl
|
||||
#else
|
||||
#define RARCH_API_EXPORT
|
||||
#define RARCH_API_CALLTYPE
|
||||
#endif
|
||||
|
||||
#ifndef RARCH_FALSE
|
||||
#define RARCH_FALSE 0
|
||||
#endif
|
||||
|
||||
#ifndef RARCH_TRUE
|
||||
#define RARCH_TRUE 1
|
||||
#endif
|
||||
|
||||
#define RARCH_DSP_API_VERSION 3
|
||||
|
||||
typedef struct rarch_dsp_info
|
||||
{
|
||||
// Input sample rate that the DSP plugin receives. This is generally ~32kHz.
|
||||
// Some small variance is allowed due to syncing behavior.
|
||||
float input_rate;
|
||||
|
||||
// RetroArch requests that the DSP plugin resamples the
|
||||
// input to a certain frequency.
|
||||
//
|
||||
// However, the plugin might ignore this
|
||||
// using the resample field in rarch_dsp_output_t (see below).
|
||||
float output_rate;
|
||||
} rarch_dsp_info_t;
|
||||
|
||||
typedef struct rarch_dsp_output
|
||||
{
|
||||
// The DSP plugin has to provide the buffering for the output samples.
|
||||
// This is for performance reasons to avoid redundant copying of data.
|
||||
// The samples are laid out in interleaving order: LRLRLRLR
|
||||
// The range of the samples are [-1.0, 1.0].
|
||||
// This range cannot be exceeded without horrible audio glitches.
|
||||
const float *samples;
|
||||
|
||||
// Frames which the DSP plugin outputted for the current process.
|
||||
// One frame is here defined as a combined sample of
|
||||
// left and right channels.
|
||||
// (I.e. 44.1kHz, 16bit stereo will have
|
||||
// 88.2k samples/sec and 44.1k frames/sec.)
|
||||
unsigned frames;
|
||||
|
||||
// If true, the DSP plugin did not resample the input audio,
|
||||
// and requests resampling to the proper frequency to be
|
||||
// performed outside the plugin.
|
||||
// If false,
|
||||
// it is assumed that the output has the same sample rate as given
|
||||
// in output_rate.
|
||||
int should_resample;
|
||||
} rarch_dsp_output_t;
|
||||
|
||||
typedef struct rarch_dsp_input
|
||||
{
|
||||
// Input data for the DSP. The samples are interleaved in order: LRLRLRLR
|
||||
const float *samples;
|
||||
|
||||
// Number of frames for input data.
|
||||
// One frame is here defined as a combined sample of
|
||||
// left and right channels.
|
||||
// (I.e. 44.1kHz, 16bit stereo will have
|
||||
// 88.2k samples/sec and 44.1k frames/sec.)
|
||||
unsigned frames;
|
||||
} rarch_dsp_input_t;
|
||||
|
||||
typedef struct rarch_dsp_plugin
|
||||
{
|
||||
// Creates a handle of the plugin. Returns NULL if failed.
|
||||
void *(*init)(const rarch_dsp_info_t *info);
|
||||
|
||||
// Processes input data.
|
||||
// The plugin is allowed to return variable sizes for output data.
|
||||
void (*process)(void *data, rarch_dsp_output_t *output,
|
||||
const rarch_dsp_input_t *input);
|
||||
|
||||
// Frees the handle.
|
||||
void (*free)(void *data);
|
||||
|
||||
// API version used to compile the plugin.
|
||||
// Used to detect mismatches in API.
|
||||
// Must be set to RARCH_DSP_API_VERSION on compile.
|
||||
int api_version;
|
||||
|
||||
// Signal plugin that it may open a configuring window or
|
||||
// something similiar. The behavior of this function
|
||||
// is thus plugin dependent. Implementing this is optional,
|
||||
// and can be set to NULL.
|
||||
void (*config)(void *data);
|
||||
|
||||
// Human readable identification string.
|
||||
const char *ident;
|
||||
|
||||
// Called every frame, allows creating a GUI main loop in the main thread.
|
||||
// GUI events can be processed here in a non-blocking fashion.
|
||||
// Can be set to NULL to ignore it.
|
||||
void (*events)(void *data);
|
||||
} rarch_dsp_plugin_t;
|
||||
|
||||
// Called by RetroArch at startup to get the callback struct.
|
||||
// This is NOT dynamically allocated!
|
||||
RARCH_API_EXPORT const rarch_dsp_plugin_t* RARCH_API_CALLTYPE
|
||||
rarch_dsp_plugin_init(void);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,164 @@
|
||||
/* RetroArch - A frontend for libretro.
|
||||
* Copyright (C) 2010-2012 - Hans-Kristian Arntzen
|
||||
*
|
||||
* RetroArch is free software: you can redistribute it and/or modify it under the terms
|
||||
* of the GNU General Public License as published by the Free Software Found-
|
||||
* ation, either version 3 of the License, or (at your option) any later version.
|
||||
*
|
||||
* RetroArch is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
|
||||
* without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
|
||||
* PURPOSE. See the GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along with RetroArch.
|
||||
* If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include "ext/rarch_audio.h"
|
||||
#include "../boolean.h"
|
||||
#include <stdlib.h>
|
||||
#include <stdint.h>
|
||||
#include "../driver.h"
|
||||
#include "../dynamic.h"
|
||||
#include "../general.h"
|
||||
#include <sys/types.h>
|
||||
|
||||
typedef struct audio_ext
|
||||
{
|
||||
dylib_t lib;
|
||||
const rarch_audio_driver_t *driver;
|
||||
void *handle;
|
||||
bool is_float;
|
||||
} audio_ext_t;
|
||||
|
||||
static void audio_ext_free(void *data)
|
||||
{
|
||||
audio_ext_t *ext = (audio_ext_t*)data;
|
||||
if (ext)
|
||||
{
|
||||
if (ext->driver && ext->handle)
|
||||
ext->driver->free(ext->handle);
|
||||
if (ext->lib)
|
||||
dylib_close(ext->lib);
|
||||
free(ext);
|
||||
}
|
||||
}
|
||||
|
||||
static void *audio_ext_init(const char *device, unsigned rate, unsigned latency)
|
||||
{
|
||||
if (!(*g_settings.audio.external_driver))
|
||||
{
|
||||
RARCH_ERR("Please define an external audio driver.\n");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
audio_ext_t *ext = (audio_ext_t*)calloc(1, sizeof(*ext));
|
||||
if (!ext)
|
||||
return NULL;
|
||||
|
||||
rarch_audio_driver_info_t info = {0};
|
||||
const rarch_audio_driver_t *(*plugin_load)(void) = NULL;
|
||||
|
||||
ext->lib = dylib_load(g_settings.audio.external_driver);
|
||||
if (!ext->lib)
|
||||
{
|
||||
RARCH_ERR("Failed to load external library \"%s\"\n", g_settings.audio.external_driver);
|
||||
goto error;
|
||||
}
|
||||
|
||||
plugin_load = (const rarch_audio_driver_t *(*)(void))dylib_proc(ext->lib, "rarch_audio_driver_init");
|
||||
if (!plugin_load)
|
||||
plugin_load = (const rarch_audio_driver_t *(*)(void))dylib_proc(ext->lib, "ssnes_audio_driver_init"); // Compat. Will be dropped on ABI break.
|
||||
|
||||
if (!plugin_load)
|
||||
{
|
||||
RARCH_ERR("Failed to find symbol \"rarch_audio_driver_init\" in plugin.\n");
|
||||
goto error;
|
||||
}
|
||||
|
||||
ext->driver = plugin_load();
|
||||
if (!ext->driver)
|
||||
{
|
||||
RARCH_ERR("Received invalid driver from plugin.\n");
|
||||
goto error;
|
||||
}
|
||||
|
||||
RARCH_LOG("Loaded external audio driver: \"%s\"\n", ext->driver->ident ? ext->driver->ident : "Unknown");
|
||||
|
||||
if (ext->driver->api_version != RARCH_AUDIO_API_VERSION)
|
||||
{
|
||||
RARCH_ERR("API mismatch in external audio plugin. SSNES: %d, Plugin: %d ...\n", RARCH_AUDIO_API_VERSION, ext->driver->api_version);
|
||||
goto error;
|
||||
}
|
||||
|
||||
info.device = device;
|
||||
info.sample_rate = rate;
|
||||
info.latency = latency;
|
||||
|
||||
ext->handle = ext->driver->init(&info);
|
||||
if (!ext->handle)
|
||||
{
|
||||
RARCH_ERR("Failed to init audio driver.\n");
|
||||
goto error;
|
||||
}
|
||||
|
||||
if (ext->driver->sample_rate)
|
||||
g_settings.audio.out_rate = ext->driver->sample_rate(ext->handle);
|
||||
|
||||
if (!g_settings.audio.sync)
|
||||
ext->driver->set_nonblock_state(ext->handle, RARCH_TRUE);
|
||||
|
||||
return ext;
|
||||
|
||||
error:
|
||||
audio_ext_free(ext);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static ssize_t audio_ext_write(void *data, const void *buf, size_t size)
|
||||
{
|
||||
audio_ext_t *ext = (audio_ext_t*)data;
|
||||
unsigned frame_size = ext->is_float ? (2 * sizeof(float)) : (2 * sizeof(int16_t));
|
||||
size /= frame_size;
|
||||
|
||||
int ret = ext->driver->write(ext->handle, buf, size);
|
||||
if (ret < 0)
|
||||
return -1;
|
||||
return ret * frame_size;
|
||||
}
|
||||
|
||||
static bool audio_ext_start(void *data)
|
||||
{
|
||||
audio_ext_t *ext = (audio_ext_t*)data;
|
||||
return ext->driver->start(ext->handle);
|
||||
}
|
||||
|
||||
static bool audio_ext_stop(void *data)
|
||||
{
|
||||
audio_ext_t *ext = (audio_ext_t*)data;
|
||||
return ext->driver->stop(ext->handle);
|
||||
}
|
||||
|
||||
static void audio_ext_set_nonblock_state(void *data, bool toggle)
|
||||
{
|
||||
audio_ext_t *ext = (audio_ext_t*)data;
|
||||
ext->driver->set_nonblock_state(ext->handle, toggle);
|
||||
}
|
||||
|
||||
static bool audio_ext_use_float(void *data)
|
||||
{
|
||||
audio_ext_t *ext = (audio_ext_t*)data;
|
||||
ext->is_float = ext->driver->use_float(ext->handle);
|
||||
return ext->is_float;
|
||||
}
|
||||
|
||||
const audio_driver_t audio_ext = {
|
||||
audio_ext_init,
|
||||
audio_ext_write,
|
||||
audio_ext_stop,
|
||||
audio_ext_start,
|
||||
audio_ext_set_nonblock_state,
|
||||
audio_ext_free,
|
||||
audio_ext_use_float,
|
||||
"ext"
|
||||
};
|
||||
|
||||
@@ -0,0 +1,94 @@
|
||||
/* RetroArch - A frontend for libretro.
|
||||
* Copyright (C) 2010-2012 - Hans-Kristian Arntzen
|
||||
*
|
||||
* RetroArch is free software: you can redistribute it and/or modify it under the terms
|
||||
* of the GNU General Public License as published by the Free Software Found-
|
||||
* ation, either version 3 of the License, or (at your option) any later version.
|
||||
*
|
||||
* RetroArch is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
|
||||
* without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
|
||||
* PURPOSE. See the GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along with RetroArch.
|
||||
* If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
// Hermite resampler based on bsnes' audio library.
|
||||
|
||||
#include "resampler.h"
|
||||
#include <stdlib.h>
|
||||
#include <math.h>
|
||||
#include "../boolean.h"
|
||||
|
||||
#define CHANNELS 2
|
||||
|
||||
struct rarch_resampler
|
||||
{
|
||||
float chan_data[CHANNELS][4];
|
||||
double r_frac;
|
||||
};
|
||||
|
||||
static inline float hermite_kernel(float mu1, float a, float b, float c, float d)
|
||||
{
|
||||
float mu2, mu3, m0, m1, a0, a1, a2, a3;
|
||||
|
||||
mu2 = mu1 * mu1;
|
||||
mu3 = mu2 * mu1;
|
||||
|
||||
m0 = (c - a) * 0.5f;
|
||||
m1 = (d - b) * 0.5f;
|
||||
|
||||
a0 = +2 * mu3 - 3 * mu2 + 1;
|
||||
a1 = mu3 - 2 * mu2 + mu1;
|
||||
a2 = mu3 - mu2;
|
||||
a3 = -2 * mu3 + 3 * mu2;
|
||||
|
||||
return (a0 * b) + (a1 * m0) + (a2 * m1) + (a3 * c);
|
||||
}
|
||||
|
||||
rarch_resampler_t *resampler_new(void)
|
||||
{
|
||||
return (rarch_resampler_t*)calloc(1, sizeof(rarch_resampler_t));
|
||||
}
|
||||
|
||||
void resampler_process(rarch_resampler_t *re, struct resampler_data *data)
|
||||
{
|
||||
double r_step = 1.0 / data->ratio;
|
||||
size_t processed_out = 0;
|
||||
|
||||
size_t in_frames = data->input_frames;
|
||||
const float *in_data = data->data_in;
|
||||
float *out_data = data->data_out;
|
||||
|
||||
for (size_t i = 0; i < in_frames; i++)
|
||||
{
|
||||
while (re->r_frac <= 1.0)
|
||||
{
|
||||
re->r_frac += r_step;
|
||||
for (unsigned i = 0; i < CHANNELS; i++)
|
||||
{
|
||||
float res = hermite_kernel((float)re->r_frac,
|
||||
re->chan_data[i][0], re->chan_data[i][1], re->chan_data[i][2], re->chan_data[i][3]);
|
||||
*out_data++ = res;
|
||||
}
|
||||
processed_out++;
|
||||
}
|
||||
|
||||
re->r_frac -= 1.0;
|
||||
for (unsigned i = 0; i < CHANNELS; i++)
|
||||
{
|
||||
re->chan_data[i][0] = re->chan_data[i][1];
|
||||
re->chan_data[i][1] = re->chan_data[i][2];
|
||||
re->chan_data[i][2] = re->chan_data[i][3];
|
||||
re->chan_data[i][3] = *in_data++;
|
||||
}
|
||||
}
|
||||
|
||||
data->output_frames = processed_out;
|
||||
}
|
||||
|
||||
void resampler_free(rarch_resampler_t *re)
|
||||
{
|
||||
free(re);
|
||||
}
|
||||
|
||||
+94
-71
@@ -1,31 +1,29 @@
|
||||
/* SSNES - A Super Nintendo Entertainment System (SNES) Emulator frontend for libsnes.
|
||||
* Copyright (C) 2010-2011 - Hans-Kristian Arntzen
|
||||
*
|
||||
* Some code herein may be based on code found in BSNES.
|
||||
/* RetroArch - A frontend for libretro.
|
||||
* Copyright (C) 2010-2012 - Hans-Kristian Arntzen
|
||||
*
|
||||
* SSNES is free software: you can redistribute it and/or modify it under the terms
|
||||
* RetroArch is free software: you can redistribute it and/or modify it under the terms
|
||||
* of the GNU General Public License as published by the Free Software Found-
|
||||
* ation, either version 3 of the License, or (at your option) any later version.
|
||||
*
|
||||
* SSNES is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
|
||||
* RetroArch is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
|
||||
* without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
|
||||
* PURPOSE. See the GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along with SSNES.
|
||||
* You should have received a copy of the GNU General Public License along with RetroArch.
|
||||
* If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
|
||||
#include "driver.h"
|
||||
#include "../driver.h"
|
||||
#include <stdlib.h>
|
||||
#include "general.h"
|
||||
#include "../general.h"
|
||||
|
||||
#include <jack/jack.h>
|
||||
#include <jack/types.h>
|
||||
#include <jack/ringbuffer.h>
|
||||
#include <pthread.h>
|
||||
#include <stdint.h>
|
||||
#include <stdbool.h>
|
||||
#include "../boolean.h"
|
||||
#include <string.h>
|
||||
#include <assert.h>
|
||||
|
||||
@@ -41,11 +39,12 @@ typedef struct jack
|
||||
|
||||
pthread_cond_t cond;
|
||||
pthread_mutex_t cond_lock;
|
||||
size_t buffer_size;
|
||||
} jack_t;
|
||||
|
||||
static int process_cb(jack_nframes_t nframes, void *data)
|
||||
{
|
||||
jack_t *jd = data;
|
||||
jack_t *jd = (jack_t*)data;
|
||||
if (nframes <= 0)
|
||||
{
|
||||
pthread_cond_signal(&jd->cond);
|
||||
@@ -62,7 +61,7 @@ static int process_cb(jack_nframes_t nframes, void *data)
|
||||
|
||||
for (int i = 0; i < 2; i++)
|
||||
{
|
||||
jack_default_audio_sample_t *out = jack_port_get_buffer(jd->ports[i], nframes);
|
||||
jack_default_audio_sample_t *out = (jack_default_audio_sample_t*)jack_port_get_buffer(jd->ports[i], nframes);
|
||||
assert(out);
|
||||
jack_ringbuffer_read(jd->buffer[i], (char*)out, min_avail * sizeof(jack_default_audio_sample_t));
|
||||
|
||||
@@ -77,7 +76,7 @@ static int process_cb(jack_nframes_t nframes, void *data)
|
||||
|
||||
static void shutdown_cb(void *data)
|
||||
{
|
||||
jack_t *jd = data;
|
||||
jack_t *jd = (jack_t*)data;
|
||||
jd->shutdown = true;
|
||||
pthread_cond_signal(&jd->cond);
|
||||
}
|
||||
@@ -103,12 +102,20 @@ static size_t find_buffersize(jack_t *jd, int latency)
|
||||
{
|
||||
int frames = latency * g_settings.audio.out_rate / 1000;
|
||||
|
||||
int jack_latency = jack_port_get_total_latency(jd->client, jd->ports[0]);
|
||||
SSNES_LOG("JACK: Jack latency is %d frames.\n", jack_latency);
|
||||
jack_latency_range_t range;
|
||||
int jack_latency = 0;
|
||||
for (int i = 0; i < 2; i++)
|
||||
{
|
||||
jack_port_get_latency_range(jd->ports[i], JackPlaybackLatency, &range);
|
||||
if ((int)range.max > jack_latency)
|
||||
jack_latency = range.max;
|
||||
}
|
||||
|
||||
RARCH_LOG("JACK: Jack latency is %d frames.\n", jack_latency);
|
||||
|
||||
int buffer_frames = frames - jack_latency;
|
||||
int min_buffer_frames = jack_get_buffer_size(jd->client) * 2;
|
||||
SSNES_LOG("JACK: Minimum buffer size is %d frames.\n", min_buffer_frames);
|
||||
RARCH_LOG("JACK: Minimum buffer size is %d frames.\n", min_buffer_frames);
|
||||
|
||||
if (buffer_frames < min_buffer_frames)
|
||||
buffer_frames = min_buffer_frames;
|
||||
@@ -116,13 +123,19 @@ static size_t find_buffersize(jack_t *jd, int latency)
|
||||
return buffer_frames * sizeof(jack_default_audio_sample_t);
|
||||
}
|
||||
|
||||
static void* __jack_init(const char* device, int rate, int latency)
|
||||
static void *ja_init(const char *device, unsigned rate, unsigned latency)
|
||||
{
|
||||
jack_t *jd = calloc(1, sizeof(jack_t));
|
||||
if ( jd == NULL )
|
||||
jack_t *jd = (jack_t*)calloc(1, sizeof(jack_t));
|
||||
if (!jd)
|
||||
return NULL;
|
||||
|
||||
pthread_cond_init(&jd->cond, NULL);
|
||||
pthread_mutex_init(&jd->cond_lock, NULL);
|
||||
|
||||
const char **jports = NULL;
|
||||
char *dest_ports[2];
|
||||
size_t bufsize = 0;
|
||||
int parsed = 0;
|
||||
|
||||
jd->client = jack_client_open("SSNES", JackNullOption, NULL);
|
||||
if (jd->client == NULL)
|
||||
@@ -137,24 +150,36 @@ static void* __jack_init(const char* device, int rate, int latency)
|
||||
jd->ports[1] = jack_port_register(jd->client, "right", JACK_DEFAULT_AUDIO_TYPE, JackPortIsOutput, 0);
|
||||
if (jd->ports[0] == NULL || jd->ports[1] == NULL)
|
||||
{
|
||||
SSNES_ERR("Failed to register ports.\n");
|
||||
RARCH_ERR("Failed to register ports.\n");
|
||||
goto error;
|
||||
}
|
||||
|
||||
|
||||
char *dest_ports[2];
|
||||
jports = jack_get_ports(jd->client, NULL, NULL, JackPortIsPhysical | JackPortIsInput);
|
||||
if (jports == NULL)
|
||||
{
|
||||
SSNES_ERR("Failed to get ports.\n");
|
||||
RARCH_ERR("Failed to get ports.\n");
|
||||
goto error;
|
||||
}
|
||||
|
||||
int parsed = parse_ports(dest_ports, jports);
|
||||
bufsize = find_buffersize(jd, latency);
|
||||
jd->buffer_size = bufsize;
|
||||
|
||||
RARCH_LOG("JACK: Internal buffer size: %d frames.\n", (int)(bufsize / sizeof(jack_default_audio_sample_t)));
|
||||
for (int i = 0; i < 2; i++)
|
||||
{
|
||||
jd->buffer[i] = jack_ringbuffer_create(bufsize);
|
||||
if (jd->buffer[i] == NULL)
|
||||
{
|
||||
RARCH_ERR("Failed to create buffers.\n");
|
||||
goto error;
|
||||
}
|
||||
}
|
||||
|
||||
parsed = parse_ports(dest_ports, jports);
|
||||
|
||||
if (jack_activate(jd->client) < 0)
|
||||
{
|
||||
SSNES_ERR("Failed to activate Jack...\n");
|
||||
RARCH_ERR("Failed to activate Jack...\n");
|
||||
goto error;
|
||||
}
|
||||
|
||||
@@ -162,30 +187,14 @@ static void* __jack_init(const char* device, int rate, int latency)
|
||||
{
|
||||
if (jack_connect(jd->client, jack_port_name(jd->ports[i]), dest_ports[i]))
|
||||
{
|
||||
SSNES_ERR("Failed to connect to Jack port.\n");
|
||||
RARCH_ERR("Failed to connect to Jack port.\n");
|
||||
goto error;
|
||||
}
|
||||
}
|
||||
|
||||
for (int i = 0; i < parsed; i++)
|
||||
free(dest_ports[i]);
|
||||
|
||||
size_t bufsize = find_buffersize(jd, latency);
|
||||
|
||||
SSNES_LOG("JACK: Internal buffer size: %d frames.\n", (int)(bufsize / sizeof(jack_default_audio_sample_t)));
|
||||
for (int i = 0; i < 2; i++)
|
||||
{
|
||||
jd->buffer[i] = jack_ringbuffer_create(bufsize);
|
||||
if (jd->buffer[i] == NULL)
|
||||
{
|
||||
SSNES_ERR("Failed to create buffers.\n");
|
||||
goto error;
|
||||
}
|
||||
}
|
||||
|
||||
pthread_cond_init(&jd->cond, NULL);
|
||||
pthread_mutex_init(&jd->cond_lock, NULL);
|
||||
|
||||
|
||||
jack_free(jports);
|
||||
return jd;
|
||||
|
||||
@@ -197,7 +206,7 @@ error:
|
||||
|
||||
static size_t write_buffer(jack_t *jd, const float *buf, size_t size)
|
||||
{
|
||||
jack_default_audio_sample_t out_deinterleaved_buffer[2][FRAMES(size)];
|
||||
jack_default_audio_sample_t out_deinterleaved_buffer[2][AUDIO_CHUNK_SIZE_NONBLOCKING];
|
||||
|
||||
for (int i = 0; i < 2; i++)
|
||||
for (size_t j = 0; j < FRAMES(size); j++)
|
||||
@@ -211,9 +220,11 @@ static size_t write_buffer(jack_t *jd, const float *buf, size_t size)
|
||||
if (jd->shutdown)
|
||||
return 0;
|
||||
|
||||
size_t avail[2];
|
||||
avail[0] = jack_ringbuffer_write_space(jd->buffer[0]);
|
||||
avail[1] = jack_ringbuffer_write_space(jd->buffer[1]);
|
||||
size_t avail[2] = {
|
||||
jack_ringbuffer_write_space(jd->buffer[0]),
|
||||
jack_ringbuffer_write_space(jd->buffer[1]),
|
||||
};
|
||||
|
||||
size_t min_avail = avail[0] < avail[1] ? avail[0] : avail[1];
|
||||
min_avail /= sizeof(float);
|
||||
|
||||
@@ -222,7 +233,10 @@ static size_t write_buffer(jack_t *jd, const float *buf, size_t size)
|
||||
if (write_frames > 0)
|
||||
{
|
||||
for (int i = 0; i < 2; i++)
|
||||
jack_ringbuffer_write(jd->buffer[i], (const char*)&out_deinterleaved_buffer[i][written], write_frames * sizeof(jack_default_audio_sample_t));
|
||||
{
|
||||
jack_ringbuffer_write(jd->buffer[i], (const char*)&out_deinterleaved_buffer[i][written],
|
||||
write_frames * sizeof(jack_default_audio_sample_t));
|
||||
}
|
||||
written += write_frames;
|
||||
}
|
||||
else
|
||||
@@ -239,34 +253,34 @@ static size_t write_buffer(jack_t *jd, const float *buf, size_t size)
|
||||
return written * sizeof(float) * 2;
|
||||
}
|
||||
|
||||
static ssize_t __jack_write(void* data, const void* buf, size_t size)
|
||||
static ssize_t ja_write(void *data, const void *buf, size_t size)
|
||||
{
|
||||
jack_t *jd = data;
|
||||
jack_t *jd = (jack_t*)data;
|
||||
|
||||
return write_buffer(jd, buf, size);
|
||||
return write_buffer(jd, (const float*)buf, size);
|
||||
}
|
||||
|
||||
static bool __jack_stop(void *data)
|
||||
static bool ja_stop(void *data)
|
||||
{
|
||||
(void)data;
|
||||
return true;
|
||||
}
|
||||
|
||||
static void __jack_set_nonblock_state(void *data, bool state)
|
||||
static void ja_set_nonblock_state(void *data, bool state)
|
||||
{
|
||||
jack_t *jd = data;
|
||||
jack_t *jd = (jack_t*)data;
|
||||
jd->nonblock = state;
|
||||
}
|
||||
|
||||
static bool __jack_start(void *data)
|
||||
static bool ja_start(void *data)
|
||||
{
|
||||
(void)data;
|
||||
return true;
|
||||
}
|
||||
|
||||
static void __jack_free(void *data)
|
||||
static void ja_free(void *data)
|
||||
{
|
||||
jack_t *jd = data;
|
||||
jack_t *jd = (jack_t*)data;
|
||||
|
||||
jd->shutdown = true;
|
||||
|
||||
@@ -285,25 +299,34 @@ static void __jack_free(void *data)
|
||||
free(jd);
|
||||
}
|
||||
|
||||
static bool __jack_use_float(void *data)
|
||||
static bool ja_use_float(void *data)
|
||||
{
|
||||
(void)data;
|
||||
return true;
|
||||
}
|
||||
|
||||
static size_t ja_write_avail(void *data)
|
||||
{
|
||||
jack_t *jd = (jack_t*)data;
|
||||
return jack_ringbuffer_write_space(jd->buffer[0]);
|
||||
}
|
||||
|
||||
static size_t ja_buffer_size(void *data)
|
||||
{
|
||||
jack_t *jd = (jack_t*)data;
|
||||
return jd->buffer_size;
|
||||
}
|
||||
|
||||
const audio_driver_t audio_jack = {
|
||||
.init = __jack_init,
|
||||
.write = __jack_write,
|
||||
.stop = __jack_stop,
|
||||
.start = __jack_start,
|
||||
.set_nonblock_state = __jack_set_nonblock_state,
|
||||
.free = __jack_free,
|
||||
.use_float = __jack_use_float,
|
||||
.ident = "jack"
|
||||
ja_init,
|
||||
ja_write,
|
||||
ja_stop,
|
||||
ja_start,
|
||||
ja_set_nonblock_state,
|
||||
ja_free,
|
||||
ja_use_float,
|
||||
"jack",
|
||||
ja_write_avail,
|
||||
ja_buffer_size,
|
||||
};
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
+40
-37
@@ -1,24 +1,28 @@
|
||||
/* SSNES - A Super Nintendo Entertainment System (SNES) Emulator frontend for libsnes.
|
||||
* Copyright (C) 2010-2011 - Hans-Kristian Arntzen
|
||||
*
|
||||
* Some code herein may be based on code found in BSNES.
|
||||
/* RetroArch - A frontend for libretro.
|
||||
* Copyright (C) 2010-2012 - Hans-Kristian Arntzen
|
||||
*
|
||||
* SSNES is free software: you can redistribute it and/or modify it under the terms
|
||||
* RetroArch is free software: you can redistribute it and/or modify it under the terms
|
||||
* of the GNU General Public License as published by the Free Software Found-
|
||||
* ation, either version 3 of the License, or (at your option) any later version.
|
||||
*
|
||||
* SSNES is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
|
||||
* RetroArch is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
|
||||
* without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
|
||||
* PURPOSE. See the GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along with SSNES.
|
||||
* You should have received a copy of the GNU General Public License along with RetroArch.
|
||||
* If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include "../driver.h"
|
||||
|
||||
#include "driver.h"
|
||||
#ifdef __APPLE__
|
||||
#include <OpenAL/al.h>
|
||||
#include <OpenAL/alc.h>
|
||||
#else
|
||||
#include <AL/al.h>
|
||||
#include <AL/alc.h>
|
||||
#endif
|
||||
|
||||
#include <time.h>
|
||||
#include <string.h>
|
||||
|
||||
@@ -49,11 +53,11 @@ typedef struct al
|
||||
|
||||
} al_t;
|
||||
|
||||
static void* __al_init(const char* device, int rate, int latency)
|
||||
static void *al_init(const char *device, unsigned rate, unsigned latency)
|
||||
{
|
||||
(void)device;
|
||||
al_t *al = calloc(1, sizeof(al_t));
|
||||
if ( al == NULL )
|
||||
al_t *al = (al_t*)calloc(1, sizeof(al_t));
|
||||
if (!al)
|
||||
return NULL;
|
||||
|
||||
al->handle = alcOpenDevice(NULL);
|
||||
@@ -69,8 +73,8 @@ static void* __al_init(const char* device, int rate, int latency)
|
||||
al->rate = rate;
|
||||
|
||||
al->num_buffers = (latency * rate * 2 * 2) / (1000 * BUFSIZE);
|
||||
al->buffers = calloc(al->num_buffers, sizeof(ALuint));
|
||||
al->res_buf = calloc(al->num_buffers, sizeof(ALuint));
|
||||
al->buffers = (ALuint*)calloc(al->num_buffers, sizeof(ALuint));
|
||||
al->res_buf = (ALuint*)calloc(al->num_buffers, sizeof(ALuint));
|
||||
if (al->buffers == NULL || al->res_buf == NULL)
|
||||
goto error;
|
||||
|
||||
@@ -120,13 +124,12 @@ static bool al_get_buffer(al_t *al, ALuint *buffer)
|
||||
if (al->res_ptr == 0)
|
||||
{
|
||||
#ifndef _WIN32
|
||||
struct timespec tv = {
|
||||
.tv_sec = 0,
|
||||
.tv_nsec = 1000000
|
||||
};
|
||||
struct timespec tv = {0};
|
||||
tv.tv_sec = 0;
|
||||
tv.tv_nsec = 1000000;
|
||||
#endif
|
||||
|
||||
for(;;)
|
||||
for (;;)
|
||||
{
|
||||
if (al_unqueue_buffers(al))
|
||||
break;
|
||||
@@ -146,17 +149,17 @@ static bool al_get_buffer(al_t *al, ALuint *buffer)
|
||||
return true;
|
||||
}
|
||||
|
||||
static size_t al_fill_internal_buf(al_t *al, const void* buf, size_t size)
|
||||
static size_t al_fill_internal_buf(al_t *al, const void *buf, size_t size)
|
||||
{
|
||||
size_t read_size = (BUFSIZE - al->tmpbuf_ptr > size) ? size : (BUFSIZE - al->tmpbuf_ptr);
|
||||
size_t read_size = (BUFSIZE - al->tmpbuf_ptr > (ssize_t)size) ? size : (BUFSIZE - al->tmpbuf_ptr);
|
||||
memcpy(al->tmpbuf + al->tmpbuf_ptr, buf, read_size);
|
||||
al->tmpbuf_ptr += read_size;
|
||||
return read_size;
|
||||
}
|
||||
|
||||
static ssize_t __al_write(void* data, const void* buf, size_t size)
|
||||
static ssize_t al_write(void *data, const void *buf, size_t size)
|
||||
{
|
||||
al_t *al = data;
|
||||
al_t *al = (al_t*)data;
|
||||
|
||||
size_t written = 0;
|
||||
while (written < size)
|
||||
@@ -189,32 +192,32 @@ static ssize_t __al_write(void* data, const void* buf, size_t size)
|
||||
return size;
|
||||
}
|
||||
|
||||
static bool __al_stop(void *data)
|
||||
static bool al_stop(void *data)
|
||||
{
|
||||
(void)data;
|
||||
return true;
|
||||
}
|
||||
|
||||
static void __al_set_nonblock_state(void *data, bool state)
|
||||
static void al_set_nonblock_state(void *data, bool state)
|
||||
{
|
||||
al_t *al = data;
|
||||
al_t *al = (al_t*)data;
|
||||
al->nonblock = state;
|
||||
}
|
||||
|
||||
static bool __al_start(void *data)
|
||||
static bool al_start(void *data)
|
||||
{
|
||||
(void)data;
|
||||
return true;
|
||||
}
|
||||
|
||||
static void __al_free(void *data)
|
||||
static void al_free(void *data)
|
||||
{
|
||||
al_t *al= data;
|
||||
al_t *al = (al_t*)data;
|
||||
if (al)
|
||||
{
|
||||
alSourceStop(al->source);
|
||||
alDeleteSources(1, &al->source);
|
||||
if ( al->buffers )
|
||||
if (al->buffers)
|
||||
{
|
||||
alDeleteBuffers(al->num_buffers, al->buffers);
|
||||
free(al->buffers);
|
||||
@@ -228,13 +231,13 @@ static void __al_free(void *data)
|
||||
}
|
||||
|
||||
const audio_driver_t audio_openal = {
|
||||
.init = __al_init,
|
||||
.write = __al_write,
|
||||
.stop = __al_stop,
|
||||
.start = __al_start,
|
||||
.set_nonblock_state = __al_set_nonblock_state,
|
||||
.free = __al_free,
|
||||
.ident = "openal"
|
||||
al_init,
|
||||
al_write,
|
||||
al_stop,
|
||||
al_start,
|
||||
al_set_nonblock_state,
|
||||
al_free,
|
||||
NULL,
|
||||
"openal"
|
||||
};
|
||||
|
||||
|
||||
+99
-50
@@ -1,147 +1,196 @@
|
||||
/* SSNES - A Super Nintendo Entertainment System (SNES) Emulator frontend for libsnes.
|
||||
* Copyright (C) 2010-2011 - Hans-Kristian Arntzen
|
||||
*
|
||||
* Some code herein may be based on code found in BSNES.
|
||||
/* RetroArch - A frontend for libretro.
|
||||
* Copyright (C) 2010-2012 - Hans-Kristian Arntzen
|
||||
*
|
||||
* SSNES is free software: you can redistribute it and/or modify it under the terms
|
||||
* RetroArch is free software: you can redistribute it and/or modify it under the terms
|
||||
* of the GNU General Public License as published by the Free Software Found-
|
||||
* ation, either version 3 of the License, or (at your option) any later version.
|
||||
*
|
||||
* SSNES is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
|
||||
* RetroArch is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
|
||||
* without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
|
||||
* PURPOSE. See the GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along with SSNES.
|
||||
* You should have received a copy of the GNU General Public License along with RetroArch.
|
||||
* If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
#include "config.h"
|
||||
#endif
|
||||
|
||||
#include "driver.h"
|
||||
#include "general.h"
|
||||
#include <stdlib.h>
|
||||
|
||||
#ifdef HAVE_OSS_BSD
|
||||
#include <soundcard.h>
|
||||
#else
|
||||
#include <sys/soundcard.h>
|
||||
#endif
|
||||
|
||||
#include <fcntl.h>
|
||||
#include <sys/ioctl.h>
|
||||
#include <unistd.h>
|
||||
#include <errno.h>
|
||||
#include <stdio.h>
|
||||
|
||||
static void* __oss_init(const char* device, int rate, int latency)
|
||||
#ifdef HAVE_OSS_BSD
|
||||
#define DEFAULT_OSS_DEV "/dev/audio"
|
||||
#else
|
||||
#define DEFAULT_OSS_DEV "/dev/dsp"
|
||||
#endif
|
||||
|
||||
static void *oss_init(const char *device, unsigned rate, unsigned latency)
|
||||
{
|
||||
int *fd = calloc(1, sizeof(int));
|
||||
if ( fd == NULL )
|
||||
int *fd = (int*)calloc(1, sizeof(int));
|
||||
if (fd == NULL)
|
||||
return NULL;
|
||||
|
||||
const char *oss_device = "/dev/dsp";
|
||||
const char *oss_device = DEFAULT_OSS_DEV;
|
||||
|
||||
if ( device != NULL )
|
||||
if (device != NULL)
|
||||
oss_device = device;
|
||||
|
||||
if ( (*fd = open(oss_device, O_WRONLY)) < 0 )
|
||||
if ((*fd = open(oss_device, O_WRONLY)) < 0)
|
||||
{
|
||||
free(fd);
|
||||
perror("open");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
int frags = (latency * rate * 4)/(1000 * (1 << 9));
|
||||
int frag = (frags << 16) | 9;
|
||||
int frags = (latency * rate * 4) / (1000 * (1 << 10));
|
||||
int frag = (frags << 16) | 10;
|
||||
|
||||
if ( ioctl(*fd, SNDCTL_DSP_SETFRAGMENT, &frag) < 0 )
|
||||
{
|
||||
close(*fd);
|
||||
free(fd);
|
||||
return NULL;
|
||||
}
|
||||
if (ioctl(*fd, SNDCTL_DSP_SETFRAGMENT, &frag) < 0)
|
||||
RARCH_WARN("Cannot set fragment sizes. Latency might not be as expected ...\n");
|
||||
|
||||
int channels = 2;
|
||||
int format = AFMT_S16_LE;
|
||||
int format = is_little_endian() ?
|
||||
AFMT_S16_LE : AFMT_S16_BE;
|
||||
|
||||
if ( ioctl(*fd, SNDCTL_DSP_CHANNELS, &channels) < 0 )
|
||||
if (ioctl(*fd, SNDCTL_DSP_CHANNELS, &channels) < 0)
|
||||
{
|
||||
close(*fd);
|
||||
free(fd);
|
||||
perror("ioctl");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if ( ioctl(*fd, SNDCTL_DSP_SETFMT, &format) < 0 )
|
||||
if (ioctl(*fd, SNDCTL_DSP_SETFMT, &format) < 0)
|
||||
{
|
||||
close(*fd);
|
||||
free(fd);
|
||||
perror("ioctl");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if ( ioctl(*fd, SNDCTL_DSP_SPEED, &rate) < 0 )
|
||||
int new_rate = rate;
|
||||
if (ioctl(*fd, SNDCTL_DSP_SPEED, &new_rate) < 0)
|
||||
{
|
||||
close(*fd);
|
||||
free(fd);
|
||||
perror("ioctl");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (new_rate != (int)rate)
|
||||
{
|
||||
RARCH_WARN("Requested sample rate not supported. Adjusting output rate to %d Hz.\n", new_rate);
|
||||
g_settings.audio.out_rate = new_rate;
|
||||
}
|
||||
|
||||
return fd;
|
||||
}
|
||||
|
||||
static ssize_t __oss_write(void* data, const void* buf, size_t size)
|
||||
static ssize_t oss_write(void *data, const void *buf, size_t size)
|
||||
{
|
||||
int *fd = data;
|
||||
int *fd = (int*)data;
|
||||
|
||||
if ( size == 0 )
|
||||
if (size == 0)
|
||||
return 0;
|
||||
|
||||
ssize_t ret;
|
||||
if ( (ret = write(*fd, buf, size)) <= 0 )
|
||||
if ((ret = write(*fd, buf, size)) <= 0)
|
||||
{
|
||||
if ( (fcntl(*fd, F_GETFL) & O_NONBLOCK) && errno == EAGAIN )
|
||||
if ((fcntl(*fd, F_GETFL) & O_NONBLOCK) && errno == EAGAIN)
|
||||
return 0;
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static bool __oss_stop(void *data)
|
||||
static bool oss_stop(void *data)
|
||||
{
|
||||
int *fd = data;
|
||||
int *fd = (int*)data;
|
||||
ioctl(*fd, SNDCTL_DSP_RESET, 0);
|
||||
return true;
|
||||
}
|
||||
|
||||
static bool __oss_start(void *data)
|
||||
static bool oss_start(void *data)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
static void __oss_set_nonblock_state(void *data, bool state)
|
||||
static void oss_set_nonblock_state(void *data, bool state)
|
||||
{
|
||||
int *fd = data;
|
||||
int *fd = (int*)data;
|
||||
int rc;
|
||||
if (state)
|
||||
rc = fcntl(*fd, F_SETFL, fcntl(*fd, F_GETFL) | O_NONBLOCK);
|
||||
else
|
||||
rc = fcntl(*fd, F_SETFL, fcntl(*fd, F_GETFL) & (~O_NONBLOCK));
|
||||
if (rc != 0)
|
||||
fprintf(stderr, "SSNES [ERROR]: Could not set nonblocking on OSS file descriptor. Will not be able to fast-forward.\n");
|
||||
RARCH_WARN("Could not set nonblocking on OSS file descriptor. Will not be able to fast-forward.\n");
|
||||
}
|
||||
|
||||
static void __oss_free(void *data)
|
||||
static void oss_free(void *data)
|
||||
{
|
||||
int *fd = data;
|
||||
int *fd = (int*)data;
|
||||
|
||||
ioctl(*fd, SNDCTL_DSP_RESET, 0);
|
||||
close(*fd);
|
||||
free(fd);
|
||||
}
|
||||
|
||||
static size_t oss_write_avail(void *data)
|
||||
{
|
||||
int *fd = (int*)data;
|
||||
|
||||
audio_buf_info info;
|
||||
if (ioctl(*fd, SNDCTL_DSP_GETOSPACE, &info) < 0)
|
||||
{
|
||||
RARCH_ERR("SNDCTL_DSP_GETOSPACE failed ...\n");
|
||||
return 0;
|
||||
}
|
||||
|
||||
return info.bytes;
|
||||
}
|
||||
|
||||
static size_t oss_buffer_size(void *data)
|
||||
{
|
||||
int *fd = (int*)data;
|
||||
|
||||
audio_buf_info info;
|
||||
if (ioctl(*fd, SNDCTL_DSP_GETOSPACE, &info) < 0)
|
||||
{
|
||||
RARCH_ERR("SNDCTL_DSP_GETOSPACE failed ...\n");
|
||||
return 1; // Return something non-zero to avoid SIGFPE.
|
||||
}
|
||||
|
||||
return info.fragsize * info.fragstotal;
|
||||
}
|
||||
|
||||
const audio_driver_t audio_oss = {
|
||||
.init = __oss_init,
|
||||
.write = __oss_write,
|
||||
.stop = __oss_stop,
|
||||
.start = __oss_start,
|
||||
.set_nonblock_state = __oss_set_nonblock_state,
|
||||
.free = __oss_free,
|
||||
.ident = "oss"
|
||||
oss_init,
|
||||
oss_write,
|
||||
oss_stop,
|
||||
oss_start,
|
||||
oss_set_nonblock_state,
|
||||
oss_free,
|
||||
NULL,
|
||||
"oss",
|
||||
oss_write_avail,
|
||||
oss_buffer_size,
|
||||
};
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
+252
@@ -0,0 +1,252 @@
|
||||
/* RetroArch - A frontend for libretro.
|
||||
* Copyright (C) 2010-2012 - Hans-Kristian Arntzen
|
||||
*
|
||||
* RetroArch is free software: you can redistribute it and/or modify it under the terms
|
||||
* of the GNU General Public License as published by the Free Software Found-
|
||||
* ation, either version 3 of the License, or (at your option) any later version.
|
||||
*
|
||||
* RetroArch is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
|
||||
* without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
|
||||
* PURPOSE. See the GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along with RetroArch.
|
||||
* If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
|
||||
#include "driver.h"
|
||||
#include "general.h"
|
||||
#include <pulse/pulseaudio.h>
|
||||
#include "../boolean.h"
|
||||
#include <string.h>
|
||||
|
||||
#include <stdio.h>
|
||||
|
||||
typedef struct
|
||||
{
|
||||
pa_threaded_mainloop *mainloop;
|
||||
pa_context *context;
|
||||
pa_stream *stream;
|
||||
bool nonblock;
|
||||
size_t buffer_size;
|
||||
} pa_t;
|
||||
|
||||
static void pulse_free(void *data)
|
||||
{
|
||||
pa_t *pa = (pa_t*)data;
|
||||
if (pa)
|
||||
{
|
||||
if (pa->mainloop)
|
||||
pa_threaded_mainloop_stop(pa->mainloop);
|
||||
|
||||
if (pa->stream)
|
||||
{
|
||||
pa_stream_disconnect(pa->stream);
|
||||
pa_stream_unref(pa->stream);
|
||||
}
|
||||
|
||||
if (pa->context)
|
||||
{
|
||||
pa_context_disconnect(pa->context);
|
||||
pa_context_unref(pa->context);
|
||||
}
|
||||
|
||||
if (pa->mainloop)
|
||||
pa_threaded_mainloop_free(pa->mainloop);
|
||||
|
||||
free(pa);
|
||||
}
|
||||
}
|
||||
|
||||
static void context_state_cb(pa_context *c, void *data)
|
||||
{
|
||||
pa_t *pa = (pa_t*)data;
|
||||
switch (pa_context_get_state(c))
|
||||
{
|
||||
case PA_CONTEXT_READY:
|
||||
case PA_CONTEXT_TERMINATED:
|
||||
case PA_CONTEXT_FAILED:
|
||||
pa_threaded_mainloop_signal(pa->mainloop, 0);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
static void stream_state_cb(pa_stream *s, void *data)
|
||||
{
|
||||
pa_t *pa = (pa_t*)data;
|
||||
switch (pa_stream_get_state(s))
|
||||
{
|
||||
case PA_STREAM_READY:
|
||||
case PA_STREAM_FAILED:
|
||||
case PA_STREAM_TERMINATED:
|
||||
pa_threaded_mainloop_signal(pa->mainloop, 0);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
static void stream_request_cb(pa_stream *s, size_t length, void *data)
|
||||
{
|
||||
(void)length;
|
||||
(void)s;
|
||||
pa_t *pa = (pa_t*)data;
|
||||
pa_threaded_mainloop_signal(pa->mainloop, 0);
|
||||
}
|
||||
|
||||
static void stream_latency_update_cb(pa_stream *s, void *data)
|
||||
{
|
||||
(void)s;
|
||||
pa_t *pa = (pa_t*)data;
|
||||
pa_threaded_mainloop_signal(pa->mainloop, 0);
|
||||
}
|
||||
|
||||
static void *pulse_init(const char *device, unsigned rate, unsigned latency)
|
||||
{
|
||||
pa_sample_spec spec;
|
||||
memset(&spec, 0, sizeof(spec));
|
||||
pa_buffer_attr buffer_attr = {0};
|
||||
|
||||
pa_t *pa = (pa_t*)calloc(1, sizeof(*pa));
|
||||
if (!pa)
|
||||
goto error;
|
||||
|
||||
pa->mainloop = pa_threaded_mainloop_new();
|
||||
if (!pa->mainloop)
|
||||
goto error;
|
||||
|
||||
pa->context = pa_context_new(pa_threaded_mainloop_get_api(pa->mainloop), "SSNES");
|
||||
if (!pa->context)
|
||||
goto error;
|
||||
|
||||
pa_context_set_state_callback(pa->context, context_state_cb, pa);
|
||||
|
||||
if (pa_context_connect(pa->context, device, PA_CONTEXT_NOFLAGS, NULL) < 0)
|
||||
goto error;
|
||||
|
||||
pa_threaded_mainloop_lock(pa->mainloop);
|
||||
if (pa_threaded_mainloop_start(pa->mainloop) < 0)
|
||||
goto error;
|
||||
|
||||
pa_threaded_mainloop_wait(pa->mainloop);
|
||||
|
||||
if (pa_context_get_state(pa->context) != PA_CONTEXT_READY)
|
||||
goto unlock_error;
|
||||
|
||||
spec.format = is_little_endian() ? PA_SAMPLE_FLOAT32LE : PA_SAMPLE_FLOAT32BE;
|
||||
spec.channels = 2;
|
||||
spec.rate = rate;
|
||||
|
||||
pa->stream = pa_stream_new(pa->context, "audio", &spec, NULL);
|
||||
if (!pa->stream)
|
||||
goto unlock_error;
|
||||
|
||||
pa_stream_set_state_callback(pa->stream, stream_state_cb, pa);
|
||||
pa_stream_set_write_callback(pa->stream, stream_request_cb, pa);
|
||||
pa_stream_set_latency_update_callback(pa->stream, stream_latency_update_cb, pa);
|
||||
|
||||
buffer_attr.maxlength = -1;
|
||||
buffer_attr.tlength = pa_usec_to_bytes(latency * PA_USEC_PER_MSEC, &spec);
|
||||
buffer_attr.prebuf = -1;
|
||||
buffer_attr.minreq = -1;
|
||||
buffer_attr.fragsize = -1;
|
||||
|
||||
pa->buffer_size = buffer_attr.tlength;
|
||||
|
||||
if (pa_stream_connect_playback(pa->stream, NULL, &buffer_attr, PA_STREAM_ADJUST_LATENCY, NULL, NULL) < 0)
|
||||
goto error;
|
||||
|
||||
pa_threaded_mainloop_wait(pa->mainloop);
|
||||
|
||||
if (pa_stream_get_state(pa->stream) != PA_STREAM_READY)
|
||||
goto unlock_error;
|
||||
|
||||
pa_threaded_mainloop_unlock(pa->mainloop);
|
||||
|
||||
return pa;
|
||||
|
||||
unlock_error:
|
||||
pa_threaded_mainloop_unlock(pa->mainloop);
|
||||
error:
|
||||
pulse_free(pa);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static ssize_t pulse_write(void *data, const void *buf, size_t size)
|
||||
{
|
||||
pa_t *pa = (pa_t*)data;
|
||||
|
||||
pa_threaded_mainloop_lock(pa->mainloop);
|
||||
size_t length = pa_stream_writable_size(pa->stream);
|
||||
pa_threaded_mainloop_unlock(pa->mainloop);
|
||||
|
||||
while (length < size && !pa->nonblock)
|
||||
{
|
||||
pa_threaded_mainloop_lock(pa->mainloop);
|
||||
pa_threaded_mainloop_wait(pa->mainloop);
|
||||
length = pa_stream_writable_size(pa->stream);
|
||||
pa_threaded_mainloop_unlock(pa->mainloop);
|
||||
}
|
||||
|
||||
size_t write_size = min(length, size);
|
||||
|
||||
pa_threaded_mainloop_lock(pa->mainloop);
|
||||
pa_stream_write(pa->stream, buf, write_size, NULL, 0LL, PA_SEEK_RELATIVE);
|
||||
pa_threaded_mainloop_unlock(pa->mainloop);
|
||||
return write_size;
|
||||
}
|
||||
|
||||
static bool pulse_stop(void *data)
|
||||
{
|
||||
(void)data;
|
||||
return true;
|
||||
}
|
||||
|
||||
static bool pulse_start(void *data)
|
||||
{
|
||||
(void)data;
|
||||
return true;
|
||||
}
|
||||
|
||||
static void pulse_set_nonblock_state(void *data, bool state)
|
||||
{
|
||||
pa_t *pa = (pa_t*)data;
|
||||
pa->nonblock = state;
|
||||
}
|
||||
|
||||
static bool pulse_use_float(void *data)
|
||||
{
|
||||
(void)data;
|
||||
return true;
|
||||
}
|
||||
|
||||
static size_t pulse_write_avail(void *data)
|
||||
{
|
||||
pa_t *pa = (pa_t*)data;
|
||||
pa_threaded_mainloop_lock(pa->mainloop);
|
||||
size_t length = pa_stream_writable_size(pa->stream);
|
||||
pa_threaded_mainloop_unlock(pa->mainloop);
|
||||
return length;
|
||||
}
|
||||
|
||||
static size_t pulse_buffer_size(void *data)
|
||||
{
|
||||
pa_t *pa = (pa_t*)data;
|
||||
return pa->buffer_size;
|
||||
}
|
||||
|
||||
const audio_driver_t audio_pulse = {
|
||||
pulse_init,
|
||||
pulse_write,
|
||||
pulse_stop,
|
||||
pulse_start,
|
||||
pulse_set_nonblock_state,
|
||||
pulse_free,
|
||||
pulse_use_float,
|
||||
"pulse",
|
||||
pulse_write_avail,
|
||||
pulse_buffer_size,
|
||||
};
|
||||
|
||||
@@ -0,0 +1,46 @@
|
||||
/* RetroArch - A frontend for libretro.
|
||||
* Copyright (C) 2010-2012 - Hans-Kristian Arntzen
|
||||
*
|
||||
* RetroArch is free software: you can redistribute it and/or modify it under the terms
|
||||
* of the GNU General Public License as published by the Free Software Found-
|
||||
* ation, either version 3 of the License, or (at your option) any later version.
|
||||
*
|
||||
* RetroArch is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
|
||||
* without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
|
||||
* PURPOSE. See the GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along with RetroArch.
|
||||
* If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
|
||||
#ifndef __RARCH_RESAMPLER_H
|
||||
#define __RARCH_RESAMPLER_H
|
||||
|
||||
#include <stddef.h>
|
||||
#include <math.h>
|
||||
|
||||
// M_PI is left out of ISO C99 :(
|
||||
#ifndef M_PI
|
||||
#define M_PI 3.14159265358979323846264338327
|
||||
#endif
|
||||
|
||||
typedef struct rarch_resampler rarch_resampler_t;
|
||||
|
||||
struct resampler_data
|
||||
{
|
||||
const float *data_in;
|
||||
float *data_out;
|
||||
|
||||
size_t input_frames;
|
||||
size_t output_frames;
|
||||
|
||||
double ratio;
|
||||
};
|
||||
|
||||
rarch_resampler_t *resampler_new(void);
|
||||
void resampler_process(rarch_resampler_t *re, struct resampler_data *data);
|
||||
void resampler_free(rarch_resampler_t *re);
|
||||
|
||||
#endif
|
||||
|
||||
+36
-38
@@ -1,17 +1,15 @@
|
||||
/* SSNES - A Super Nintendo Entertainment System (SNES) Emulator frontend for libsnes.
|
||||
* Copyright (C) 2010-2011 - Hans-Kristian Arntzen
|
||||
*
|
||||
* Some code herein may be based on code found in BSNES.
|
||||
/* RetroArch - A frontend for libretro.
|
||||
* Copyright (C) 2010-2012 - Hans-Kristian Arntzen
|
||||
*
|
||||
* SSNES is free software: you can redistribute it and/or modify it under the terms
|
||||
* RetroArch is free software: you can redistribute it and/or modify it under the terms
|
||||
* of the GNU General Public License as published by the Free Software Found-
|
||||
* ation, either version 3 of the License, or (at your option) any later version.
|
||||
*
|
||||
* SSNES is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
|
||||
* RetroArch is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
|
||||
* without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
|
||||
* PURPOSE. See the GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along with SSNES.
|
||||
* You should have received a copy of the GNU General Public License along with RetroArch.
|
||||
* If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
@@ -21,7 +19,8 @@
|
||||
#include <roaraudio.h>
|
||||
#include <errno.h>
|
||||
#include <stdio.h>
|
||||
#include <stdbool.h>
|
||||
#include "../boolean.h"
|
||||
#include "general.h"
|
||||
|
||||
typedef struct
|
||||
{
|
||||
@@ -29,44 +28,47 @@ typedef struct
|
||||
bool nonblocking;
|
||||
} roar_t;
|
||||
|
||||
static void* __roar_init(const char* device, int rate, int latency)
|
||||
static void *ra_init(const char *device, unsigned rate, unsigned latency)
|
||||
{
|
||||
(void)latency;
|
||||
int err;
|
||||
roar_t *roar = calloc(1, sizeof(roar_t));
|
||||
roar_t *roar = (roar_t*)calloc(1, sizeof(roar_t));
|
||||
if (roar == NULL)
|
||||
return NULL;
|
||||
|
||||
roar_vs_t *vss;
|
||||
if ( (vss = roar_vs_new_simple(NULL, NULL, rate, 2, ROAR_CODEC_PCM_S_LE, 16, ROAR_DIR_PLAY, &err)) == NULL )
|
||||
if ((vss = roar_vs_new_simple(device, "SSNES", rate, 2, ROAR_CODEC_PCM_S, 16, ROAR_DIR_PLAY, &err)) == NULL)
|
||||
{
|
||||
fprintf(stderr, "roar_vs: \"%s\"\n", roar_vs_strerr(err));
|
||||
RARCH_ERR("RoarAudio: \"%s\"\n", roar_vs_strerr(err));
|
||||
free(roar);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
roar_vs_role(vss, ROAR_ROLE_GAME, NULL);
|
||||
roar->vss = vss;
|
||||
|
||||
return roar;
|
||||
}
|
||||
|
||||
static ssize_t __roar_write(void* data, const void* buf, size_t size)
|
||||
static ssize_t ra_write(void *data, const void *buf, size_t size)
|
||||
{
|
||||
roar_t *roar = data;
|
||||
roar_t *roar = (roar_t*)data;
|
||||
ssize_t rc;
|
||||
|
||||
if ( size == 0 )
|
||||
if (size == 0)
|
||||
return 0;
|
||||
|
||||
int err;
|
||||
size_t written = 0;
|
||||
while (written < size)
|
||||
{
|
||||
if ((rc = roar_vs_write(roar->vss, (const char*)buf + written, size - written, &err)) < size)
|
||||
size_t write_amt = size - written;
|
||||
if ((rc = roar_vs_write(roar->vss, (const char*)buf + written, write_amt, &err)) < (ssize_t)write_amt)
|
||||
{
|
||||
if (rc < 0)
|
||||
if (roar->nonblocking)
|
||||
return rc;
|
||||
else if (rc < 0)
|
||||
return -1;
|
||||
else if (roar->nonblocking)
|
||||
return 0;
|
||||
}
|
||||
written += rc;
|
||||
}
|
||||
@@ -74,45 +76,41 @@ static ssize_t __roar_write(void* data, const void* buf, size_t size)
|
||||
return size;
|
||||
}
|
||||
|
||||
static bool __roar_stop(void *data)
|
||||
static bool ra_stop(void *data)
|
||||
{
|
||||
(void)data;
|
||||
return true;
|
||||
}
|
||||
|
||||
static void __roar_set_nonblock_state(void *data, bool state)
|
||||
static void ra_set_nonblock_state(void *data, bool state)
|
||||
{
|
||||
roar_t *roar = data;
|
||||
roar_t *roar = (roar_t*)data;
|
||||
if (roar_vs_blocking(roar->vss, (state) ? ROAR_VS_FALSE : ROAR_VS_TRUE, NULL) < 0)
|
||||
fprintf(stderr, "SSNES [ERROR]: Can't set nonblocking. Will not be able to fast-forward.\n");
|
||||
fprintf(stderr, "RetroArch [ERROR]: Can't set nonblocking. Will not be able to fast-forward.\n");
|
||||
roar->nonblocking = state;
|
||||
}
|
||||
|
||||
static bool __roar_start(void *data)
|
||||
static bool ra_start(void *data)
|
||||
{
|
||||
(void)data;
|
||||
return true;
|
||||
}
|
||||
|
||||
static void __roar_free(void *data)
|
||||
static void ra_free(void *data)
|
||||
{
|
||||
roar_t *roar = data;
|
||||
roar_t *roar = (roar_t*)data;
|
||||
roar_vs_close(roar->vss, ROAR_VS_TRUE, NULL);
|
||||
free(data);
|
||||
}
|
||||
|
||||
const audio_driver_t audio_roar = {
|
||||
.init = __roar_init,
|
||||
.write = __roar_write,
|
||||
.stop = __roar_stop,
|
||||
.start = __roar_start,
|
||||
.set_nonblock_state = __roar_set_nonblock_state,
|
||||
.free = __roar_free,
|
||||
.ident = "roar"
|
||||
ra_init,
|
||||
ra_write,
|
||||
ra_stop,
|
||||
ra_start,
|
||||
ra_set_nonblock_state,
|
||||
ra_free,
|
||||
NULL,
|
||||
"roar"
|
||||
};
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
+132
-62
@@ -1,146 +1,216 @@
|
||||
/* SSNES - A Super Nintendo Entertainment System (SNES) Emulator frontend for libsnes.
|
||||
* Copyright (C) 2010-2011 - Hans-Kristian Arntzen
|
||||
*
|
||||
* Some code herein may be based on code found in BSNES.
|
||||
/* RetroArch - A frontend for libretro.
|
||||
* Copyright (C) 2010-2012 - Hans-Kristian Arntzen
|
||||
*
|
||||
* SSNES is free software: you can redistribute it and/or modify it under the terms
|
||||
* RetroArch is free software: you can redistribute it and/or modify it under the terms
|
||||
* of the GNU General Public License as published by the Free Software Found-
|
||||
* ation, either version 3 of the License, or (at your option) any later version.
|
||||
*
|
||||
* SSNES is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
|
||||
* RetroArch is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
|
||||
* without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
|
||||
* PURPOSE. See the GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along with SSNES.
|
||||
* You should have received a copy of the GNU General Public License along with RetroArch.
|
||||
* If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
|
||||
#include "driver.h"
|
||||
#include "../driver.h"
|
||||
#include <stdlib.h>
|
||||
#ifdef RARCH_CONSOLE
|
||||
#include "../console/librsound/rsound.h"
|
||||
#else
|
||||
#include <rsound.h>
|
||||
#endif
|
||||
#include "fifo_buffer.h"
|
||||
#include "../boolean.h"
|
||||
#include "../thread.h"
|
||||
|
||||
typedef struct rsd
|
||||
{
|
||||
rsound_t *rd;
|
||||
int latency;
|
||||
int rate;
|
||||
int nonblock;
|
||||
bool nonblock;
|
||||
volatile bool has_error;
|
||||
|
||||
fifo_buffer_t *buffer;
|
||||
|
||||
slock_t *cond_lock;
|
||||
scond_t *cond;
|
||||
} rsd_t;
|
||||
|
||||
static void* __rsd_init(const char* device, int rate, int latency)
|
||||
static ssize_t audio_cb(void *data, size_t bytes, void *userdata)
|
||||
{
|
||||
rsd_t *rsd = calloc(1, sizeof(rsd_t));
|
||||
if ( rsd == NULL )
|
||||
rsd_t *rsd = (rsd_t*)userdata;
|
||||
|
||||
size_t avail = fifo_read_avail(rsd->buffer);
|
||||
size_t write_size = bytes > avail ? avail : bytes;
|
||||
fifo_read(rsd->buffer, data, write_size);
|
||||
scond_signal(rsd->cond);
|
||||
|
||||
return write_size;
|
||||
}
|
||||
|
||||
static void err_cb(void *userdata)
|
||||
{
|
||||
rsd_t *rsd = (rsd_t*)userdata;
|
||||
rsd->has_error = true;
|
||||
scond_signal(rsd->cond);
|
||||
}
|
||||
|
||||
static void *rs_init(const char *device, unsigned rate, unsigned latency)
|
||||
{
|
||||
rsd_t *rsd = (rsd_t*)calloc(1, sizeof(rsd_t));
|
||||
if (!rsd)
|
||||
return NULL;
|
||||
|
||||
rsound_t *rd;
|
||||
|
||||
if ( rsd_init(&rd) < 0 )
|
||||
if (rsd_init(&rd) < 0)
|
||||
{
|
||||
free(rsd);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
rsd->cond_lock = slock_new();
|
||||
rsd->cond = scond_new();
|
||||
|
||||
rsd->buffer = fifo_new(1024 * 4);
|
||||
|
||||
int channels = 2;
|
||||
int format = RSD_S16_NE;
|
||||
|
||||
rsd_set_param(rd, RSD_CHANNELS, &channels);
|
||||
rsd_set_param(rd, RSD_SAMPLERATE, &rate);
|
||||
rsd_set_param(rd, RSD_LATENCY, &latency);
|
||||
|
||||
if ( device != NULL )
|
||||
if (device)
|
||||
rsd_set_param(rd, RSD_HOST, (void*)device);
|
||||
|
||||
rsd_set_param(rd, RSD_FORMAT, &format);
|
||||
|
||||
if ( rsd_start(rd) < 0 )
|
||||
rsd_set_callback(rd, audio_cb, err_cb, 256, rsd);
|
||||
|
||||
if (rsd_start(rd) < 0)
|
||||
{
|
||||
free(rsd);
|
||||
rsd_free(rd);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
int min_latency = (rsd_delay_ms(rd) > latency) ? (rsd_delay_ms(rd) * 3 / 2) : latency;
|
||||
|
||||
rsd_set_param(rd, RSD_LATENCY, &min_latency);
|
||||
|
||||
rsd->rd = rd;
|
||||
rsd->latency = min_latency;
|
||||
rsd->rate = rate;
|
||||
|
||||
return rsd;
|
||||
}
|
||||
|
||||
static ssize_t __rsd_write(void* data, const void* buf, size_t size)
|
||||
static ssize_t rs_write(void *data, const void *buf, size_t size)
|
||||
{
|
||||
rsd_t *rsd = data;
|
||||
rsd_t *rsd = (rsd_t*)data;
|
||||
|
||||
if ( (rsd_delay_ms(rsd->rd) > rsd->latency || rsd_get_avail(rsd->rd) < size) && rsd->nonblock )
|
||||
return 0;
|
||||
|
||||
if ( size == 0 )
|
||||
return 0;
|
||||
|
||||
rsd_delay_wait(rsd->rd);
|
||||
if ( rsd_write(rsd->rd, buf, size) == 0 )
|
||||
if (rsd->has_error)
|
||||
return -1;
|
||||
|
||||
if ( rsd_delay_ms(rsd->rd) < rsd->latency/2 )
|
||||
if (rsd->nonblock)
|
||||
{
|
||||
int ms = rsd->latency/2;
|
||||
size_t size = (ms * rsd->rate * 4) / 1000;
|
||||
void *temp = calloc(1, size);
|
||||
rsd_write(rsd->rd, temp, size);
|
||||
free(temp);
|
||||
rsd_callback_lock(rsd->rd);
|
||||
size_t avail = fifo_write_avail(rsd->buffer);
|
||||
size_t write_amt = avail > size ? size : avail;
|
||||
fifo_write(rsd->buffer, buf, write_amt);
|
||||
rsd_callback_unlock(rsd->rd);
|
||||
return write_amt;
|
||||
}
|
||||
else
|
||||
{
|
||||
size_t written = 0;
|
||||
while (written < size && !rsd->has_error)
|
||||
{
|
||||
rsd_callback_lock(rsd->rd);
|
||||
size_t avail = fifo_write_avail(rsd->buffer);
|
||||
|
||||
return size;
|
||||
if (avail == 0)
|
||||
{
|
||||
rsd_callback_unlock(rsd->rd);
|
||||
if (!rsd->has_error)
|
||||
{
|
||||
slock_lock(rsd->cond_lock);
|
||||
scond_wait(rsd->cond, rsd->cond_lock);
|
||||
slock_unlock(rsd->cond_lock);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
size_t write_amt = size - written > avail ? avail : size - written;
|
||||
fifo_write(rsd->buffer, (const char*)buf + written, write_amt);
|
||||
rsd_callback_unlock(rsd->rd);
|
||||
written += write_amt;
|
||||
}
|
||||
}
|
||||
return written;
|
||||
}
|
||||
}
|
||||
|
||||
static bool __rsd_stop(void *data)
|
||||
static bool rs_stop(void *data)
|
||||
{
|
||||
rsd_t *rsd = data;
|
||||
rsd_t *rsd = (rsd_t*)data;
|
||||
rsd_stop(rsd->rd);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
static void __rsd_set_nonblock_state(void *data, bool state)
|
||||
static void rs_set_nonblock_state(void *data, bool state)
|
||||
{
|
||||
rsd_t *rsd = data;
|
||||
rsd_t *rsd = (rsd_t*)data;
|
||||
rsd->nonblock = state;
|
||||
}
|
||||
|
||||
static bool __rsd_start(void *data)
|
||||
static bool rs_start(void *data)
|
||||
{
|
||||
rsd_t *rsd = data;
|
||||
if ( rsd_start(rsd->rd) < 0)
|
||||
rsd_t *rsd = (rsd_t*)data;
|
||||
if (rsd_start(rsd->rd) < 0)
|
||||
return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
static void __rsd_free(void *data)
|
||||
static void rs_free(void *data)
|
||||
{
|
||||
rsd_t *rsd = data;
|
||||
rsd_t *rsd = (rsd_t*)data;
|
||||
|
||||
rsd_stop(rsd->rd);
|
||||
rsd_free(rsd->rd);
|
||||
|
||||
fifo_free(rsd->buffer);
|
||||
slock_free(rsd->cond_lock);
|
||||
scond_free(rsd->cond);
|
||||
|
||||
free(rsd);
|
||||
}
|
||||
|
||||
static size_t rs_write_avail(void *data)
|
||||
{
|
||||
rsd_t *rsd = (rsd_t*)data;
|
||||
|
||||
if (rsd->has_error)
|
||||
return 0;
|
||||
rsd_callback_lock(rsd->rd);
|
||||
size_t val = fifo_write_avail(rsd->buffer);
|
||||
rsd_callback_unlock(rsd->rd);
|
||||
return val;
|
||||
}
|
||||
|
||||
static size_t rs_buffer_size(void *data)
|
||||
{
|
||||
(void)data;
|
||||
return 1024 * 4;
|
||||
}
|
||||
|
||||
const audio_driver_t audio_rsound = {
|
||||
.init = __rsd_init,
|
||||
.write = __rsd_write,
|
||||
.stop = __rsd_stop,
|
||||
.start = __rsd_start,
|
||||
.set_nonblock_state = __rsd_set_nonblock_state,
|
||||
.free = __rsd_free,
|
||||
.ident = "rsound"
|
||||
rs_init,
|
||||
rs_write,
|
||||
rs_stop,
|
||||
rs_start,
|
||||
rs_set_nonblock_state,
|
||||
rs_free,
|
||||
NULL,
|
||||
"rsound",
|
||||
rs_write_avail,
|
||||
rs_buffer_size,
|
||||
};
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -1,69 +1,55 @@
|
||||
/* SSNES - A Super Nintendo Entertainment System (SNES) Emulator frontend for libsnes.
|
||||
* Copyright (C) 2010-2011 - Hans-Kristian Arntzen
|
||||
*
|
||||
* Some code herein may be based on code found in BSNES.
|
||||
/* RetroArch - A frontend for libretro.
|
||||
* Copyright (C) 2010-2012 - Hans-Kristian Arntzen
|
||||
*
|
||||
* SSNES is free software: you can redistribute it and/or modify it under the terms
|
||||
* RetroArch is free software: you can redistribute it and/or modify it under the terms
|
||||
* of the GNU General Public License as published by the Free Software Found-
|
||||
* ation, either version 3 of the License, or (at your option) any later version.
|
||||
*
|
||||
* SSNES is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
|
||||
* RetroArch is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
|
||||
* without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
|
||||
* PURPOSE. See the GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along with SSNES.
|
||||
* You should have received a copy of the GNU General Public License along with RetroArch.
|
||||
* If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
|
||||
#include "driver.h"
|
||||
#include "../driver.h"
|
||||
#include <stdlib.h>
|
||||
#include <stdbool.h>
|
||||
#include "../boolean.h"
|
||||
#include <stddef.h>
|
||||
#include <stdint.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "SDL.h"
|
||||
#include "SDL_audio.h"
|
||||
#include "SDL_thread.h"
|
||||
#include "general.h"
|
||||
#include "buffer.h"
|
||||
#include "../thread.h"
|
||||
|
||||
#include "../general.h"
|
||||
#include "../fifo_buffer.h"
|
||||
|
||||
typedef struct sdl_audio
|
||||
{
|
||||
bool nonblock;
|
||||
|
||||
SDL_mutex *lock;
|
||||
SDL_cond *cond;
|
||||
rsound_fifo_buffer_t *buffer;
|
||||
slock_t *lock;
|
||||
scond_t *cond;
|
||||
fifo_buffer_t *buffer;
|
||||
} sdl_audio_t;
|
||||
|
||||
static void sdl_audio_cb(void *data, Uint8 *stream, int len)
|
||||
{
|
||||
sdl_audio_t *sdl = data;
|
||||
sdl_audio_t *sdl = (sdl_audio_t*)data;
|
||||
|
||||
size_t avail = rsnd_fifo_read_avail(sdl->buffer);
|
||||
size_t write_size = len > avail ? avail : len;
|
||||
rsnd_fifo_read(sdl->buffer, stream, write_size);
|
||||
SDL_CondSignal(sdl->cond);
|
||||
size_t avail = fifo_read_avail(sdl->buffer);
|
||||
size_t write_size = len > (int)avail ? avail : len;
|
||||
fifo_read(sdl->buffer, stream, write_size);
|
||||
scond_signal(sdl->cond);
|
||||
|
||||
// If underrun, fill rest with silence.
|
||||
memset(stream + write_size, 0, len - write_size);
|
||||
}
|
||||
|
||||
// Interesting hack from http://www-graphics.stanford.edu/~seander/bithacks.html#RoundUpPowerOf2
|
||||
static inline uint32_t next_pow2(uint32_t v)
|
||||
{
|
||||
v--;
|
||||
v |= v >> 1;
|
||||
v |= v >> 2;
|
||||
v |= v >> 4;
|
||||
v |= v >> 8;
|
||||
v |= v >> 16;
|
||||
v++;
|
||||
return v;
|
||||
}
|
||||
|
||||
static inline int find_num_frames(int rate, int latency)
|
||||
{
|
||||
int frames = (rate * latency) / 1000;
|
||||
@@ -71,50 +57,49 @@ static inline int find_num_frames(int rate, int latency)
|
||||
return next_pow2(frames);
|
||||
}
|
||||
|
||||
static void* sdl_audio_init(const char* device, int rate, int latency)
|
||||
static void *sdl_audio_init(const char *device, unsigned rate, unsigned latency)
|
||||
{
|
||||
(void)device;
|
||||
if (SDL_InitSubSystem(SDL_INIT_AUDIO) < 0)
|
||||
return NULL;
|
||||
|
||||
sdl_audio_t *sdl = calloc(1, sizeof(*sdl));
|
||||
sdl_audio_t *sdl = (sdl_audio_t*)calloc(1, sizeof(*sdl));
|
||||
if (!sdl)
|
||||
return NULL;
|
||||
|
||||
// We have to buffer up some data ourselves, so we let SDL carry approx half of the latency. SDL double buffers audio and we do as well.
|
||||
int frames = find_num_frames(rate, latency / 4);
|
||||
|
||||
SDL_AudioSpec spec = {
|
||||
.freq = rate,
|
||||
.format = AUDIO_S16SYS,
|
||||
.channels = 2,
|
||||
.samples = frames, // This is in audio frames, not samples ... :(
|
||||
.callback = sdl_audio_cb,
|
||||
.userdata = sdl
|
||||
};
|
||||
SDL_AudioSpec spec = {0};
|
||||
spec.freq = rate;
|
||||
spec.format = AUDIO_S16SYS;
|
||||
spec.channels = 2;
|
||||
spec.samples = frames; // This is in audio frames, not samples ... :(
|
||||
spec.callback = sdl_audio_cb;
|
||||
spec.userdata = sdl;
|
||||
|
||||
SDL_AudioSpec out;
|
||||
|
||||
if (SDL_OpenAudio(&spec, &out) < 0)
|
||||
{
|
||||
SSNES_ERR("Failed to open SDL audio: %s\n", SDL_GetError());
|
||||
RARCH_ERR("Failed to open SDL audio: %s\n", SDL_GetError());
|
||||
free(sdl);
|
||||
return 0;
|
||||
}
|
||||
g_settings.audio.out_rate = out.freq;
|
||||
|
||||
sdl->lock = SDL_CreateMutex();
|
||||
sdl->cond = SDL_CreateCond();
|
||||
sdl->lock = slock_new();
|
||||
sdl->cond = scond_new();
|
||||
|
||||
SSNES_LOG("SDL audio: Requested %d ms latency, got %d ms\n", latency, (int)(out.samples * 4 * 1000 / g_settings.audio.out_rate));
|
||||
RARCH_LOG("SDL audio: Requested %d ms latency, got %d ms\n", latency, (int)(out.samples * 4 * 1000 / g_settings.audio.out_rate));
|
||||
|
||||
// Create a buffer twice as big as needed and prefill the buffer.
|
||||
size_t bufsize = out.samples * 4 * sizeof(int16_t);
|
||||
void *tmp = calloc(1, bufsize);
|
||||
sdl->buffer = rsnd_fifo_new(bufsize);
|
||||
sdl->buffer = fifo_new(bufsize);
|
||||
if (tmp)
|
||||
{
|
||||
rsnd_fifo_write(sdl->buffer, tmp, bufsize);
|
||||
fifo_write(sdl->buffer, tmp, bufsize);
|
||||
free(tmp);
|
||||
}
|
||||
|
||||
@@ -122,17 +107,17 @@ static void* sdl_audio_init(const char* device, int rate, int latency)
|
||||
return sdl;
|
||||
}
|
||||
|
||||
static ssize_t sdl_audio_write(void* data, const void* buf, size_t size)
|
||||
static ssize_t sdl_audio_write(void *data, const void *buf, size_t size)
|
||||
{
|
||||
sdl_audio_t *sdl = data;
|
||||
sdl_audio_t *sdl = (sdl_audio_t*)data;
|
||||
|
||||
ssize_t ret = 0;
|
||||
if (sdl->nonblock)
|
||||
{
|
||||
SDL_LockAudio();
|
||||
size_t avail = rsnd_fifo_write_avail(sdl->buffer);
|
||||
size_t avail = fifo_write_avail(sdl->buffer);
|
||||
size_t write_amt = avail > size ? size : avail;
|
||||
rsnd_fifo_write(sdl->buffer, buf, write_amt);
|
||||
fifo_write(sdl->buffer, buf, write_amt);
|
||||
SDL_UnlockAudio();
|
||||
ret = write_amt;
|
||||
}
|
||||
@@ -142,19 +127,19 @@ static ssize_t sdl_audio_write(void* data, const void* buf, size_t size)
|
||||
while (written < size)
|
||||
{
|
||||
SDL_LockAudio();
|
||||
size_t avail = rsnd_fifo_write_avail(sdl->buffer);
|
||||
size_t avail = fifo_write_avail(sdl->buffer);
|
||||
|
||||
if (avail == 0)
|
||||
{
|
||||
SDL_UnlockAudio();
|
||||
SDL_mutexP(sdl->lock);
|
||||
SDL_CondWait(sdl->cond, sdl->lock);
|
||||
SDL_mutexV(sdl->lock);
|
||||
slock_lock(sdl->lock);
|
||||
scond_wait(sdl->cond, sdl->lock);
|
||||
slock_unlock(sdl->lock);
|
||||
}
|
||||
else
|
||||
{
|
||||
size_t write_amt = size - written > avail ? avail : size - written;
|
||||
rsnd_fifo_write(sdl->buffer, (const char*)buf + written, write_amt);
|
||||
fifo_write(sdl->buffer, (const char*)buf + written, write_amt);
|
||||
SDL_UnlockAudio();
|
||||
written += write_amt;
|
||||
}
|
||||
@@ -181,7 +166,7 @@ static bool sdl_audio_start(void *data)
|
||||
|
||||
static void sdl_audio_set_nonblock_state(void *data, bool state)
|
||||
{
|
||||
sdl_audio_t *sdl = data;
|
||||
sdl_audio_t *sdl = (sdl_audio_t*)data;
|
||||
sdl->nonblock = state;
|
||||
}
|
||||
|
||||
@@ -190,28 +175,24 @@ static void sdl_audio_free(void *data)
|
||||
SDL_CloseAudio();
|
||||
SDL_QuitSubSystem(SDL_INIT_AUDIO);
|
||||
|
||||
sdl_audio_t *sdl = data;
|
||||
sdl_audio_t *sdl = (sdl_audio_t*)data;
|
||||
if (sdl)
|
||||
{
|
||||
rsnd_fifo_free(sdl->buffer);
|
||||
SDL_DestroyMutex(sdl->lock);
|
||||
SDL_DestroyCond(sdl->cond);
|
||||
fifo_free(sdl->buffer);
|
||||
slock_free(sdl->lock);
|
||||
scond_free(sdl->cond);
|
||||
}
|
||||
free(sdl);
|
||||
}
|
||||
|
||||
const audio_driver_t audio_sdl = {
|
||||
.init = sdl_audio_init,
|
||||
.write = sdl_audio_write,
|
||||
.stop = sdl_audio_stop,
|
||||
.start = sdl_audio_start,
|
||||
.set_nonblock_state = sdl_audio_set_nonblock_state,
|
||||
.free = sdl_audio_free,
|
||||
.ident = "sdl"
|
||||
sdl_audio_init,
|
||||
sdl_audio_write,
|
||||
sdl_audio_stop,
|
||||
sdl_audio_start,
|
||||
sdl_audio_set_nonblock_state,
|
||||
sdl_audio_free,
|
||||
NULL,
|
||||
"sdl"
|
||||
};
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
+264
@@ -0,0 +1,264 @@
|
||||
/* RetroArch - A frontend for libretro.
|
||||
* Copyright (C) 2010-2012 - Hans-Kristian Arntzen
|
||||
*
|
||||
* RetroArch is free software: you can redistribute it and/or modify it under the terms
|
||||
* of the GNU General Public License as published by the Free Software Found-
|
||||
* ation, either version 3 of the License, or (at your option) any later version.
|
||||
*
|
||||
* RetroArch is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
|
||||
* without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
|
||||
* PURPOSE. See the GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along with RetroArch.
|
||||
* If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
// Bog-standard windowed SINC implementation.
|
||||
// Only suitable as an upsampler, as there is no low-pass filter stage.
|
||||
|
||||
#include "resampler.h"
|
||||
#include <math.h>
|
||||
#include <stdint.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
#ifndef RESAMPLER_TEST
|
||||
#include "../general.h"
|
||||
#else
|
||||
#define RARCH_LOG(...)
|
||||
#endif
|
||||
|
||||
#if __SSE__
|
||||
#include <xmmintrin.h>
|
||||
#endif
|
||||
|
||||
#define PHASE_BITS 8
|
||||
#define SUBPHASE_BITS 16
|
||||
|
||||
#define PHASES (1 << PHASE_BITS)
|
||||
#define PHASES_SHIFT (SUBPHASE_BITS)
|
||||
#define SUBPHASES (1 << SUBPHASE_BITS)
|
||||
#define SUBPHASES_SHIFT 0
|
||||
#define SUBPHASES_MASK ((1 << SUBPHASE_BITS) - 1)
|
||||
#define PHASES_WRAP (1 << (PHASE_BITS + SUBPHASE_BITS))
|
||||
#define FRAMES_SHIFT (PHASE_BITS + SUBPHASE_BITS)
|
||||
|
||||
#define SIDELOBES 8
|
||||
#define TAPS (SIDELOBES * 2)
|
||||
#define CUTOFF 1.0
|
||||
|
||||
#define PHASE_INDEX 0
|
||||
#define DELTA_INDEX 1
|
||||
|
||||
struct rarch_resampler
|
||||
{
|
||||
float phase_table[PHASES][2][TAPS];
|
||||
float buffer_l[2 * TAPS];
|
||||
float buffer_r[2 * TAPS];
|
||||
|
||||
unsigned ptr;
|
||||
|
||||
uint32_t time;
|
||||
};
|
||||
|
||||
static inline double sinc(double val)
|
||||
{
|
||||
if (fabs(val) < 0.00001)
|
||||
return 1.0;
|
||||
else
|
||||
return sin(val) / val;
|
||||
}
|
||||
|
||||
static inline double lanzcos(double index)
|
||||
{
|
||||
return sinc(index);
|
||||
}
|
||||
|
||||
static void init_sinc_table(rarch_resampler_t *resamp)
|
||||
{
|
||||
// Sinc phases: [..., p + 3, p + 2, p + 1, p + 0, p - 1, p - 2, p - 3, p - 4, ...]
|
||||
for (int i = 0; i < PHASES; i++)
|
||||
{
|
||||
for (int j = 0; j < TAPS; j++)
|
||||
{
|
||||
double p = (double)i / PHASES;
|
||||
double sinc_phase = M_PI * (p + (SIDELOBES - 1 - j));
|
||||
resamp->phase_table[i][PHASE_INDEX][j] = CUTOFF * sinc(CUTOFF * sinc_phase) *
|
||||
lanzcos(sinc_phase / SIDELOBES);
|
||||
}
|
||||
}
|
||||
|
||||
// Optimize linear interpolation.
|
||||
for (int i = 0; i < PHASES - 1; i++)
|
||||
{
|
||||
for (int j = 0; j < TAPS; j++)
|
||||
{
|
||||
resamp->phase_table[i][DELTA_INDEX][j] =
|
||||
(resamp->phase_table[i + 1][PHASE_INDEX][j] - resamp->phase_table[i][PHASE_INDEX][j]) / SUBPHASES;
|
||||
}
|
||||
}
|
||||
|
||||
// Interpolation between [PHASES - 1] => [PHASES]
|
||||
for (int j = 0; j < TAPS; j++)
|
||||
{
|
||||
double p = 1.0;
|
||||
double sinc_phase = M_PI * (p + (SIDELOBES - 1 - j));
|
||||
double phase = CUTOFF * sinc(CUTOFF * sinc_phase) * lanzcos(sinc_phase / SIDELOBES);
|
||||
|
||||
float result = (phase - resamp->phase_table[PHASES - 1][PHASE_INDEX][j]) / SUBPHASES;
|
||||
resamp->phase_table[PHASES - 1][DELTA_INDEX][j] = result;
|
||||
}
|
||||
}
|
||||
|
||||
// No memalign() for us on Win32 ...
|
||||
static void *aligned_alloc(size_t boundary, size_t size)
|
||||
{
|
||||
void *ptr = malloc(boundary + size + sizeof(uintptr_t));
|
||||
if (!ptr)
|
||||
return NULL;
|
||||
|
||||
uintptr_t addr = ((uintptr_t)ptr + sizeof(uintptr_t) + boundary) & ~(boundary - 1);
|
||||
void **place = (void**)addr;
|
||||
place[-1] = ptr;
|
||||
|
||||
return (void*)addr;
|
||||
}
|
||||
|
||||
static void aligned_free(void *ptr)
|
||||
{
|
||||
void **p = (void**)ptr;
|
||||
free(p[-1]);
|
||||
}
|
||||
|
||||
rarch_resampler_t *resampler_new(void)
|
||||
{
|
||||
rarch_resampler_t *re = (rarch_resampler_t*)aligned_alloc(16, sizeof(*re));
|
||||
if (!re)
|
||||
return NULL;
|
||||
|
||||
memset(re, 0, sizeof(*re));
|
||||
|
||||
init_sinc_table(re);
|
||||
|
||||
#if __SSE__
|
||||
RARCH_LOG("Sinc resampler [SSE]\n");
|
||||
#else
|
||||
RARCH_LOG("Sinc resampler [C]\n");
|
||||
#endif
|
||||
|
||||
return re;
|
||||
}
|
||||
|
||||
#if __SSE__
|
||||
static void process_sinc(rarch_resampler_t *resamp, float *out_buffer)
|
||||
{
|
||||
__m128 sum_l = _mm_setzero_ps();
|
||||
__m128 sum_r = _mm_setzero_ps();
|
||||
|
||||
const float *buffer_l = resamp->buffer_l + resamp->ptr;
|
||||
const float *buffer_r = resamp->buffer_r + resamp->ptr;
|
||||
|
||||
unsigned phase = resamp->time >> PHASES_SHIFT;
|
||||
unsigned delta = (resamp->time >> SUBPHASES_SHIFT) & SUBPHASES_MASK;
|
||||
__m128 delta_f = _mm_set1_ps(delta);
|
||||
|
||||
const float *phase_table = resamp->phase_table[phase][PHASE_INDEX];
|
||||
const float *delta_table = resamp->phase_table[phase][DELTA_INDEX];
|
||||
|
||||
for (unsigned i = 0; i < TAPS; i += 4)
|
||||
{
|
||||
__m128 buf_l = _mm_loadu_ps(buffer_l + i);
|
||||
__m128 buf_r = _mm_loadu_ps(buffer_r + i);
|
||||
|
||||
__m128 phases = _mm_load_ps(phase_table + i);
|
||||
__m128 deltas = _mm_load_ps(delta_table + i);
|
||||
|
||||
__m128 sinc = _mm_add_ps(phases, _mm_mul_ps(deltas, delta_f));
|
||||
|
||||
sum_l = _mm_add_ps(sum_l, _mm_mul_ps(buf_l, sinc));
|
||||
sum_r = _mm_add_ps(sum_r, _mm_mul_ps(buf_r, sinc));
|
||||
}
|
||||
|
||||
// Them annoying shuffles :V
|
||||
// sum_l = { l3, l2, l1, l0 }
|
||||
// sum_r = { r3, r2, r1, r0 }
|
||||
|
||||
__m128 sum = _mm_add_ps(_mm_shuffle_ps(sum_l, sum_r, _MM_SHUFFLE(1, 0, 1, 0)),
|
||||
_mm_shuffle_ps(sum_l, sum_r, _MM_SHUFFLE(3, 2, 3, 2)));
|
||||
|
||||
// sum = { r1, r0, l1, l0 } + { r3, r2, l3, l2 }
|
||||
// sum = { R1, R0, L1, L0 }
|
||||
|
||||
sum = _mm_add_ps(_mm_shuffle_ps(sum, sum, _MM_SHUFFLE(3, 3, 1, 1)), sum);
|
||||
|
||||
// sum = {R1, R1, L1, L1 } + { R1, R0, L1, L0 }
|
||||
// sum = { X, R, X, L }
|
||||
|
||||
// Store L
|
||||
_mm_store_ss(out_buffer + 0, sum);
|
||||
|
||||
// movehl { X, R, X, L } == { X, R, X, R }
|
||||
_mm_store_ss(out_buffer + 1, _mm_movehl_ps(sum, sum));
|
||||
}
|
||||
#else // Plain ol' C99
|
||||
static void process_sinc(rarch_resampler_t *resamp, float *out_buffer)
|
||||
{
|
||||
float sum_l = 0.0f;
|
||||
float sum_r = 0.0f;
|
||||
const float *buffer_l = resamp->buffer_l + resamp->ptr;
|
||||
const float *buffer_r = resamp->buffer_r + resamp->ptr;
|
||||
|
||||
unsigned phase = resamp->time >> PHASES_SHIFT;
|
||||
unsigned delta = (resamp->time >> SUBPHASES_SHIFT) & SUBPHASES_MASK;
|
||||
float delta_f = (float)delta;
|
||||
|
||||
const float *phase_table = resamp->phase_table[phase][PHASE_INDEX];
|
||||
const float *delta_table = resamp->phase_table[phase][DELTA_INDEX];
|
||||
|
||||
for (unsigned i = 0; i < TAPS; i++)
|
||||
{
|
||||
float sinc_val = phase_table[i] + delta_f * delta_table[i];
|
||||
sum_l += buffer_l[i] * sinc_val;
|
||||
sum_r += buffer_r[i] * sinc_val;
|
||||
}
|
||||
|
||||
out_buffer[0] = sum_l;
|
||||
out_buffer[1] = sum_r;
|
||||
}
|
||||
#endif
|
||||
|
||||
void resampler_process(rarch_resampler_t *re, struct resampler_data *data)
|
||||
{
|
||||
uint32_t ratio = PHASES_WRAP / data->ratio;
|
||||
|
||||
const float *input = data->data_in;
|
||||
float *output = data->data_out;
|
||||
size_t frames = data->input_frames;
|
||||
size_t out_frames = 0;
|
||||
|
||||
while (frames)
|
||||
{
|
||||
process_sinc(re, output);
|
||||
output += 2;
|
||||
out_frames++;
|
||||
|
||||
re->time += ratio;
|
||||
while (re->time >= PHASES_WRAP)
|
||||
{
|
||||
re->buffer_l[re->ptr + TAPS] = re->buffer_l[re->ptr] = *input++;
|
||||
re->buffer_r[re->ptr + TAPS] = re->buffer_r[re->ptr] = *input++;
|
||||
re->ptr = (re->ptr + 1) & (TAPS - 1);
|
||||
|
||||
re->time -= PHASES_WRAP;
|
||||
frames--;
|
||||
}
|
||||
}
|
||||
|
||||
data->output_frames = out_frames;
|
||||
}
|
||||
|
||||
void resampler_free(rarch_resampler_t *re)
|
||||
{
|
||||
aligned_free(re);
|
||||
}
|
||||
|
||||
@@ -0,0 +1,29 @@
|
||||
TESTS := test-hermite test-sinc test-snr-sinc test-snr-hermite
|
||||
|
||||
CFLAGS += -O3 -g -Wall -pedantic -std=gnu99 -DRESAMPLER_TEST -march=native
|
||||
LDFLAGS += -lm
|
||||
|
||||
all: $(TESTS)
|
||||
|
||||
test-hermite: ../hermite.o ../utils.o main.o
|
||||
$(CC) -o $@ $^ $(LDFLAGS)
|
||||
|
||||
test-sinc: ../sinc.o ../utils.o main.o
|
||||
$(CC) -o $@ $^ $(LDFLAGS)
|
||||
|
||||
test-snr-sinc: ../sinc.o ../utils.o snr.o
|
||||
$(CC) -o $@ $^ $(LDFLAGS)
|
||||
|
||||
test-snr-hermite: ../hermite.o ../utils.o snr.o
|
||||
$(CC) -o $@ $^ $(LDFLAGS)
|
||||
|
||||
%.o: %.c
|
||||
$(CC) -c -o $@ $< $(CFLAGS)
|
||||
|
||||
clean:
|
||||
rm -f $(TESTS)
|
||||
rm -f *.o
|
||||
rm -f ../*.o
|
||||
|
||||
.PHONY: clean
|
||||
|
||||
@@ -0,0 +1,79 @@
|
||||
/* RetroArch - A frontend for libretro.
|
||||
* Copyright (C) 2010-2012 - Hans-Kristian Arntzen
|
||||
*
|
||||
* RetroArch is free software: you can redistribute it and/or modify it under the terms
|
||||
* of the GNU General Public License as published by the Free Software Found-
|
||||
* ation, either version 3 of the License, or (at your option) any later version.
|
||||
*
|
||||
* RetroArch is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
|
||||
* without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
|
||||
* PURPOSE. See the GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along with RetroArch.
|
||||
* If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
// Resampler that reads raw S16NE/stereo from stdin and outputs to stdout in S16NE/stereo.
|
||||
// Used for testing and performance benchmarking.
|
||||
|
||||
#include "../resampler.h"
|
||||
#include "../utils.h"
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
int main(int argc, char *argv[])
|
||||
{
|
||||
int16_t input_i[1024];
|
||||
float input_f[1024];
|
||||
int16_t output_i[1024 * 8];
|
||||
float output_f[1024 * 8];
|
||||
|
||||
if (argc != 3)
|
||||
{
|
||||
fprintf(stderr, "Usage: %s <in-rate> <out-rate> (max ratio: 8.0)\n", argv[0]);
|
||||
return 1;
|
||||
}
|
||||
|
||||
double in_rate = strtod(argv[1], NULL);
|
||||
double out_rate = strtod(argv[2], NULL);
|
||||
|
||||
double ratio = out_rate / in_rate;
|
||||
if (ratio >= 7.99)
|
||||
{
|
||||
fprintf(stderr, "Ratio is too high.\n");
|
||||
return 1;
|
||||
}
|
||||
|
||||
rarch_resampler_t *resamp = resampler_new();
|
||||
if (!resamp)
|
||||
{
|
||||
fprintf(stderr, "Failed to allocate resampler ...\n");
|
||||
return 1;
|
||||
}
|
||||
|
||||
for (;;)
|
||||
{
|
||||
if (fread(input_i, sizeof(int16_t), 1024, stdin) != 1024)
|
||||
break;
|
||||
|
||||
audio_convert_s16_to_float(input_f, input_i, 1024);
|
||||
|
||||
struct resampler_data data = {
|
||||
.data_in = input_f,
|
||||
.data_out = output_f,
|
||||
.input_frames = sizeof(input_f) / (2 * sizeof(float)),
|
||||
.ratio = ratio,
|
||||
};
|
||||
|
||||
resampler_process(resamp, &data);
|
||||
|
||||
size_t output_samples = data.output_frames * 2;
|
||||
audio_convert_float_to_s16(output_i, output_f, output_samples);
|
||||
|
||||
if (fwrite(output_i, sizeof(int16_t), output_samples, stdout) != output_samples)
|
||||
break;
|
||||
}
|
||||
|
||||
resampler_free(resamp);
|
||||
}
|
||||
|
||||
@@ -0,0 +1,316 @@
|
||||
/* RetroArch - A frontend for libretro.
|
||||
* Copyright (C) 2010-2012 - Hans-Kristian Arntzen
|
||||
*
|
||||
* RetroArch is free software: you can redistribute it and/or modify it under the terms
|
||||
* of the GNU General Public License as published by the Free Software Found-
|
||||
* ation, either version 3 of the License, or (at your option) any later version.
|
||||
*
|
||||
* RetroArch is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
|
||||
* without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
|
||||
* PURPOSE. See the GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along with RetroArch.
|
||||
* If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include "../resampler.h"
|
||||
#include "../utils.h"
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <math.h>
|
||||
#include <complex.h>
|
||||
#include <string.h>
|
||||
#include <assert.h>
|
||||
#include <stdbool.h>
|
||||
|
||||
static void gen_signal(float *out, double omega, double bias_samples, size_t samples)
|
||||
{
|
||||
for (size_t i = 0; i < samples; i += 2)
|
||||
{
|
||||
out[i + 0] = cos(((i >> 1) + bias_samples) * omega);
|
||||
out[i + 1] = out[i + 0];
|
||||
}
|
||||
}
|
||||
|
||||
struct snr_result
|
||||
{
|
||||
double snr;
|
||||
double gain;
|
||||
|
||||
unsigned alias_freq[3];
|
||||
double alias_power[3];
|
||||
};
|
||||
|
||||
static unsigned bitrange(unsigned len)
|
||||
{
|
||||
unsigned ret = 0;
|
||||
while ((len >>= 1))
|
||||
ret++;
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static unsigned bitswap(unsigned i, unsigned range)
|
||||
{
|
||||
unsigned ret = 0;
|
||||
for (unsigned shifts = 0; shifts < range; shifts++)
|
||||
ret |= i & (1 << (range - shifts - 1)) ? (1 << shifts) : 0;
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
// When interleaving the butterfly buffer, addressing puts bits in reverse.
|
||||
// [0, 1, 2, 3, 4, 5, 6, 7] => [0, 4, 2, 6, 1, 5, 3, 7]
|
||||
static void interleave(complex double *butterfly_buf, size_t samples)
|
||||
{
|
||||
unsigned range = bitrange(samples);
|
||||
for (unsigned i = 0; i < samples; i++)
|
||||
{
|
||||
unsigned target = bitswap(i, range);
|
||||
if (target > i)
|
||||
{
|
||||
complex double tmp = butterfly_buf[target];
|
||||
butterfly_buf[target] = butterfly_buf[i];
|
||||
butterfly_buf[i] = tmp;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static complex double gen_phase(double index)
|
||||
{
|
||||
return cexp(M_PI * I * index);
|
||||
}
|
||||
|
||||
static void butterfly(complex double *a, complex double *b, complex double mod)
|
||||
{
|
||||
mod *= *b;
|
||||
complex double a_ = *a + mod;
|
||||
complex double b_ = *a - mod;
|
||||
*a = a_;
|
||||
*b = b_;
|
||||
}
|
||||
|
||||
static void butterflies(complex double *butterfly_buf, double phase_dir, size_t step_size, size_t samples)
|
||||
{
|
||||
for (unsigned i = 0; i < samples; i += 2 * step_size)
|
||||
for (unsigned j = i; j < i + step_size; j++)
|
||||
butterfly(&butterfly_buf[j], &butterfly_buf[j + step_size], gen_phase((phase_dir * (j - i)) / step_size));
|
||||
}
|
||||
|
||||
static void calculate_fft(const float *data, complex double *butterfly_buf, size_t samples)
|
||||
{
|
||||
// Enforce POT.
|
||||
assert((samples & (samples - 1)) == 0);
|
||||
|
||||
for (unsigned i = 0; i < samples; i++)
|
||||
butterfly_buf[i] = data[2 * i];
|
||||
|
||||
// Interleave buffer to work with FFT.
|
||||
interleave(butterfly_buf, samples);
|
||||
|
||||
// Fly, lovely butterflies! :D
|
||||
for (unsigned step_size = 1; step_size < samples; step_size *= 2)
|
||||
butterflies(butterfly_buf, -1.0, step_size, samples);
|
||||
}
|
||||
|
||||
static void calculate_fft_adjust(complex double *butterfly_buf, double gain, bool merge_high, size_t samples)
|
||||
{
|
||||
if (merge_high)
|
||||
{
|
||||
for (unsigned i = 1; i < samples / 2; i++)
|
||||
butterfly_buf[i] *= 2.0;
|
||||
}
|
||||
|
||||
// Normalize amplitudes.
|
||||
for (unsigned i = 0; i < samples; i++)
|
||||
butterfly_buf[i] *= gain;
|
||||
}
|
||||
|
||||
static void calculate_ifft(complex double *butterfly_buf, size_t samples, bool normalize)
|
||||
{
|
||||
// Enforce POT.
|
||||
assert((samples & (samples - 1)) == 0);
|
||||
|
||||
interleave(butterfly_buf, samples);
|
||||
|
||||
// Fly, lovely butterflies! In opposite direction! :D
|
||||
for (unsigned step_size = 1; step_size < samples; step_size *= 2)
|
||||
butterflies(butterfly_buf, 1.0, step_size, samples);
|
||||
|
||||
if (normalize)
|
||||
calculate_fft_adjust(butterfly_buf, 1.0 / samples, false, samples);
|
||||
}
|
||||
|
||||
static void test_fft(void)
|
||||
{
|
||||
fprintf(stderr, "Sanity checking FFT ...\n");
|
||||
float signal[32];
|
||||
complex double butterfly_buf[16];
|
||||
complex double buf_tmp[16];
|
||||
|
||||
const float cos_freqs[] = {
|
||||
1.0, 4.0, 6.0,
|
||||
};
|
||||
|
||||
const float sin_freqs[] = {
|
||||
-2.0, 5.0, 7.0,
|
||||
};
|
||||
|
||||
for (unsigned i = 0; i < 16; i++)
|
||||
{
|
||||
signal[2 * i] = 0.0;
|
||||
for (unsigned j = 0; j < sizeof(cos_freqs) / sizeof(cos_freqs[0]); j++)
|
||||
signal[2 * i] += cos(2.0 * M_PI * i * cos_freqs[j] / 16.0);
|
||||
for (unsigned j = 0; j < sizeof(sin_freqs) / sizeof(sin_freqs[0]); j++)
|
||||
signal[2 * i] += sin(2.0 * M_PI * i * sin_freqs[j] / 16.0);
|
||||
}
|
||||
|
||||
calculate_fft(signal, butterfly_buf, 16);
|
||||
memcpy(buf_tmp, butterfly_buf, sizeof(buf_tmp));
|
||||
calculate_fft_adjust(buf_tmp, 1.0 / 16, true, 16);
|
||||
|
||||
fprintf(stderr, "FFT: { ");
|
||||
for (unsigned i = 0; i < 7; i++)
|
||||
fprintf(stderr, "(%4.2lf, %4.2lf), ", creal(buf_tmp[i]), cimag(buf_tmp[i]));
|
||||
fprintf(stderr, "(%4.2lf, %4.2lf) }\n", creal(buf_tmp[7]), cimag(buf_tmp[7]));
|
||||
|
||||
calculate_ifft(butterfly_buf, 16, true);
|
||||
|
||||
fprintf(stderr, "Original: { ");
|
||||
for (unsigned i = 0; i < 15; i++)
|
||||
fprintf(stderr, "%5.2f, ", signal[2 * i]);
|
||||
fprintf(stderr, "%5.2f }\n", signal[2 * 15]);
|
||||
|
||||
fprintf(stderr, "FFT => IFFT: { ");
|
||||
for (unsigned i = 0; i < 15; i++)
|
||||
fprintf(stderr, "%5.2lf, ", creal(butterfly_buf[i]));
|
||||
fprintf(stderr, "%5.2lf }\n", creal(butterfly_buf[15]));
|
||||
}
|
||||
|
||||
static void set_alias_power(struct snr_result *res, unsigned freq, double power)
|
||||
{
|
||||
for (unsigned i = 0; i < 3; i++)
|
||||
{
|
||||
if (power >= res->alias_power[i])
|
||||
{
|
||||
memmove(res->alias_freq + i + 1, res->alias_freq + i, (2 - i) * sizeof(res->alias_freq[0]));
|
||||
memmove(res->alias_power + i + 1, res->alias_power + i, (2 - i) * sizeof(res->alias_power[0]));
|
||||
res->alias_power[i] = power;
|
||||
res->alias_freq[i] = freq;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void calculate_snr(struct snr_result *res,
|
||||
unsigned in_rate, unsigned max_rate,
|
||||
const float *resamp, complex double *butterfly_buf, size_t samples)
|
||||
{
|
||||
samples >>= 1;
|
||||
calculate_fft(resamp, butterfly_buf, samples);
|
||||
calculate_fft_adjust(butterfly_buf, 1.0 / samples, true, samples);
|
||||
|
||||
memset(res, 0, sizeof(*res));
|
||||
|
||||
double signal = cabs(butterfly_buf[in_rate] * butterfly_buf[in_rate]);
|
||||
butterfly_buf[in_rate] = 0.0;
|
||||
|
||||
double noise = 0.0;
|
||||
|
||||
// Aliased frequencies above half the original sampling rate are not considered.
|
||||
for (unsigned i = 0; i <= max_rate; i++)
|
||||
{
|
||||
double power = cabs(butterfly_buf[i] * butterfly_buf[i]);
|
||||
set_alias_power(res, i, power);
|
||||
noise += power;
|
||||
}
|
||||
|
||||
res->snr = 10.0 * log10(signal / noise);
|
||||
res->gain = 10.0 * log10(signal);
|
||||
|
||||
for (unsigned i = 0; i < 3; i++)
|
||||
res->alias_power[i] = 10.0 * log10(res->alias_power[i]);
|
||||
}
|
||||
|
||||
int main(int argc, char *argv[])
|
||||
{
|
||||
if (argc != 2)
|
||||
{
|
||||
fprintf(stderr, "Usage: %s <ratio> (out-rate is fixed for FFT).\n", argv[0]);
|
||||
return 1;
|
||||
}
|
||||
|
||||
double ratio = strtod(argv[1], NULL);
|
||||
|
||||
const unsigned fft_samples = 1024 * 128;
|
||||
unsigned out_rate = fft_samples / 2;
|
||||
unsigned in_rate = out_rate / ratio;
|
||||
ratio = (double)out_rate / in_rate;
|
||||
|
||||
if (ratio <= 1.0)
|
||||
{
|
||||
fprintf(stderr, "Ratio too low ...\n");
|
||||
return 1;
|
||||
}
|
||||
|
||||
static const float freq_list[] = {
|
||||
0.001, 0.002, 0.003, 0.004, 0.005, 0.006, 0.007, 0.008, 0.009,
|
||||
0.010, 0.015, 0.020, 0.025, 0.030, 0.035, 0.040, 0.045, 0.050,
|
||||
0.060, 0.070, 0.080, 0.090,
|
||||
0.10, 0.15, 0.20, 0.25, 0.30, 0.35,
|
||||
0.40, 0.41, 0.42, 0.43, 0.44, 0.45,
|
||||
0.46, 0.47, 0.48, 0.49,
|
||||
0.495, 0.496, 0.497, 0.498, 0.499,
|
||||
};
|
||||
|
||||
unsigned samples = in_rate * 4;
|
||||
float *input = calloc(sizeof(float), samples);
|
||||
float *output = calloc(sizeof(float), (fft_samples + 1) * 2);
|
||||
complex double *butterfly_buf = calloc(sizeof(complex double), fft_samples / 2);
|
||||
assert(input);
|
||||
assert(output);
|
||||
|
||||
rarch_resampler_t *re = resampler_new();
|
||||
assert(re);
|
||||
|
||||
test_fft();
|
||||
|
||||
printf("Omega,SNR,Gain\n");
|
||||
for (unsigned i = 0; i < sizeof(freq_list) / sizeof(freq_list[0]); i++)
|
||||
{
|
||||
unsigned freq = freq_list[i] * in_rate;
|
||||
double omega = 2.0 * M_PI * freq / in_rate;
|
||||
gen_signal(input, omega, 0, samples);
|
||||
|
||||
struct resampler_data data = {
|
||||
.data_in = input,
|
||||
.data_out = output,
|
||||
.input_frames = in_rate * 2,
|
||||
.ratio = ratio,
|
||||
};
|
||||
|
||||
resampler_process(re, &data);
|
||||
|
||||
unsigned out_samples = data.output_frames * 2;
|
||||
assert(out_samples >= fft_samples * 2);
|
||||
|
||||
// We generate 2 seconds worth of audio, however, only the last second is considered so phase has stabilized.
|
||||
struct snr_result res;
|
||||
calculate_snr(&res, freq, in_rate / 2, output + fft_samples, butterfly_buf, fft_samples);
|
||||
|
||||
//printf("SNR @ w = %5.3f : %6.2lf dB, Gain: %6.1lf dB\n",
|
||||
// freq_list[i], res.snr, res.gain);
|
||||
printf("%.3f,%.2lf,%.1lf\n", freq_list[i], res.snr, res.gain);
|
||||
|
||||
//printf("\tAliases: #1 (w = %5.3f, %6.2lf dB), #2 (w = %5.3f, %6.2lf dB), #3 (w = %5.3f, %6.2lf dB)\n",
|
||||
// res.alias_freq[0] / (float)in_rate, res.alias_power[0],
|
||||
// res.alias_freq[1] / (float)in_rate, res.alias_power[1],
|
||||
// res.alias_freq[2] / (float)in_rate, res.alias_power[2]);
|
||||
}
|
||||
|
||||
resampler_free(re);
|
||||
free(input);
|
||||
free(output);
|
||||
free(butterfly_buf);
|
||||
}
|
||||
|
||||
+134
@@ -0,0 +1,134 @@
|
||||
/* RetroArch - A frontend for libretro.
|
||||
* Copyright (C) 2010-2012 - Hans-Kristian Arntzen
|
||||
*
|
||||
* RetroArch is free software: you can redistribute it and/or modify it under the terms
|
||||
* of the GNU General Public License as published by the Free Software Found-
|
||||
* ation, either version 3 of the License, or (at your option) any later version.
|
||||
*
|
||||
* RetroArch is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
|
||||
* without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
|
||||
* PURPOSE. See the GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along with RetroArch.
|
||||
* If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include "utils.h"
|
||||
|
||||
#if __SSE2__
|
||||
#include <emmintrin.h>
|
||||
#elif __ALTIVEC__
|
||||
#include <altivec.h>
|
||||
#endif
|
||||
|
||||
void audio_convert_s16_to_float_C(float *out,
|
||||
const int16_t *in, size_t samples)
|
||||
{
|
||||
for (size_t i = 0; i < samples; i++)
|
||||
out[i] = (float)in[i] / 0x8000;
|
||||
}
|
||||
|
||||
void audio_convert_float_to_s16_C(int16_t *out,
|
||||
const float *in, size_t samples)
|
||||
{
|
||||
for (size_t i = 0; i < samples; i++)
|
||||
{
|
||||
int32_t val = (int32_t)(in[i] * 0x8000);
|
||||
out[i] = (val > 0x7FFF) ? 0x7FFF : (val < -0x8000 ? -0x8000 : (int16_t)val);
|
||||
}
|
||||
}
|
||||
|
||||
#if __SSE2__
|
||||
void audio_convert_s16_to_float_SSE2(float *out,
|
||||
const int16_t *in, size_t samples)
|
||||
{
|
||||
__m128 factor = _mm_set1_ps(1.0f / (0x7fff * 0x10000));
|
||||
size_t i;
|
||||
for (i = 0; i + 8 <= samples; i += 8, in += 8, out += 8)
|
||||
{
|
||||
__m128i input = _mm_loadu_si128((const __m128i *)in);
|
||||
__m128i regs[2] = {
|
||||
_mm_unpacklo_epi16(_mm_setzero_si128(), input),
|
||||
_mm_unpackhi_epi16(_mm_setzero_si128(), input),
|
||||
};
|
||||
|
||||
__m128 output[2] = {
|
||||
_mm_mul_ps(_mm_cvtepi32_ps(regs[0]), factor),
|
||||
_mm_mul_ps(_mm_cvtepi32_ps(regs[1]), factor),
|
||||
};
|
||||
|
||||
_mm_storeu_ps(out + 0, output[0]);
|
||||
_mm_storeu_ps(out + 4, output[1]);
|
||||
}
|
||||
|
||||
audio_convert_s16_to_float_C(out, in, samples - i);
|
||||
}
|
||||
|
||||
void audio_convert_float_to_s16_SSE2(int16_t *out,
|
||||
const float *in, size_t samples)
|
||||
{
|
||||
__m128 factor = _mm_set1_ps((float)0x7fff);
|
||||
size_t i;
|
||||
for (i = 0; i + 8 <= samples; i += 8, in += 8, out += 8)
|
||||
{
|
||||
__m128 input[2] = { _mm_loadu_ps(in + 0), _mm_loadu_ps(in + 4) };
|
||||
__m128 res[2] = { _mm_mul_ps(input[0], factor), _mm_mul_ps(input[1], factor) };
|
||||
|
||||
__m128i ints[2] = { _mm_cvtps_epi32(res[0]), _mm_cvtps_epi32(res[1]) };
|
||||
__m128i packed = _mm_packs_epi32(ints[0], ints[1]);
|
||||
|
||||
_mm_storeu_si128((__m128i *)out, packed);
|
||||
}
|
||||
|
||||
audio_convert_float_to_s16_C(out, in, samples - i);
|
||||
}
|
||||
#elif __ALTIVEC__
|
||||
void audio_convert_s16_to_float_altivec(float *out,
|
||||
const int16_t *in, size_t samples)
|
||||
{
|
||||
// Unaligned loads/store is a bit expensive, so we optimize for the good path (very likely).
|
||||
if (((uintptr_t)out & 15) + ((uintptr_t)in & 15) == 0)
|
||||
{
|
||||
size_t i;
|
||||
for (i = 0; i + 8 <= samples; i += 8, in += 8, out += 8)
|
||||
{
|
||||
vector signed short input = vec_ld(0, in);
|
||||
vector signed int hi = vec_unpackh(input);
|
||||
vector signed int lo = vec_unpackl(input);
|
||||
vector float out_hi = vec_ctf(hi, 15);
|
||||
vector float out_lo = vec_ctf(lo, 15);
|
||||
|
||||
vec_st(out_hi, 0, out);
|
||||
vec_st(out_lo, 16, out);
|
||||
}
|
||||
|
||||
audio_convert_s16_to_float_C(out, in, samples - i);
|
||||
}
|
||||
else
|
||||
audio_convert_s16_to_float_C(out, in, samples);
|
||||
}
|
||||
|
||||
void audio_convert_float_to_s16_altivec(int16_t *out,
|
||||
const float *in, size_t samples)
|
||||
{
|
||||
// Unaligned loads/store is a bit expensive, so we optimize for the good path (very likely).
|
||||
if (((uintptr_t)out & 15) + ((uintptr_t)in & 15) == 0)
|
||||
{
|
||||
size_t i;
|
||||
for (i = 0; i + 8 <= samples; i += 8, in += 8, out += 8)
|
||||
{
|
||||
vector float input0 = vec_ld( 0, in);
|
||||
vector float input1 = vec_ld(16, in);
|
||||
vector signed int result0 = vec_cts(input0, 15);
|
||||
vector signed int result1 = vec_cts(input1, 15);
|
||||
vec_st(vec_packs(result0, result1), 0, out);
|
||||
}
|
||||
|
||||
audio_convert_float_to_s16_C(out, in, samples - i);
|
||||
}
|
||||
else
|
||||
audio_convert_float_to_s16_C(out, in, samples);
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
@@ -0,0 +1,53 @@
|
||||
/* RetroArch - A frontend for libretro.
|
||||
* Copyright (C) 2010-2012 - Hans-Kristian Arntzen
|
||||
*
|
||||
* RetroArch is free software: you can redistribute it and/or modify it under the terms
|
||||
* of the GNU General Public License as published by the Free Software Found-
|
||||
* ation, either version 3 of the License, or (at your option) any later version.
|
||||
*
|
||||
* RetroArch is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
|
||||
* without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
|
||||
* PURPOSE. See the GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along with RetroArch.
|
||||
* If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifndef AUDIO_UTILS_H
|
||||
#define AUDIO_UTILS_H
|
||||
|
||||
#include <stdint.h>
|
||||
#include <stddef.h>
|
||||
|
||||
#if __SSE2__
|
||||
#define audio_convert_s16_to_float audio_convert_s16_to_float_SSE2
|
||||
#define audio_convert_float_to_s16 audio_convert_float_to_s16_SSE2
|
||||
|
||||
void audio_convert_s16_to_float_SSE2(float *out,
|
||||
const int16_t *in, size_t samples);
|
||||
|
||||
void audio_convert_float_to_s16_SSE2(int16_t *out,
|
||||
const float *in, size_t samples);
|
||||
|
||||
#elif __ALTIVEC__
|
||||
#define audio_convert_s16_to_float audio_convert_s16_to_float_altivec
|
||||
#define audio_convert_float_to_s16 audio_convert_float_to_s16_altivec
|
||||
|
||||
void audio_convert_s16_to_float_altivec(float *out,
|
||||
const int16_t *in, size_t samples);
|
||||
|
||||
void audio_convert_float_to_s16_altivec(int16_t *out,
|
||||
const float *in, size_t samples);
|
||||
|
||||
#else
|
||||
#define audio_convert_s16_to_float audio_convert_s16_to_float_C
|
||||
#define audio_convert_float_to_s16 audio_convert_float_to_s16_C
|
||||
#endif
|
||||
|
||||
void audio_convert_s16_to_float_C(float *out,
|
||||
const int16_t *in, size_t samples);
|
||||
void audio_convert_float_to_s16_C(int16_t *out,
|
||||
const float *in, size_t samples);
|
||||
|
||||
#endif
|
||||
|
||||
@@ -0,0 +1,187 @@
|
||||
/*
|
||||
Simple C interface for XAudio2
|
||||
Author: Hans-Kristian Arntzen
|
||||
License: Public Domain
|
||||
*/
|
||||
|
||||
#include "xaudio.h"
|
||||
#include "xaudio-c.h"
|
||||
#include <stdint.h>
|
||||
#include <stdio.h>
|
||||
#include "../../msvc/msvc_compat.h"
|
||||
|
||||
#define MAX_BUFFERS 16
|
||||
#define MAX_BUFFERS_MASK (MAX_BUFFERS - 1)
|
||||
|
||||
#undef min
|
||||
#undef max
|
||||
#define min(a, b) ((a) < (b) ? (a) : (b))
|
||||
#define max(a, b) ((a) > (b) ? (a) : (b))
|
||||
|
||||
struct xaudio2
|
||||
{
|
||||
const IXAudio2VoiceCallbackVtbl *lpVtbl;
|
||||
|
||||
uint8_t *buf;
|
||||
IXAudio2 *pXAudio2;
|
||||
IXAudio2MasteringVoice *pMasterVoice;
|
||||
IXAudio2SourceVoice *pSourceVoice;
|
||||
HANDLE hEvent;
|
||||
|
||||
volatile long buffers;
|
||||
unsigned bufsize;
|
||||
unsigned bufptr;
|
||||
unsigned write_buffer;
|
||||
};
|
||||
|
||||
static void WINAPI voice_on_buffer_end(void *handle_, void *data)
|
||||
{
|
||||
(void)data;
|
||||
xaudio2_t *handle = (xaudio2_t*)handle_;
|
||||
InterlockedDecrement(&handle->buffers);
|
||||
SetEvent(handle->hEvent);
|
||||
}
|
||||
|
||||
static void WINAPI dummy_voidp(void *handle, void *data) { (void)handle; (void)data; }
|
||||
static void WINAPI dummy_nil(void *handle) { (void)handle; }
|
||||
static void WINAPI dummy_uint32(void *handle, UINT32 dummy) { (void)handle; (void)dummy; }
|
||||
static void WINAPI dummy_voidp_hresult(void *handle, void *data, HRESULT dummy) { (void)handle; (void)data; (void)dummy; }
|
||||
|
||||
const struct IXAudio2VoiceCallbackVtbl voice_vtable = {
|
||||
dummy_uint32,
|
||||
dummy_nil,
|
||||
dummy_nil,
|
||||
dummy_voidp,
|
||||
voice_on_buffer_end,
|
||||
dummy_voidp,
|
||||
dummy_voidp_hresult,
|
||||
};
|
||||
|
||||
void xaudio2_enumerate_devices(xaudio2_t *xa)
|
||||
{
|
||||
UINT32 dev_count;
|
||||
IXAudio2_GetDeviceCount(xa->pXAudio2, &dev_count);
|
||||
fprintf(stderr, "XAudio2 devices:\n");
|
||||
for (unsigned i = 0; i < dev_count; i++)
|
||||
{
|
||||
XAUDIO2_DEVICE_DETAILS dev_detail;
|
||||
IXAudio2_GetDeviceDetails(xa->pXAudio2, i, &dev_detail);
|
||||
fwprintf(stderr, L"\t%u: %s\n", i, dev_detail.DisplayName);
|
||||
}
|
||||
}
|
||||
|
||||
xaudio2_t *xaudio2_new(unsigned samplerate, unsigned channels,
|
||||
size_t size, unsigned device)
|
||||
{
|
||||
xaudio2_t *handle = (xaudio2_t*)calloc(1, sizeof(*handle));
|
||||
if (!handle)
|
||||
return NULL;
|
||||
|
||||
handle->lpVtbl = &voice_vtable;
|
||||
CoInitializeEx(0, COINIT_MULTITHREADED);
|
||||
WAVEFORMATEX wfx = {0};
|
||||
|
||||
if (FAILED(XAudio2Create(&handle->pXAudio2)))
|
||||
goto error;
|
||||
|
||||
if (FAILED(IXAudio2_CreateMasteringVoice(handle->pXAudio2,
|
||||
&handle->pMasterVoice, channels, samplerate, 0, device, NULL)))
|
||||
goto error;
|
||||
|
||||
wfx.wFormatTag = WAVE_FORMAT_IEEE_FLOAT;
|
||||
wfx.nChannels = channels;
|
||||
wfx.nSamplesPerSec = samplerate;
|
||||
wfx.nBlockAlign = channels * sizeof(float);
|
||||
wfx.wBitsPerSample = sizeof(float) * 8;
|
||||
wfx.nAvgBytesPerSec = wfx.nSamplesPerSec * wfx.nBlockAlign;
|
||||
wfx.cbSize = 0;
|
||||
|
||||
if (FAILED(IXAudio2_CreateSourceVoice(handle->pXAudio2,
|
||||
&handle->pSourceVoice, &wfx,
|
||||
XAUDIO2_VOICE_NOSRC, XAUDIO2_DEFAULT_FREQ_RATIO,
|
||||
(IXAudio2VoiceCallback*)handle, 0, 0)))
|
||||
goto error;
|
||||
|
||||
handle->hEvent = CreateEvent(0, FALSE, FALSE, 0);
|
||||
if (!handle->hEvent)
|
||||
goto error;
|
||||
|
||||
handle->bufsize = size / MAX_BUFFERS;
|
||||
handle->buf = (uint8_t*)calloc(1, handle->bufsize * MAX_BUFFERS);
|
||||
if (!handle->buf)
|
||||
goto error;
|
||||
|
||||
if (FAILED(IXAudio2SourceVoice_Start(handle->pSourceVoice, 0, XAUDIO2_COMMIT_NOW)))
|
||||
goto error;
|
||||
|
||||
return handle;
|
||||
|
||||
error:
|
||||
xaudio2_free(handle);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
size_t xaudio2_write_avail(xaudio2_t *handle)
|
||||
{
|
||||
return handle->bufsize * (MAX_BUFFERS - handle->buffers - 1);
|
||||
}
|
||||
|
||||
size_t xaudio2_write(xaudio2_t *handle, const void *buf, size_t bytes_)
|
||||
{
|
||||
unsigned bytes = bytes_;
|
||||
const uint8_t *buffer = (const uint8_t*)buf;
|
||||
while (bytes)
|
||||
{
|
||||
unsigned need = min(bytes, handle->bufsize - handle->bufptr);
|
||||
memcpy(handle->buf + handle->write_buffer * handle->bufsize + handle->bufptr,
|
||||
buffer, need);
|
||||
|
||||
handle->bufptr += need;
|
||||
buffer += need;
|
||||
bytes -= need;
|
||||
|
||||
if (handle->bufptr == handle->bufsize)
|
||||
{
|
||||
while (handle->buffers == MAX_BUFFERS - 1)
|
||||
WaitForSingleObject(handle->hEvent, INFINITE);
|
||||
|
||||
XAUDIO2_BUFFER xa2buffer = {0};
|
||||
xa2buffer.AudioBytes = handle->bufsize;
|
||||
xa2buffer.pAudioData = handle->buf + handle->write_buffer * handle->bufsize;
|
||||
|
||||
if (FAILED(IXAudio2SourceVoice_SubmitSourceBuffer(handle->pSourceVoice, &xa2buffer, NULL)))
|
||||
return 0;
|
||||
|
||||
InterlockedIncrement(&handle->buffers);
|
||||
handle->bufptr = 0;
|
||||
handle->write_buffer = (handle->write_buffer + 1) & MAX_BUFFERS_MASK;
|
||||
}
|
||||
}
|
||||
|
||||
return bytes_;
|
||||
}
|
||||
|
||||
void xaudio2_free(xaudio2_t *handle)
|
||||
{
|
||||
if (handle)
|
||||
{
|
||||
if (handle->pSourceVoice)
|
||||
{
|
||||
IXAudio2SourceVoice_Stop(handle->pSourceVoice, 0, XAUDIO2_COMMIT_NOW);
|
||||
IXAudio2SourceVoice_DestroyVoice(handle->pSourceVoice);
|
||||
}
|
||||
|
||||
if (handle->pMasterVoice)
|
||||
IXAudio2MasteringVoice_DestroyVoice(handle->pMasterVoice);
|
||||
|
||||
if (handle->pXAudio2)
|
||||
IXAudio2_Release(handle->pXAudio2);
|
||||
|
||||
if (handle->hEvent)
|
||||
CloseHandle(handle->hEvent);
|
||||
|
||||
free(handle->buf);
|
||||
free(handle);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,28 @@
|
||||
/*
|
||||
Simple C interface for XAudio2
|
||||
Author: Hans-Kristian Arntzen
|
||||
License: Public Domain
|
||||
*/
|
||||
|
||||
#ifndef XAUDIO_C_H
|
||||
#define XAUDIO_C_H
|
||||
|
||||
#include <stddef.h>
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
typedef struct xaudio2 xaudio2_t;
|
||||
|
||||
xaudio2_t* xaudio2_new(unsigned samplerate, unsigned channels, size_t bufsize, unsigned device);
|
||||
size_t xaudio2_write_avail(xaudio2_t *handle);
|
||||
size_t xaudio2_write(xaudio2_t *handle, const void *data, size_t bytes);
|
||||
void xaudio2_free(xaudio2_t *handle);
|
||||
void xaudio2_enumerate_devices(xaudio2_t *handle);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,240 @@
|
||||
/*
|
||||
xaudio.h (2010-08-14) / (2012-12-04)
|
||||
authors: OV2, Themaister
|
||||
*/
|
||||
|
||||
// Kinda stripped down. Only contains the bare essentials used in SSNES.
|
||||
|
||||
#ifndef XAUDIO2_MINGW_H
|
||||
#define XAUDIO2_MINGW_H
|
||||
|
||||
#ifdef __cplusplus
|
||||
#define CINTERFACE
|
||||
#endif
|
||||
|
||||
#define WIN32_LEAN_AND_MEAN
|
||||
#include <windows.h>
|
||||
#include <basetyps.h>
|
||||
#include <objbase.h>
|
||||
#include <mmreg.h>
|
||||
|
||||
#define DEFINE_GUID_X(n, l, w1, w2, b1, b2, b3, b4, b5, b6, b7, b8) \
|
||||
static const GUID n = { l, w1, w2, { b1, b2, b3, b4, b5, b6, b7, b8 } }
|
||||
#define DEFINE_CLSID_X(className, l, w1, w2, b1, b2, b3, b4, b5, b6, b7, b8) \
|
||||
DEFINE_GUID_X(CLSID_##className, 0x##l, 0x##w1, 0x##w2, 0x##b1, 0x##b2, 0x##b3, 0x##b4, 0x##b5, 0x##b6, 0x##b7, 0x##b8)
|
||||
#define DEFINE_IID_X(interfaceName, l, w1, w2, b1, b2, b3, b4, b5, b6, b7, b8) \
|
||||
DEFINE_GUID_X(IID_##interfaceName, 0x##l, 0x##w1, 0x##w2, 0x##b1, 0x##b2, 0x##b3, 0x##b4, 0x##b5, 0x##b6, 0x##b7, 0x##b8)
|
||||
#define X2DEFAULT(x)
|
||||
|
||||
DEFINE_CLSID_X(XAudio2, e21a7345, eb21, 468e, be, 50, 80, 4d, b9, 7c, f7, 08);
|
||||
DEFINE_IID_X(IXAudio2, 8bcf1f58, 9fe7, 4583, 8a, c6, e2, ad, c4, 65, c8, bb);
|
||||
|
||||
#ifndef INTERFACE
|
||||
#define INTERFACE void
|
||||
#endif
|
||||
|
||||
#define XAUDIO2_COMMIT_NOW 0
|
||||
#define XAUDIO2_DEFAULT_CHANNELS 0
|
||||
#define XAUDIO2_DEFAULT_SAMPLERATE 0
|
||||
#define XAUDIO2_DEFAULT_FREQ_RATIO 4.0f
|
||||
#define XAUDIO2_DEBUG_ENGINE 0x0001
|
||||
#define XAUDIO2_VOICE_NOSRC 0x0004
|
||||
|
||||
typedef enum XAUDIO2_DEVICE_ROLE
|
||||
{
|
||||
NotDefaultDevice = 0x0,
|
||||
DefaultConsoleDevice = 0x1,
|
||||
DefaultMultimediaDevice = 0x2,
|
||||
DefaultCommunicationsDevice = 0x4,
|
||||
DefaultGameDevice = 0x8,
|
||||
GlobalDefaultDevice = 0xf,
|
||||
InvalidDeviceRole = ~GlobalDefaultDevice
|
||||
} XAUDIO2_DEVICE_ROLE;
|
||||
|
||||
typedef enum XAUDIO2_WINDOWS_PROCESSOR_SPECIFIER
|
||||
{
|
||||
XAUDIO2_ANY_PROCESSOR = 0xffffffff,
|
||||
XAUDIO2_DEFAULT_PROCESSOR = XAUDIO2_ANY_PROCESSOR
|
||||
} XAUDIO2_WINDOWS_PROCESSOR_SPECIFIER, XAUDIO2_PROCESSOR;
|
||||
|
||||
typedef enum XAUDIO2_FILTER_TYPE {
|
||||
LowPassFilter,
|
||||
BandPassFilter,
|
||||
HighPassFilter
|
||||
} XAUDIO2_FILTER_TYPE;
|
||||
|
||||
typedef struct XAUDIO2_DEVICE_DETAILS
|
||||
{
|
||||
WCHAR DeviceID[256];
|
||||
WCHAR DisplayName[256];
|
||||
XAUDIO2_DEVICE_ROLE Role;
|
||||
WAVEFORMATEXTENSIBLE OutputFormat;
|
||||
} XAUDIO2_DEVICE_DETAILS;
|
||||
|
||||
typedef struct XAUDIO2_VOICE_DETAILS XAUDIO2_VOICE_DETAILS;
|
||||
typedef struct XAUDIO2_VOICE_SENDS XAUDIO2_VOICE_SENDS;
|
||||
typedef struct XAUDIO2_EFFECT_DESCRIPTOR XAUDIO2_EFFECT_DESCRIPTOR;
|
||||
typedef struct XAUDIO2_EFFECT_CHAIN XAUDIO2_EFFECT_CHAIN;
|
||||
typedef struct XAUDIO2_FILTER_PARAMETERS XAUDIO2_FILTER_PARAMETERS;
|
||||
typedef struct XAUDIO2_BUFFER_WMA XAUDIO2_BUFFER_WMA;
|
||||
typedef struct XAUDIO2_VOICE_STATE XAUDIO2_VOICE_STATE;
|
||||
typedef struct XAUDIO2_PERFORMANCE_DATA XAUDIO2_PERFORMANCE_DATA;
|
||||
typedef struct XAUDIO2_DEBUG_CONFIGURATION XAUDIO2_DEBUG_CONFIGURATION;
|
||||
typedef struct IXAudio2EngineCallback IXAudio2EngineCallback;
|
||||
typedef struct IXAudio2SubmixVoice IXAudio2SubmixVoice;
|
||||
|
||||
typedef struct XAUDIO2_BUFFER
|
||||
{
|
||||
UINT32 Flags;
|
||||
UINT32 AudioBytes;
|
||||
const BYTE* pAudioData;
|
||||
UINT32 PlayBegin;
|
||||
UINT32 PlayLength;
|
||||
UINT32 LoopBegin;
|
||||
UINT32 LoopLength;
|
||||
UINT32 LoopCount;
|
||||
void *pContext;
|
||||
} XAUDIO2_BUFFER;
|
||||
|
||||
DECLARE_INTERFACE(IXAudio2VoiceCallback)
|
||||
{
|
||||
STDMETHOD_(void, OnVoiceProcessingPassStart) (THIS_ UINT32 BytesRequired) PURE;
|
||||
STDMETHOD_(void, OnVoiceProcessingPassEnd) (THIS) PURE;
|
||||
STDMETHOD_(void, OnStreamEnd) (THIS) PURE;
|
||||
STDMETHOD_(void, OnBufferStart) (THIS_ void *pBufferContext) PURE;
|
||||
STDMETHOD_(void, OnBufferEnd) (THIS_ void *pBufferContext) PURE;
|
||||
STDMETHOD_(void, OnLoopEnd) (THIS_ void *pBufferContext) PURE;
|
||||
STDMETHOD_(void, OnVoiceError) (THIS_ void *pBufferContext, HRESULT Error) PURE;
|
||||
};
|
||||
|
||||
DECLARE_INTERFACE(IXAudio2Voice)
|
||||
{
|
||||
#define Declare_IXAudio2Voice_Methods() \
|
||||
STDMETHOD_(void, GetVoiceDetails) (THIS_ XAUDIO2_VOICE_DETAILS* pVoiceDetails) PURE; \
|
||||
STDMETHOD(SetOutputVoices) (THIS_ const XAUDIO2_VOICE_SENDS* pSendList) PURE; \
|
||||
STDMETHOD(SetEffectChain) (THIS_ const XAUDIO2_EFFECT_CHAIN* pEffectChain) PURE; \
|
||||
STDMETHOD(EnableEffect) (THIS_ UINT32 EffectIndex, \
|
||||
UINT32 OperationSet X2DEFAULT(XAUDIO2_COMMIT_NOW)) PURE; \
|
||||
STDMETHOD(DisableEffect) (THIS_ UINT32 EffectIndex, \
|
||||
UINT32 OperationSet X2DEFAULT(XAUDIO2_COMMIT_NOW)) PURE; \
|
||||
STDMETHOD_(void, GetEffectState) (THIS_ UINT32 EffectIndex, BOOL* pEnabled) PURE; \
|
||||
STDMETHOD(SetEffectParameters) (THIS_ UINT32 EffectIndex, \
|
||||
const void *pParameters, \
|
||||
UINT32 ParametersByteSize, \
|
||||
UINT32 OperationSet X2DEFAULT(XAUDIO2_COMMIT_NOW)) PURE; \
|
||||
STDMETHOD(GetEffectParameters) (THIS_ UINT32 EffectIndex, void *pParameters, \
|
||||
UINT32 ParametersByteSize) PURE; \
|
||||
STDMETHOD(SetFilterParameters) (THIS_ const XAUDIO2_FILTER_PARAMETERS* pParameters, \
|
||||
UINT32 OperationSet X2DEFAULT(XAUDIO2_COMMIT_NOW)) PURE; \
|
||||
STDMETHOD_(void, GetFilterParameters) (THIS_ XAUDIO2_FILTER_PARAMETERS* pParameters) PURE; \
|
||||
STDMETHOD(SetVolume) (THIS_ float Volume, \
|
||||
UINT32 OperationSet X2DEFAULT(XAUDIO2_COMMIT_NOW)) PURE; \
|
||||
STDMETHOD_(void, GetVolume) (THIS_ float* pVolume) PURE; \
|
||||
STDMETHOD(SetChannelVolumes) (THIS_ UINT32 Channels, const float* pVolumes, \
|
||||
UINT32 OperationSet X2DEFAULT(XAUDIO2_COMMIT_NOW)) PURE; \
|
||||
STDMETHOD_(void, GetChannelVolumes) (THIS_ UINT32 Channels, float* pVolumes) PURE; \
|
||||
STDMETHOD(SetOutputMatrix) (THIS_ IXAudio2Voice* pDestinationVoice, \
|
||||
UINT32 SourceChannels, UINT32 DestinationChannels, \
|
||||
const float* pLevelMatrix, \
|
||||
UINT32 OperationSet X2DEFAULT(XAUDIO2_COMMIT_NOW)) PURE; \
|
||||
STDMETHOD_(void, GetOutputMatrix) (THIS_ IXAudio2Voice* pDestinationVoice, \
|
||||
UINT32 SourceChannels, UINT32 DestinationChannels, \
|
||||
float* pLevelMatrix) PURE; \
|
||||
STDMETHOD_(void, DestroyVoice) (THIS) PURE
|
||||
|
||||
Declare_IXAudio2Voice_Methods();
|
||||
};
|
||||
|
||||
DECLARE_INTERFACE_(IXAudio2MasteringVoice, IXAudio2Voice)
|
||||
{
|
||||
Declare_IXAudio2Voice_Methods();
|
||||
};
|
||||
|
||||
DECLARE_INTERFACE_(IXAudio2SourceVoice, IXAudio2Voice)
|
||||
{
|
||||
Declare_IXAudio2Voice_Methods();
|
||||
STDMETHOD(Start) (THIS_ UINT32 Flags, UINT32 OperationSet X2DEFAULT(XAUDIO2_COMMIT_NOW)) PURE;
|
||||
STDMETHOD(Stop) (THIS_ UINT32 Flags, UINT32 OperationSet X2DEFAULT(XAUDIO2_COMMIT_NOW)) PURE;
|
||||
STDMETHOD(SubmitSourceBuffer) (THIS_ const XAUDIO2_BUFFER* pBuffer, const XAUDIO2_BUFFER_WMA* pBufferWMA X2DEFAULT(NULL)) PURE;
|
||||
STDMETHOD(FlushSourceBuffers) (THIS) PURE;
|
||||
STDMETHOD(Discontinuity) (THIS) PURE;
|
||||
STDMETHOD(ExitLoop) (THIS_ UINT32 OperationSet X2DEFAULT(XAUDIO2_COMMIT_NOW)) PURE;
|
||||
STDMETHOD_(void, GetState) (THIS_ XAUDIO2_VOICE_STATE* pVoiceState) PURE;
|
||||
STDMETHOD(SetFrequencyRatio) (THIS_ float Ratio,
|
||||
UINT32 OperationSet X2DEFAULT(XAUDIO2_COMMIT_NOW)) PURE;
|
||||
STDMETHOD_(void, GetFrequencyRatio) (THIS_ float* pRatio) PURE;
|
||||
};
|
||||
|
||||
DECLARE_INTERFACE_(IXAudio2, IUnknown)
|
||||
{
|
||||
STDMETHOD(QueryInterface) (THIS_ REFIID riid, void** ppvInterface) PURE;
|
||||
STDMETHOD_(ULONG, AddRef) (THIS) PURE;
|
||||
STDMETHOD_(ULONG, Release) (THIS) PURE;
|
||||
STDMETHOD(GetDeviceCount) (THIS_ UINT32* pCount) PURE;
|
||||
STDMETHOD(GetDeviceDetails) (THIS_ UINT32 Index, XAUDIO2_DEVICE_DETAILS* pDeviceDetails) PURE;
|
||||
STDMETHOD(Initialize) (THIS_ UINT32 Flags X2DEFAULT(0),
|
||||
XAUDIO2_PROCESSOR XAudio2Processor X2DEFAULT(XAUDIO2_DEFAULT_PROCESSOR)) PURE;
|
||||
STDMETHOD(RegisterForCallbacks) (IXAudio2EngineCallback* pCallback) PURE;
|
||||
STDMETHOD_(void, UnregisterForCallbacks) (IXAudio2EngineCallback* pCallback) PURE;
|
||||
STDMETHOD(CreateSourceVoice) (THIS_ IXAudio2SourceVoice** ppSourceVoice,
|
||||
const WAVEFORMATEX* pSourceFormat,
|
||||
UINT32 Flags X2DEFAULT(0),
|
||||
float MaxFrequencyRatio X2DEFAULT(XAUDIO2_DEFAULT_FREQ_RATIO),
|
||||
IXAudio2VoiceCallback* pCallback X2DEFAULT(NULL),
|
||||
const XAUDIO2_VOICE_SENDS* pSendList X2DEFAULT(NULL),
|
||||
const XAUDIO2_EFFECT_CHAIN* pEffectChain X2DEFAULT(NULL)) PURE;
|
||||
STDMETHOD(CreateSubmixVoice) (THIS_ IXAudio2SubmixVoice** ppSubmixVoice,
|
||||
UINT32 InputChannels, UINT32 InputSampleRate,
|
||||
UINT32 Flags X2DEFAULT(0), UINT32 ProcessingStage X2DEFAULT(0),
|
||||
const XAUDIO2_VOICE_SENDS* pSendList X2DEFAULT(NULL),
|
||||
const XAUDIO2_EFFECT_CHAIN* pEffectChain X2DEFAULT(NULL)) PURE;
|
||||
STDMETHOD(CreateMasteringVoice) (THIS_ IXAudio2MasteringVoice** ppMasteringVoice,
|
||||
UINT32 InputChannels X2DEFAULT(XAUDIO2_DEFAULT_CHANNELS),
|
||||
UINT32 InputSampleRate X2DEFAULT(XAUDIO2_DEFAULT_SAMPLERATE),
|
||||
UINT32 Flags X2DEFAULT(0), UINT32 DeviceIndex X2DEFAULT(0),
|
||||
const XAUDIO2_EFFECT_CHAIN* pEffectChain X2DEFAULT(NULL)) PURE;
|
||||
STDMETHOD(StartEngine) (THIS) PURE;
|
||||
STDMETHOD_(void, StopEngine) (THIS) PURE;
|
||||
STDMETHOD(CommitChanges) (THIS_ UINT32 OperationSet) PURE;
|
||||
STDMETHOD_(void, GetPerformanceData) (THIS_ XAUDIO2_PERFORMANCE_DATA* pPerfData) PURE;
|
||||
STDMETHOD_(void, SetDebugConfiguration) (THIS_ const XAUDIO2_DEBUG_CONFIGURATION* pDebugConfiguration,
|
||||
void *pReserved X2DEFAULT(NULL)) PURE;
|
||||
};
|
||||
|
||||
// C hooks.
|
||||
#define IXAudio2_Initialize(THIS, ...) (THIS)->lpVtbl->Initialize(THIS, __VA_ARGS__)
|
||||
#define IXAudio2_Release(THIS) (THIS)->lpVtbl->Release(THIS)
|
||||
#define IXAudio2_CreateSourceVoice(THIS, ...) (THIS)->lpVtbl->CreateSourceVoice(THIS, __VA_ARGS__)
|
||||
#define IXAudio2_CreateMasteringVoice(THIS, ...) (THIS)->lpVtbl->CreateMasteringVoice(THIS, __VA_ARGS__)
|
||||
#define IXAudio2_GetDeviceCount(THIS, ...) (THIS)->lpVtbl->GetDeviceCount(THIS, __VA_ARGS__)
|
||||
#define IXAudio2_GetDeviceDetails(THIS, ...) (THIS)->lpVtbl->GetDeviceDetails(THIS, __VA_ARGS__)
|
||||
|
||||
#define IXAudio2SourceVoice_Start(THIS, ...) (THIS)->lpVtbl->Start(THIS, __VA_ARGS__)
|
||||
#define IXAudio2SourceVoice_Stop(THIS, ...) (THIS)->lpVtbl->Stop(THIS, __VA_ARGS__)
|
||||
#define IXAudio2SourceVoice_SubmitSourceBuffer(THIS, ...) (THIS)->lpVtbl->SubmitSourceBuffer(THIS, __VA_ARGS__)
|
||||
#define IXAudio2SourceVoice_DestroyVoice(THIS) (THIS)->lpVtbl->DestroyVoice(THIS)
|
||||
#define IXAudio2MasteringVoice_DestroyVoice(THIS) (THIS)->lpVtbl->DestroyVoice(THIS)
|
||||
|
||||
static inline HRESULT XAudio2Create(IXAudio2 **ppXAudio2)
|
||||
{
|
||||
IXAudio2 *pXAudio2;
|
||||
|
||||
#ifdef __cplusplus
|
||||
HRESULT hr = CoCreateInstance(CLSID_XAudio2, NULL, CLSCTX_INPROC_SERVER, IID_IXAudio2, (void**)&pXAudio2);
|
||||
#else
|
||||
HRESULT hr = CoCreateInstance(&CLSID_XAudio2, NULL, CLSCTX_INPROC_SERVER, &IID_IXAudio2, (void**)&pXAudio2);
|
||||
#endif
|
||||
|
||||
if (SUCCEEDED(hr))
|
||||
{
|
||||
hr = IXAudio2_Initialize(pXAudio2, 0, XAUDIO2_DEFAULT_PROCESSOR);
|
||||
if (SUCCEEDED(hr))
|
||||
*ppXAudio2 = pXAudio2;
|
||||
else
|
||||
IXAudio2_Release(pXAudio2);
|
||||
}
|
||||
return hr;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
+137
@@ -0,0 +1,137 @@
|
||||
/* RetroArch - A frontend for libretro.
|
||||
* Copyright (C) 2010-2012 - Hans-Kristian Arntzen
|
||||
*
|
||||
* RetroArch is free software: you can redistribute it and/or modify it under the terms
|
||||
* of the GNU General Public License as published by the Free Software Found-
|
||||
* ation, either version 3 of the License, or (at your option) any later version.
|
||||
*
|
||||
* RetroArch is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
|
||||
* without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
|
||||
* PURPOSE. See the GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along with RetroArch.
|
||||
* If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include "../driver.h"
|
||||
#include <stdlib.h>
|
||||
#include "xaudio-c/xaudio-c.h"
|
||||
#include "../general.h"
|
||||
|
||||
typedef struct
|
||||
{
|
||||
xaudio2_t *xa;
|
||||
bool nonblock;
|
||||
size_t bufsize;
|
||||
} xa_t;
|
||||
|
||||
static void *xa_init(const char *device, unsigned rate, unsigned latency)
|
||||
{
|
||||
if (latency < 8)
|
||||
latency = 8; // Do not allow shenanigans.
|
||||
|
||||
xa_t *xa = (xa_t*)calloc(1, sizeof(*xa));
|
||||
if (!xa)
|
||||
return NULL;
|
||||
|
||||
size_t bufsize = latency * rate / 1000;
|
||||
|
||||
RARCH_LOG("XAudio2: Requesting %d ms latency, using %d ms latency.\n", latency, (int)bufsize * 1000 / rate);
|
||||
|
||||
xa->bufsize = bufsize * 2 * sizeof(float);
|
||||
|
||||
unsigned device_index = 0;
|
||||
if (device)
|
||||
device_index = strtoul(device, NULL, 0);
|
||||
|
||||
xa->xa = xaudio2_new(rate, 2, xa->bufsize, device_index);
|
||||
if (!xa->xa)
|
||||
{
|
||||
RARCH_ERR("Failed to init XAudio2.\n");
|
||||
free(xa);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (g_extern.verbose)
|
||||
xaudio2_enumerate_devices(xa->xa);
|
||||
|
||||
return xa;
|
||||
}
|
||||
|
||||
static ssize_t xa_write(void *data, const void *buf, size_t size)
|
||||
{
|
||||
xa_t *xa = (xa_t*)data;
|
||||
if (xa->nonblock)
|
||||
{
|
||||
size_t avail = xaudio2_write_avail(xa->xa);
|
||||
if (avail == 0)
|
||||
return 0;
|
||||
if (avail < size)
|
||||
size = avail;
|
||||
}
|
||||
|
||||
size_t ret = xaudio2_write(xa->xa, buf, size);
|
||||
if (ret == 0 && size > 0)
|
||||
return -1;
|
||||
return ret;
|
||||
}
|
||||
|
||||
static bool xa_stop(void *data)
|
||||
{
|
||||
(void)data;
|
||||
return true;
|
||||
}
|
||||
|
||||
static void xa_set_nonblock_state(void *data, bool state)
|
||||
{
|
||||
xa_t *xa = (xa_t*)data;
|
||||
xa->nonblock = state;
|
||||
}
|
||||
|
||||
static bool xa_start(void *data)
|
||||
{
|
||||
(void)data;
|
||||
return true;
|
||||
}
|
||||
|
||||
static bool xa_use_float(void *data)
|
||||
{
|
||||
(void)data;
|
||||
return true;
|
||||
}
|
||||
|
||||
static void xa_free(void *data)
|
||||
{
|
||||
xa_t *xa = (xa_t*)data;
|
||||
if (xa)
|
||||
{
|
||||
if (xa->xa)
|
||||
xaudio2_free(xa->xa);
|
||||
free(xa);
|
||||
}
|
||||
}
|
||||
|
||||
static size_t xa_write_avail(void *data)
|
||||
{
|
||||
xa_t *xa = (xa_t*)data;
|
||||
return xaudio2_write_avail(xa->xa);
|
||||
}
|
||||
|
||||
static size_t xa_buffer_size(void *data)
|
||||
{
|
||||
xa_t *xa = (xa_t*)data;
|
||||
return xa->bufsize;
|
||||
}
|
||||
|
||||
const audio_driver_t audio_xa = {
|
||||
xa_init,
|
||||
xa_write,
|
||||
xa_stop,
|
||||
xa_start,
|
||||
xa_set_nonblock_state,
|
||||
xa_free,
|
||||
xa_use_float,
|
||||
"xaudio",
|
||||
xa_write_avail,
|
||||
xa_buffer_size,
|
||||
};
|
||||
+157
@@ -0,0 +1,157 @@
|
||||
/* RetroArch - A frontend for libretro.
|
||||
* Copyright (C) 2010-2012 - Hans-Kristian Arntzen
|
||||
*
|
||||
* RetroArch is free software: you can redistribute it and/or modify it under the terms
|
||||
* of the GNU General Public License as published by the Free Software Found-
|
||||
* ation, either version 3 of the License, or (at your option) any later version.
|
||||
*
|
||||
* RetroArch is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
|
||||
* without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
|
||||
* PURPOSE. See the GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along with RetroArch.
|
||||
* If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include "autosave.h"
|
||||
#include "thread.h"
|
||||
#include <stdlib.h>
|
||||
#include "boolean.h"
|
||||
#include <string.h>
|
||||
#include <stdio.h>
|
||||
#include "general.h"
|
||||
|
||||
struct autosave
|
||||
{
|
||||
volatile bool quit;
|
||||
slock_t *lock;
|
||||
|
||||
slock_t *cond_lock;
|
||||
scond_t *cond;
|
||||
sthread_t *thread;
|
||||
|
||||
void *buffer;
|
||||
const void *snes_buffer;
|
||||
const char *path;
|
||||
size_t bufsize;
|
||||
unsigned interval;
|
||||
};
|
||||
|
||||
static void autosave_thread(void *data)
|
||||
{
|
||||
autosave_t *save = (autosave_t*)data;
|
||||
|
||||
bool first_log = true;
|
||||
|
||||
while (!save->quit)
|
||||
{
|
||||
autosave_lock(save);
|
||||
bool differ = memcmp(save->buffer, save->snes_buffer, save->bufsize) != 0;
|
||||
if (differ)
|
||||
memcpy(save->buffer, save->snes_buffer, save->bufsize);
|
||||
autosave_unlock(save);
|
||||
|
||||
if (differ)
|
||||
{
|
||||
// Should probably deal with this more elegantly.
|
||||
FILE *file = fopen(save->path, "wb");
|
||||
if (file)
|
||||
{
|
||||
// Avoid spamming down stderr ... :)
|
||||
if (first_log)
|
||||
{
|
||||
RARCH_LOG("Autosaving SRAM to \"%s\", will continue to check every %u seconds ...\n", save->path, save->interval);
|
||||
first_log = false;
|
||||
}
|
||||
else
|
||||
RARCH_LOG("SRAM changed ... autosaving ...\n");
|
||||
|
||||
bool failed = false;
|
||||
failed |= fwrite(save->buffer, 1, save->bufsize, file) != save->bufsize;
|
||||
failed |= fflush(file) != 0;
|
||||
failed |= fclose(file) != 0;
|
||||
if (failed)
|
||||
RARCH_WARN("Failed to autosave SRAM. Disk might be full.\n");
|
||||
}
|
||||
}
|
||||
|
||||
slock_lock(save->cond_lock);
|
||||
if (!save->quit)
|
||||
scond_wait_timeout(save->cond, save->cond_lock, save->interval * 1000);
|
||||
slock_unlock(save->cond_lock);
|
||||
}
|
||||
}
|
||||
|
||||
autosave_t *autosave_new(const char *path, const void *data, size_t size, unsigned interval)
|
||||
{
|
||||
autosave_t *handle = (autosave_t*)calloc(1, sizeof(*handle));
|
||||
if (!handle)
|
||||
return NULL;
|
||||
|
||||
handle->bufsize = size;
|
||||
handle->interval = interval;
|
||||
handle->path = path;
|
||||
handle->buffer = malloc(size);
|
||||
handle->snes_buffer = data;
|
||||
|
||||
if (!handle->buffer)
|
||||
{
|
||||
free(handle);
|
||||
return NULL;
|
||||
}
|
||||
memcpy(handle->buffer, handle->snes_buffer, handle->bufsize);
|
||||
|
||||
handle->lock = slock_new();
|
||||
handle->cond_lock = slock_new();
|
||||
handle->cond = scond_new();
|
||||
|
||||
handle->thread = sthread_create(autosave_thread, handle);
|
||||
|
||||
return handle;
|
||||
}
|
||||
|
||||
void autosave_lock(autosave_t *handle)
|
||||
{
|
||||
slock_lock(handle->lock);
|
||||
}
|
||||
|
||||
void autosave_unlock(autosave_t *handle)
|
||||
{
|
||||
slock_unlock(handle->lock);
|
||||
}
|
||||
|
||||
void autosave_free(autosave_t *handle)
|
||||
{
|
||||
slock_lock(handle->cond_lock);
|
||||
handle->quit = true;
|
||||
slock_unlock(handle->cond_lock);
|
||||
scond_signal(handle->cond);
|
||||
sthread_join(handle->thread);
|
||||
|
||||
slock_free(handle->lock);
|
||||
slock_free(handle->cond_lock);
|
||||
scond_free(handle->cond);
|
||||
|
||||
free(handle->buffer);
|
||||
free(handle);
|
||||
}
|
||||
|
||||
void lock_autosave(void)
|
||||
{
|
||||
for (unsigned i = 0; i < sizeof(g_extern.autosave)/sizeof(g_extern.autosave[0]); i++)
|
||||
{
|
||||
if (g_extern.autosave[i])
|
||||
autosave_lock(g_extern.autosave[i]);
|
||||
}
|
||||
}
|
||||
|
||||
void unlock_autosave(void)
|
||||
{
|
||||
for (unsigned i = 0; i < sizeof(g_extern.autosave)/sizeof(g_extern.autosave[0]); i++)
|
||||
{
|
||||
if (g_extern.autosave[i])
|
||||
autosave_unlock(g_extern.autosave[i]);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
+31
@@ -0,0 +1,31 @@
|
||||
/* RetroArch - A frontend for libretro.
|
||||
* Copyright (C) 2010-2012 - Hans-Kristian Arntzen
|
||||
*
|
||||
* RetroArch is free software: you can redistribute it and/or modify it under the terms
|
||||
* of the GNU General Public License as published by the Free Software Found-
|
||||
* ation, either version 3 of the License, or (at your option) any later version.
|
||||
*
|
||||
* RetroArch is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
|
||||
* without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
|
||||
* PURPOSE. See the GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along with RetroArch.
|
||||
* If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifndef __RARCH_AUTOSAVE_H
|
||||
#define __RARCH_AUTOSAVE_H
|
||||
|
||||
#include <stddef.h>
|
||||
|
||||
typedef struct autosave autosave_t;
|
||||
|
||||
autosave_t *autosave_new(const char *path, const void *data, size_t size, unsigned interval);
|
||||
void autosave_lock(autosave_t *handle);
|
||||
void autosave_unlock(autosave_t *handle);
|
||||
void autosave_free(autosave_t *handle);
|
||||
|
||||
void lock_autosave(void);
|
||||
void unlock_autosave(void);
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,24 @@
|
||||
/* RetroArch - A frontend for libretro.
|
||||
* Copyright (C) 2010-2012 - Hans-Kristian Arntzen
|
||||
*
|
||||
* RetroArch is free software: you can redistribute it and/or modify it under the terms
|
||||
* of the GNU General Public License as published by the Free Software Found-
|
||||
* ation, either version 3 of the License, or (at your option) any later version.
|
||||
*
|
||||
* RetroArch is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
|
||||
* without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
|
||||
* PURPOSE. See the GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along with RetroArch.
|
||||
* If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifndef __RARCH_BOOLEAN_H
|
||||
#define __RARCH_BOOLEAN_H
|
||||
|
||||
#ifndef __cplusplus
|
||||
#include <stdbool.h>
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
||||
@@ -0,0 +1,388 @@
|
||||
/* RetroArch - A frontend for libretro.
|
||||
* Copyright (C) 2010-2012 - Hans-Kristian Arntzen
|
||||
*
|
||||
* RetroArch is free software: you can redistribute it and/or modify it under the terms
|
||||
* of the GNU General Public License as published by the Free Software Found-
|
||||
* ation, either version 3 of the License, or (at your option) any later version.
|
||||
*
|
||||
* RetroArch is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
|
||||
* without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
|
||||
* PURPOSE. See the GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along with RetroArch.
|
||||
* If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include "cheats.h"
|
||||
#include "hash.h"
|
||||
#include "dynamic.h"
|
||||
#include "general.h"
|
||||
#include "compat/strl.h"
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
#include "config.h"
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_CONFIGFILE
|
||||
#include "conf/config_file.h"
|
||||
#endif
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <stddef.h>
|
||||
#include <string.h>
|
||||
|
||||
#include <libxml/parser.h>
|
||||
#include <libxml/tree.h>
|
||||
|
||||
struct cheat
|
||||
{
|
||||
char *desc;
|
||||
bool state;
|
||||
char *code;
|
||||
};
|
||||
|
||||
struct cheat_manager
|
||||
{
|
||||
struct cheat *cheats;
|
||||
unsigned ptr;
|
||||
unsigned size;
|
||||
unsigned buf_size;
|
||||
};
|
||||
|
||||
static char *strcat_alloc(char *dest, const char *input)
|
||||
{
|
||||
size_t dest_len = dest ? strlen(dest) : 0;
|
||||
size_t input_len = strlen(input);
|
||||
size_t required_len = dest_len + input_len + 1;
|
||||
|
||||
char *output = (char*)realloc(dest, required_len);
|
||||
if (!output)
|
||||
return NULL;
|
||||
|
||||
if (dest)
|
||||
strlcat(output, input, required_len);
|
||||
else
|
||||
strlcpy(output, input, required_len);
|
||||
|
||||
return output;
|
||||
}
|
||||
|
||||
static bool xml_grab_cheat(struct cheat *cht, xmlNodePtr ptr)
|
||||
{
|
||||
if (!ptr)
|
||||
return false;
|
||||
|
||||
memset(cht, 0, sizeof(struct cheat));
|
||||
bool first = true;
|
||||
|
||||
for (; ptr; ptr = ptr->next)
|
||||
{
|
||||
if (strcmp((const char*)ptr->name, "description") == 0)
|
||||
{
|
||||
cht->desc = (char*)xmlNodeGetContent(ptr);
|
||||
}
|
||||
else if (strcmp((const char*)ptr->name, "code") == 0)
|
||||
{
|
||||
if (!first)
|
||||
{
|
||||
cht->code = strcat_alloc(cht->code, "+");
|
||||
if (!cht->code)
|
||||
return false;
|
||||
}
|
||||
|
||||
xmlChar *code = xmlNodeGetContent(ptr);
|
||||
if (!code)
|
||||
return false;
|
||||
|
||||
cht->code = strcat_alloc(cht->code, (const char*)code);
|
||||
xmlFree(code);
|
||||
if (!cht->code)
|
||||
return false;
|
||||
|
||||
first = false;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
static bool xml_grab_cheats(cheat_manager_t *handle, xmlNodePtr ptr)
|
||||
{
|
||||
for (; ptr; ptr = ptr->next)
|
||||
{
|
||||
if (strcmp((const char*)ptr->name, "name") == 0)
|
||||
{
|
||||
xmlChar *name = xmlNodeGetContent(ptr);
|
||||
if (name)
|
||||
{
|
||||
RARCH_LOG("Found cheat for game: \"%s\"\n", name);
|
||||
xmlFree(name);
|
||||
}
|
||||
}
|
||||
else if (strcmp((const char*)ptr->name, "cheat") == 0)
|
||||
{
|
||||
if (handle->size == handle->buf_size)
|
||||
{
|
||||
handle->buf_size *= 2;
|
||||
handle->cheats = (struct cheat*)realloc(handle->cheats, handle->buf_size * sizeof(struct cheat));
|
||||
if (!handle->cheats)
|
||||
return false;
|
||||
}
|
||||
|
||||
if (xml_grab_cheat(&handle->cheats[handle->size], ptr->children))
|
||||
handle->size++;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
static void cheat_manager_apply_cheats(cheat_manager_t *handle)
|
||||
{
|
||||
unsigned index = 0;
|
||||
pretro_cheat_reset();
|
||||
for (unsigned i = 0; i < handle->size; i++)
|
||||
{
|
||||
if (handle->cheats[i].state)
|
||||
pretro_cheat_set(index++, true, handle->cheats[i].code);
|
||||
}
|
||||
}
|
||||
|
||||
static void cheat_manager_load_config(cheat_manager_t *handle, const char *path, const char *sha256)
|
||||
{
|
||||
#ifdef HAVE_CONFIGFILE
|
||||
if (!(*path))
|
||||
return;
|
||||
|
||||
config_file_t *conf = config_file_new(path);
|
||||
if (!conf)
|
||||
return;
|
||||
|
||||
char *str;
|
||||
if (!config_get_string(conf, sha256, &str))
|
||||
{
|
||||
config_file_free(conf);
|
||||
return;
|
||||
}
|
||||
|
||||
const char *num = strtok(str, ";");
|
||||
while (num)
|
||||
{
|
||||
unsigned index = strtoul(num, NULL, 0);
|
||||
if (index < handle->size)
|
||||
handle->cheats[index].state = true;
|
||||
|
||||
num = strtok(NULL, ";");
|
||||
}
|
||||
|
||||
free(str);
|
||||
config_file_free(conf);
|
||||
|
||||
cheat_manager_apply_cheats(handle);
|
||||
|
||||
#else
|
||||
(void)handle;
|
||||
(void)path;
|
||||
(void)sha256;
|
||||
#endif
|
||||
}
|
||||
|
||||
static void cheat_manager_save_config(cheat_manager_t *handle, const char *path, const char *sha256)
|
||||
{
|
||||
#ifdef HAVE_CONFIGFILE
|
||||
if (!(*path))
|
||||
return;
|
||||
|
||||
config_file_t *conf = config_file_new(path);
|
||||
if (!conf)
|
||||
conf = config_file_new(NULL);
|
||||
|
||||
if (!conf)
|
||||
{
|
||||
RARCH_ERR("Cannot save XML cheat settings.\n");
|
||||
return;
|
||||
}
|
||||
|
||||
char conf_str[512] = {0};
|
||||
char tmp[32] = {0};
|
||||
|
||||
for (unsigned i = 0; i < handle->size; i++)
|
||||
{
|
||||
if (handle->cheats[i].state)
|
||||
{
|
||||
snprintf(tmp, sizeof(tmp), "%u;", i);
|
||||
strlcat(conf_str, tmp, sizeof(conf_str));
|
||||
}
|
||||
}
|
||||
|
||||
if (*conf_str)
|
||||
conf_str[strlen(conf_str) - 1] = '\0'; // Remove the trailing ';'
|
||||
|
||||
config_set_string(conf, sha256, conf_str);
|
||||
|
||||
if (!config_file_write(conf, path))
|
||||
RARCH_ERR("Failed to write XML cheat settings to \"%s\". Check permissions.\n", path);
|
||||
|
||||
config_file_free(conf);
|
||||
|
||||
#else
|
||||
(void)handle;
|
||||
(void)path;
|
||||
(void)sha256;
|
||||
#endif
|
||||
}
|
||||
|
||||
cheat_manager_t* cheat_manager_new(const char *path)
|
||||
{
|
||||
LIBXML_TEST_VERSION;
|
||||
|
||||
pretro_cheat_reset();
|
||||
|
||||
xmlParserCtxtPtr ctx = NULL;
|
||||
xmlDocPtr doc = NULL;
|
||||
cheat_manager_t *handle = (cheat_manager_t*)calloc(1, sizeof(struct cheat_manager));
|
||||
if (!handle)
|
||||
return NULL;
|
||||
|
||||
xmlNodePtr head = NULL;
|
||||
xmlNodePtr cur = NULL;
|
||||
|
||||
handle->buf_size = 1;
|
||||
handle->cheats = (struct cheat*)calloc(handle->buf_size, sizeof(struct cheat));
|
||||
if (!handle->cheats)
|
||||
{
|
||||
handle->buf_size = 0;
|
||||
goto error;
|
||||
}
|
||||
|
||||
ctx = xmlNewParserCtxt();
|
||||
if (!ctx)
|
||||
goto error;
|
||||
|
||||
doc = xmlCtxtReadFile(ctx, path, NULL, 0);
|
||||
if (!doc)
|
||||
{
|
||||
RARCH_ERR("Failed to parse XML file: %s\n", path);
|
||||
goto error;
|
||||
}
|
||||
|
||||
if (ctx->valid == 0)
|
||||
{
|
||||
RARCH_ERR("Cannot validate XML file: %s\n", path);
|
||||
goto error;
|
||||
}
|
||||
|
||||
head = xmlDocGetRootElement(doc);
|
||||
for (cur = head; cur; cur = cur->next)
|
||||
{
|
||||
if (cur->type == XML_ELEMENT_NODE && strcmp((const char*)cur->name, "database") == 0)
|
||||
break;
|
||||
}
|
||||
|
||||
if (!cur)
|
||||
goto error;
|
||||
|
||||
for (cur = cur->children; cur; cur = cur->next)
|
||||
{
|
||||
if (cur->type != XML_ELEMENT_NODE)
|
||||
continue;
|
||||
|
||||
if (strcmp((const char*)cur->name, "cartridge") == 0)
|
||||
{
|
||||
xmlChar *sha256 = xmlGetProp(cur, (const xmlChar*)"sha256");
|
||||
if (!sha256)
|
||||
continue;
|
||||
|
||||
if (strcmp((const char*)sha256, g_extern.sha256) == 0)
|
||||
{
|
||||
xmlFree(sha256);
|
||||
break;
|
||||
}
|
||||
|
||||
xmlFree(sha256);
|
||||
}
|
||||
}
|
||||
|
||||
if (!cur)
|
||||
goto error;
|
||||
|
||||
if (!xml_grab_cheats(handle, cur->children))
|
||||
{
|
||||
RARCH_ERR("Failed to grab cheats. This should not happen.\n");
|
||||
goto error;
|
||||
}
|
||||
|
||||
if (handle->size == 0)
|
||||
{
|
||||
RARCH_ERR("Did not find any cheats in XML file: %s\n", path);
|
||||
goto error;
|
||||
}
|
||||
|
||||
cheat_manager_load_config(handle, g_settings.cheat_settings_path, g_extern.sha256);
|
||||
|
||||
xmlFreeDoc(doc);
|
||||
xmlFreeParserCtxt(ctx);
|
||||
return handle;
|
||||
|
||||
error:
|
||||
cheat_manager_free(handle);
|
||||
if (doc)
|
||||
xmlFreeDoc(doc);
|
||||
if (ctx)
|
||||
xmlFreeParserCtxt(ctx);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
void cheat_manager_free(cheat_manager_t *handle)
|
||||
{
|
||||
if (!handle)
|
||||
return;
|
||||
|
||||
if (handle->cheats)
|
||||
{
|
||||
cheat_manager_save_config(handle, g_settings.cheat_settings_path, g_extern.sha256);
|
||||
for (unsigned i = 0; i < handle->size; i++)
|
||||
{
|
||||
xmlFree(handle->cheats[i].desc);
|
||||
free(handle->cheats[i].code);
|
||||
}
|
||||
|
||||
free(handle->cheats);
|
||||
}
|
||||
|
||||
free(handle);
|
||||
}
|
||||
|
||||
static void cheat_manager_update(cheat_manager_t *handle)
|
||||
{
|
||||
msg_queue_clear(g_extern.msg_queue);
|
||||
char msg[256];
|
||||
snprintf(msg, sizeof(msg), "Cheat: #%u [%s]: %s", handle->ptr, handle->cheats[handle->ptr].state ? "ON" : "OFF", handle->cheats[handle->ptr].desc);
|
||||
msg_queue_push(g_extern.msg_queue, msg, 1, 180);
|
||||
RARCH_LOG("%s\n", msg);
|
||||
}
|
||||
|
||||
|
||||
void cheat_manager_toggle(cheat_manager_t *handle)
|
||||
{
|
||||
handle->cheats[handle->ptr].state ^= true;
|
||||
cheat_manager_apply_cheats(handle);
|
||||
cheat_manager_update(handle);
|
||||
}
|
||||
|
||||
void cheat_manager_index_next(cheat_manager_t *handle)
|
||||
{
|
||||
handle->ptr = (handle->ptr + 1) % handle->size;
|
||||
cheat_manager_update(handle);
|
||||
}
|
||||
|
||||
void cheat_manager_index_prev(cheat_manager_t *handle)
|
||||
{
|
||||
if (handle->ptr == 0)
|
||||
handle->ptr = handle->size - 1;
|
||||
else
|
||||
handle->ptr--;
|
||||
|
||||
cheat_manager_update(handle);
|
||||
}
|
||||
|
||||
@@ -0,0 +1,28 @@
|
||||
/* RetroArch - A frontend for libretro.
|
||||
* Copyright (C) 2010-2012 - Hans-Kristian Arntzen
|
||||
*
|
||||
* RetroArch is free software: you can redistribute it and/or modify it under the terms
|
||||
* of the GNU General Public License as published by the Free Software Found-
|
||||
* ation, either version 3 of the License, or (at your option) any later version.
|
||||
*
|
||||
* RetroArch is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
|
||||
* without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
|
||||
* PURPOSE. See the GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along with RetroArch.
|
||||
* If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifndef __RARCH_CHEATS_H
|
||||
#define __RARCH_CHEATS_H
|
||||
|
||||
typedef struct cheat_manager cheat_manager_t;
|
||||
|
||||
cheat_manager_t* cheat_manager_new(const char *path);
|
||||
void cheat_manager_free(cheat_manager_t *handle);
|
||||
|
||||
void cheat_manager_index_next(cheat_manager_t *handle);
|
||||
void cheat_manager_index_prev(cheat_manager_t *handle);
|
||||
void cheat_manager_toggle(cheat_manager_t *handle);
|
||||
|
||||
#endif
|
||||
+282
@@ -0,0 +1,282 @@
|
||||
/* RetroArch - A frontend for libretro.
|
||||
* Copyright (C) 2010-2012 - Hans-Kristian Arntzen
|
||||
*
|
||||
* RetroArch is free software: you can redistribute it and/or modify it under the terms
|
||||
* of the GNU General Public License as published by the Free Software Found-
|
||||
* ation, either version 3 of the License, or (at your option) any later version.
|
||||
*
|
||||
* RetroArch is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
|
||||
* without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
|
||||
* PURPOSE. See the GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along with RetroArch.
|
||||
* If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include "getopt_rarch.h"
|
||||
#include "strl.h"
|
||||
#include "posix_string.h"
|
||||
|
||||
#ifndef HAVE_GETOPT_LONG
|
||||
|
||||
#include <string.h>
|
||||
#include "../boolean.h"
|
||||
#include <stddef.h>
|
||||
#include <stdlib.h>
|
||||
#ifdef _MSC_VER
|
||||
#include "../msvc/msvc_compat.h"
|
||||
#endif
|
||||
#include "../general.h"
|
||||
|
||||
char *optarg;
|
||||
int optind, opterr, optopt;
|
||||
|
||||
static bool is_short_option(const char *str)
|
||||
{
|
||||
return str[0] == '-' && str[1] != '-';
|
||||
}
|
||||
|
||||
static bool is_long_option(const char *str)
|
||||
{
|
||||
return str[0] == '-' && str[1] == '-';
|
||||
}
|
||||
|
||||
static int find_short_index(char * const *argv)
|
||||
{
|
||||
for (int index = 0; argv[index]; index++)
|
||||
{
|
||||
if (is_short_option(argv[index]))
|
||||
return index;
|
||||
}
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
static int find_long_index(char * const *argv)
|
||||
{
|
||||
for (int index = 0; argv[index]; index++)
|
||||
{
|
||||
if (is_long_option(argv[index]))
|
||||
return index;
|
||||
}
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
static int parse_short(const char *optstring, char * const *argv)
|
||||
{
|
||||
char arg = argv[0][1];
|
||||
if (arg == ':')
|
||||
return '?';
|
||||
|
||||
const char *opt = strchr(optstring, arg);
|
||||
if (!opt)
|
||||
return '?';
|
||||
|
||||
bool extra_opt = argv[0][2];
|
||||
bool takes_arg = opt[1] == ':';
|
||||
|
||||
// If we take an argument, and we see additional characters,
|
||||
// this is in fact the argument (i.e. -cfoo is same as -c foo).
|
||||
bool embedded_arg = extra_opt && takes_arg;
|
||||
|
||||
if (takes_arg)
|
||||
{
|
||||
if (embedded_arg)
|
||||
{
|
||||
optarg = argv[0] + 2;
|
||||
optind++;
|
||||
}
|
||||
else
|
||||
{
|
||||
optarg = argv[1];
|
||||
optind += 2;
|
||||
}
|
||||
|
||||
return optarg ? opt[0] : '?';
|
||||
}
|
||||
else if (embedded_arg) // If we see additional characters, and they don't take arguments, this means we have multiple flags in one.
|
||||
{
|
||||
memmove(&argv[0][1], &argv[0][2], strlen(&argv[0][2]) + 1);
|
||||
return opt[0];
|
||||
}
|
||||
else
|
||||
{
|
||||
optind++;
|
||||
return opt[0];
|
||||
}
|
||||
}
|
||||
|
||||
static int parse_long(const struct option *longopts, char * const *argv)
|
||||
{
|
||||
const struct option *opt = NULL;
|
||||
for (size_t indice = 0; longopts[indice].name; indice++)
|
||||
{
|
||||
if (strcmp(longopts[indice].name, &argv[0][2]) == 0)
|
||||
{
|
||||
opt = &longopts[indice];
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (!opt)
|
||||
return '?';
|
||||
|
||||
// getopt_long has an "optional" arg, but we don't bother with that.
|
||||
if (opt->has_arg && !argv[1])
|
||||
return '?';
|
||||
|
||||
if (opt->has_arg)
|
||||
{
|
||||
optarg = argv[1];
|
||||
optind += 2;
|
||||
}
|
||||
else
|
||||
optind++;
|
||||
|
||||
if (opt->flag)
|
||||
{
|
||||
*opt->flag = opt->val;
|
||||
return 0;
|
||||
}
|
||||
else
|
||||
return opt->val;
|
||||
}
|
||||
|
||||
static void shuffle_block(char **begin, char **last, char **end)
|
||||
{
|
||||
ptrdiff_t len = last - begin;
|
||||
const char **tmp = (const char**)calloc(len, sizeof(const char*));
|
||||
rarch_assert(tmp);
|
||||
|
||||
memcpy(tmp, begin, sizeof(tmp));
|
||||
memmove(begin, last, (end - last) * sizeof(char*));
|
||||
memcpy(end - len, tmp, sizeof(tmp));
|
||||
|
||||
free(tmp);
|
||||
}
|
||||
|
||||
int getopt_long(int argc, char *argv[],
|
||||
const char *optstring, const struct option *longopts, int *longindex)
|
||||
{
|
||||
(void)longindex;
|
||||
if (argc == 1)
|
||||
return -1;
|
||||
|
||||
if (optind == 0)
|
||||
optind = 1;
|
||||
|
||||
int short_index = find_short_index(&argv[optind]);
|
||||
int long_index = find_long_index(&argv[optind]);
|
||||
|
||||
// We're done here.
|
||||
if (short_index == -1 && long_index == -1)
|
||||
return -1;
|
||||
|
||||
// Reorder argv so that non-options come last.
|
||||
// Non-POSIXy, but that's what getopt does by default.
|
||||
if ((short_index > 0) && ((short_index < long_index) || (long_index == -1)))
|
||||
{
|
||||
shuffle_block(&argv[optind], &argv[optind + short_index], &argv[argc]);
|
||||
short_index = 0;
|
||||
}
|
||||
else if ((long_index > 0) && ((long_index < short_index) || (short_index == -1)))
|
||||
{
|
||||
shuffle_block(&argv[optind], &argv[optind + long_index], &argv[argc]);
|
||||
long_index = 0;
|
||||
}
|
||||
|
||||
rarch_assert(short_index == 0 || long_index == 0);
|
||||
|
||||
if (short_index == 0)
|
||||
return parse_short(optstring, &argv[optind]);
|
||||
else if (long_index == 0)
|
||||
return parse_long(longopts, &argv[optind]);
|
||||
else
|
||||
return '?';
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
#ifndef HAVE_STRL
|
||||
|
||||
// Implementation of strlcpy()/strlcat() based on OpenBSD.
|
||||
|
||||
size_t strlcpy(char *dest, const char *source, size_t size)
|
||||
{
|
||||
size_t src_size = 0;
|
||||
size_t n = size;
|
||||
|
||||
if (n)
|
||||
while (--n && (*dest++ = *source++)) src_size++;
|
||||
|
||||
if (!n)
|
||||
{
|
||||
if (size) *dest = '\0';
|
||||
while (*source++) src_size++;
|
||||
}
|
||||
|
||||
return src_size;
|
||||
}
|
||||
|
||||
size_t strlcat(char *dest, const char *source, size_t size)
|
||||
{
|
||||
size_t len = strlen(dest);
|
||||
dest += len;
|
||||
|
||||
if (len > size)
|
||||
size = 0;
|
||||
else
|
||||
size -= len;
|
||||
|
||||
return len + strlcpy(dest, source, size);
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
#ifdef _WIN32
|
||||
|
||||
#undef strcasecmp
|
||||
#undef strdup
|
||||
#undef isblank
|
||||
#include <ctype.h>
|
||||
#include <stdlib.h>
|
||||
#include <stddef.h>
|
||||
#include "strl.h"
|
||||
|
||||
#include <string.h>
|
||||
|
||||
int strcasecmp_rarch__(const char *a, const char *b)
|
||||
{
|
||||
while (*a && *b)
|
||||
{
|
||||
int a_ = tolower(*a);
|
||||
int b_ = tolower(*b);
|
||||
if (a_ != b_)
|
||||
return a_ - b_;
|
||||
|
||||
a++;
|
||||
b++;
|
||||
}
|
||||
|
||||
return tolower(*a) - tolower(*b);
|
||||
}
|
||||
|
||||
char *strdup_rarch__(const char *orig)
|
||||
{
|
||||
size_t len = strlen(orig) + 1;
|
||||
char *ret = (char*)malloc(len);
|
||||
if (!ret)
|
||||
return NULL;
|
||||
|
||||
strlcpy(ret, orig, len);
|
||||
return ret;
|
||||
}
|
||||
|
||||
int isblank_rarch__(int c)
|
||||
{
|
||||
return (c == ' ') || (c == '\t');
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
@@ -0,0 +1,57 @@
|
||||
/* RetroArch - A frontend for libretro.
|
||||
* Copyright (C) 2010-2012 - Hans-Kristian Arntzen
|
||||
*
|
||||
* RetroArch is free software: you can redistribute it and/or modify it under the terms
|
||||
* of the GNU General Public License as published by the Free Software Found-
|
||||
* ation, either version 3 of the License, or (at your option) any later version.
|
||||
*
|
||||
* RetroArch is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
|
||||
* without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
|
||||
* PURPOSE. See the GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along with RetroArch.
|
||||
* If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifndef __RARCH_GETOPT_H
|
||||
#define __RARCH_GETOPT_H
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
#include "config.h"
|
||||
#endif
|
||||
|
||||
// Custom implementation of the GNU getopt_long for portability.
|
||||
// Not designed to be fully compatible,
|
||||
// but compatible with the features RetroArch uses.
|
||||
|
||||
#ifdef HAVE_GETOPT_LONG
|
||||
#include <getopt.h>
|
||||
#else
|
||||
// Avoid possible naming collitions during link since we prefer to use the actual name.
|
||||
#define getopt_long(argc, argv, optstring, longopts, longindex) __getopt_long_ssnes(argc, argv, optstring, longopts, longindex)
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
struct option
|
||||
{
|
||||
const char *name;
|
||||
int has_arg;
|
||||
int *flag;
|
||||
int val;
|
||||
};
|
||||
|
||||
// argv[] is declared with char * const argv[] in GNU,
|
||||
// but this makes no sense, as non-POSIX getopt_long mutates argv (non-opts are moved to the end).
|
||||
int getopt_long(int argc, char *argv[],
|
||||
const char *optstring, const struct option *longopts, int *longindex);
|
||||
extern char *optarg;
|
||||
extern int optind, opterr, optopt;
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
||||
@@ -0,0 +1,39 @@
|
||||
/* RetroArch - A frontend for libretro.
|
||||
* Copyright (C) 2010-2012 - Hans-Kristian Arntzen
|
||||
*
|
||||
* RetroArch is free software: you can redistribute it and/or modify it under the terms
|
||||
* of the GNU General Public License as published by the Free Software Found-
|
||||
* ation, either version 3 of the License, or (at your option) any later version.
|
||||
*
|
||||
* RetroArch is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
|
||||
* without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
|
||||
* PURPOSE. See the GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along with RetroArch.
|
||||
* If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifndef __RARCH_POSIX_STRING_H
|
||||
#define __RARCH_POSIX_STRING_H
|
||||
|
||||
#ifdef _WIN32
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#undef strcasecmp
|
||||
#define strcasecmp(a, b) strcasecmp_rarch__(a, b)
|
||||
#define strdup(orig) strdup_rarch__(orig)
|
||||
#define isblank(c) isblank_rarch__(c)
|
||||
int strcasecmp(const char *a, const char *b);
|
||||
char *strdup(const char *orig);
|
||||
int isblank(int c);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
||||
#endif
|
||||
|
||||
@@ -0,0 +1,42 @@
|
||||
/* RetroArch - A frontend for libretro.
|
||||
* Copyright (C) 2010-2012 - Hans-Kristian Arntzen
|
||||
*
|
||||
* RetroArch is free software: you can redistribute it and/or modify it under the terms
|
||||
* of the GNU General Public License as published by the Free Software Found-
|
||||
* ation, either version 3 of the License, or (at your option) any later version.
|
||||
*
|
||||
* RetroArch is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
|
||||
* without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
|
||||
* PURPOSE. See the GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along with RetroArch.
|
||||
* If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifndef __RARCH_STRL_H
|
||||
#define __RARCH_STRL_H
|
||||
|
||||
#include <string.h>
|
||||
#include <stddef.h>
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
#include "config.h"
|
||||
#endif
|
||||
|
||||
#ifndef HAVE_STRL
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
// Avoid possible naming collisions during link since we prefer to use the actual name.
|
||||
#define strlcpy(dst, src, size) strlcpy_rarch__(dst, src, size)
|
||||
#define strlcat(dst, src, size) strlcat_rarch__(dst, src, size)
|
||||
|
||||
size_t strlcpy(char *dest, const char *source, size_t size);
|
||||
size_t strlcat(char *dest, const char *source, size_t size);
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
#endif
|
||||
#endif
|
||||
|
||||
+469
-87
@@ -1,17 +1,15 @@
|
||||
/* SSNES - A Super Nintendo Entertainment System (SNES) Emulator frontend for libsnes.
|
||||
* Copyright (C) 2010-2011 - Hans-Kristian Arntzen
|
||||
*
|
||||
* Some code herein may be based on code found in BSNES.
|
||||
/* RetroArch - A frontend for libretro.
|
||||
* Copyright (C) 2010-2012 - Hans-Kristian Arntzen
|
||||
*
|
||||
* SSNES is free software: you can redistribute it and/or modify it under the terms
|
||||
* RetroArch is free software: you can redistribute it and/or modify it under the terms
|
||||
* of the GNU General Public License as published by the Free Software Found-
|
||||
* ation, either version 3 of the License, or (at your option) any later version.
|
||||
*
|
||||
* SSNES is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
|
||||
* RetroArch is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
|
||||
* without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
|
||||
* PURPOSE. See the GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along with SSNES.
|
||||
* You should have received a copy of the GNU General Public License along with RetroArch.
|
||||
* If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
@@ -21,22 +19,61 @@
|
||||
#include <string.h>
|
||||
#include <stdio.h>
|
||||
#include <ctype.h>
|
||||
#include <errno.h>
|
||||
#include "../compat/strl.h"
|
||||
#include "../compat/posix_string.h"
|
||||
#include "../msvc/msvc_compat.h"
|
||||
|
||||
#if !defined(_WIN32) && !defined(__CELLOS_LV2__) && !defined(_XBOX)
|
||||
#include <sys/param.h> // PATH_MAX
|
||||
#elif defined(_WIN32) && !defined(_XBOX)
|
||||
#define WIN32_LEAN_AND_MEAN
|
||||
#include <windows.h>
|
||||
#elif defined(_XBOX)
|
||||
#define NOD3D
|
||||
#define NONET
|
||||
#include <xtl.h>
|
||||
#endif
|
||||
|
||||
#ifndef PATH_MAX
|
||||
#ifdef PATH_MAX
|
||||
#define PATH_MAX PATH_MAX
|
||||
#else
|
||||
#define PATH_MAX 512
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#define MAX_INCLUDE_DEPTH 16
|
||||
|
||||
struct entry_list
|
||||
{
|
||||
bool readonly; // If we got this from an #include, do not allow write.
|
||||
char *key;
|
||||
char *value;
|
||||
struct entry_list *next;
|
||||
};
|
||||
|
||||
struct include_list
|
||||
{
|
||||
char *path;
|
||||
struct include_list *next;
|
||||
};
|
||||
|
||||
struct config_file
|
||||
{
|
||||
char *path;
|
||||
struct entry_list *entries;
|
||||
struct entry_list *tail;
|
||||
unsigned include_depth;
|
||||
|
||||
struct include_list *includes;
|
||||
};
|
||||
|
||||
static config_file_t *config_file_new_internal(const char *path, unsigned depth);
|
||||
|
||||
static char *getaline(FILE *file)
|
||||
{
|
||||
char *newline = malloc(9);
|
||||
char *newline = (char*)malloc(9);
|
||||
size_t cur_size = 8;
|
||||
size_t index = 0;
|
||||
|
||||
@@ -46,7 +83,7 @@ static char *getaline(FILE *file)
|
||||
if (index == cur_size)
|
||||
{
|
||||
cur_size *= 2;
|
||||
newline = realloc(newline, cur_size + 1);
|
||||
newline = (char*)realloc(newline, cur_size + 1);
|
||||
}
|
||||
|
||||
newline[index++] = in;
|
||||
@@ -56,18 +93,198 @@ static char *getaline(FILE *file)
|
||||
return newline;
|
||||
}
|
||||
|
||||
static bool parse_line(struct entry_list *list, char *line)
|
||||
static char *extract_value(char *line, bool is_value)
|
||||
{
|
||||
if (is_value)
|
||||
{
|
||||
while (isspace(*line))
|
||||
line++;
|
||||
|
||||
// If we don't have an equal sign here, we've got an invalid string...
|
||||
if (*line != '=')
|
||||
return NULL;
|
||||
|
||||
line++;
|
||||
}
|
||||
|
||||
while (isspace(*line))
|
||||
line++;
|
||||
|
||||
// We have a full string. Read until next ".
|
||||
if (*line == '"')
|
||||
{
|
||||
line++;
|
||||
char *tok = strtok(line, "\"");
|
||||
if (!tok)
|
||||
return NULL;
|
||||
return strdup(tok);
|
||||
}
|
||||
else if (*line == '\0') // Nothing :(
|
||||
return NULL;
|
||||
else // We don't have that... Read till next space.
|
||||
{
|
||||
char *tok = strtok(line, " \n\t\f\r\v");
|
||||
if (tok)
|
||||
return strdup(tok);
|
||||
else
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
|
||||
static void set_list_readonly(struct entry_list *list)
|
||||
{
|
||||
while (list)
|
||||
{
|
||||
list->readonly = true;
|
||||
list = list->next;
|
||||
}
|
||||
}
|
||||
|
||||
// Move semantics? :)
|
||||
static void add_child_list(config_file_t *parent, config_file_t *child)
|
||||
{
|
||||
if (parent->entries)
|
||||
{
|
||||
struct entry_list *head = parent->entries;
|
||||
while (head->next)
|
||||
head = head->next;
|
||||
|
||||
set_list_readonly(child->entries);
|
||||
head->next = child->entries;
|
||||
}
|
||||
else
|
||||
{
|
||||
set_list_readonly(child->entries);
|
||||
parent->entries = child->entries;
|
||||
}
|
||||
|
||||
child->entries = NULL;
|
||||
|
||||
// Rebase tail.
|
||||
if (parent->entries)
|
||||
{
|
||||
struct entry_list *head = parent->entries;
|
||||
while (head->next)
|
||||
head = head->next;
|
||||
parent->tail = head;
|
||||
}
|
||||
else
|
||||
parent->tail = NULL;
|
||||
}
|
||||
|
||||
static void add_include_list(config_file_t *conf, const char *path)
|
||||
{
|
||||
struct include_list *head = conf->includes;
|
||||
struct include_list *node = (struct include_list*)calloc(1, sizeof(*node));
|
||||
node->path = strdup(path);
|
||||
|
||||
if (head)
|
||||
{
|
||||
while (head->next)
|
||||
head = head->next;
|
||||
|
||||
head->next = node;
|
||||
}
|
||||
else
|
||||
conf->includes = node;
|
||||
}
|
||||
|
||||
static void add_sub_conf(config_file_t *conf, char *line)
|
||||
{
|
||||
char *path = extract_value(line, false);
|
||||
if (!path)
|
||||
return;
|
||||
|
||||
add_include_list(conf, path);
|
||||
|
||||
char real_path[PATH_MAX];
|
||||
|
||||
#ifdef _WIN32
|
||||
// Accomodate POSIX systems on Win32.
|
||||
bool is_full_path = *path == '/';
|
||||
|
||||
if (is_full_path)
|
||||
strlcpy(real_path, path, sizeof(real_path));
|
||||
else
|
||||
{
|
||||
// Workaround GetFullPathName not existing on XDK.
|
||||
// : is not a valid element in a path name. (NTFS streams?)
|
||||
if (strchr(path, ':') == NULL)
|
||||
{
|
||||
strlcpy(real_path, conf->path, sizeof(real_path));
|
||||
char *split = strrchr(real_path, '/');
|
||||
if (!split)
|
||||
split = strrchr(real_path, '\\');
|
||||
|
||||
split[1] = '\0';
|
||||
strlcat(real_path, path, sizeof(real_path));
|
||||
}
|
||||
else
|
||||
strlcpy(real_path, path, sizeof(real_path));
|
||||
}
|
||||
#else
|
||||
if (*path == '/')
|
||||
strlcpy(real_path, path, sizeof(real_path));
|
||||
#ifndef __CELLOS_LV2__
|
||||
else if (*path == '~')
|
||||
{
|
||||
const char *home = getenv("HOME");
|
||||
strlcpy(real_path, home ? home : "/", sizeof(real_path));
|
||||
strlcat(real_path, path + 1, sizeof(real_path));
|
||||
}
|
||||
#endif
|
||||
else
|
||||
{
|
||||
strlcpy(real_path, conf->path, sizeof(real_path));
|
||||
char *split = strrchr(real_path, '/');
|
||||
if (split)
|
||||
{
|
||||
split[1] = '\0';
|
||||
strlcat(real_path, path, sizeof(real_path));
|
||||
}
|
||||
else
|
||||
strlcpy(real_path, path, sizeof(real_path));
|
||||
}
|
||||
#endif
|
||||
|
||||
config_file_t *sub_conf = config_file_new_internal(real_path, conf->include_depth + 1);
|
||||
if (!sub_conf)
|
||||
{
|
||||
free(path);
|
||||
return;
|
||||
}
|
||||
|
||||
// Pilfer internal list. :D
|
||||
add_child_list(conf, sub_conf);
|
||||
config_file_free(sub_conf);
|
||||
free(path);
|
||||
}
|
||||
|
||||
static bool parse_line(config_file_t *conf, struct entry_list *list, char *line)
|
||||
{
|
||||
// Remove everything after comment.
|
||||
char *comment = strchr(line, '#');
|
||||
if (comment)
|
||||
*comment = '\0';
|
||||
|
||||
// Starting line with # and include includes config files. :)
|
||||
if ((comment == line) && (conf->include_depth < MAX_INCLUDE_DEPTH))
|
||||
{
|
||||
comment++;
|
||||
if (strstr(comment, "include ") == comment)
|
||||
{
|
||||
add_sub_conf(conf, comment + strlen("include "));
|
||||
return false;
|
||||
}
|
||||
}
|
||||
else if (conf->include_depth >= MAX_INCLUDE_DEPTH)
|
||||
fprintf(stderr, "!!! #include depth exceeded for config. Might be a cycle.\n");
|
||||
|
||||
// Skips to first character.
|
||||
while (isspace(*line))
|
||||
line++;
|
||||
|
||||
char *key = malloc(9);
|
||||
char *key = (char*)malloc(9);
|
||||
size_t cur_size = 8;
|
||||
size_t index = 0;
|
||||
|
||||
@@ -76,7 +293,7 @@ static bool parse_line(struct entry_list *list, char *line)
|
||||
if (index == cur_size)
|
||||
{
|
||||
cur_size *= 2;
|
||||
key = realloc(key, cur_size + 1);
|
||||
key = (char*)realloc(key, cur_size + 1);
|
||||
}
|
||||
|
||||
key[index++] = *line++;
|
||||
@@ -84,118 +301,113 @@ static bool parse_line(struct entry_list *list, char *line)
|
||||
key[index] = '\0';
|
||||
list->key = key;
|
||||
|
||||
while (isspace(*line))
|
||||
line++;
|
||||
|
||||
// If we don't have an equal sign here, we've got an invalid string...
|
||||
if (*line != '=')
|
||||
list->value = extract_value(line, true);
|
||||
if (!list->value)
|
||||
{
|
||||
list->key = NULL;
|
||||
free(key);
|
||||
return false;
|
||||
}
|
||||
line++;
|
||||
|
||||
while (isspace(*line))
|
||||
line++;
|
||||
|
||||
// We have a full string. Read until next ".
|
||||
if (*line == '"')
|
||||
{
|
||||
char *tok = strtok(line + 1, "\"");
|
||||
if (tok == NULL)
|
||||
{
|
||||
list->key = NULL;
|
||||
free(key);
|
||||
return false;
|
||||
}
|
||||
list->value = strdup(tok);
|
||||
}
|
||||
else // We don't have that... Read till next space.
|
||||
{
|
||||
char *tok = strtok(line, " \t\f");
|
||||
if (tok == NULL)
|
||||
{
|
||||
list->key = NULL;
|
||||
free(key);
|
||||
return false;
|
||||
}
|
||||
list->value = strdup(tok);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
config_file_t *config_file_new(const char *path)
|
||||
static config_file_t *config_file_new_internal(const char *path, unsigned depth)
|
||||
{
|
||||
|
||||
struct config_file *conf = calloc(1, sizeof(*conf));
|
||||
if (conf == NULL)
|
||||
struct config_file *conf = (struct config_file*)calloc(1, sizeof(*conf));
|
||||
if (!conf)
|
||||
return NULL;
|
||||
|
||||
if (path == NULL)
|
||||
if (!path)
|
||||
return conf;
|
||||
|
||||
FILE *file = fopen(path, "r");
|
||||
if (!file)
|
||||
conf->path = strdup(path);
|
||||
if (!conf->path)
|
||||
{
|
||||
free(conf);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
struct entry_list *tail = conf->entries;
|
||||
conf->include_depth = depth;
|
||||
|
||||
FILE *file = fopen(path, "r");
|
||||
if (!file)
|
||||
{
|
||||
free(conf->path);
|
||||
free(conf);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
while (!feof(file))
|
||||
{
|
||||
struct entry_list *list = calloc(1, sizeof(*list));
|
||||
struct entry_list *list = (struct entry_list*)calloc(1, sizeof(*list));
|
||||
char *line = getaline(file);
|
||||
|
||||
if (line)
|
||||
{
|
||||
if (parse_line(list, line))
|
||||
if (parse_line(conf, list, line))
|
||||
{
|
||||
if (conf->entries == NULL)
|
||||
if (conf->entries)
|
||||
{
|
||||
conf->entries = list;
|
||||
tail = list;
|
||||
conf->tail->next = list;
|
||||
conf->tail = list;
|
||||
}
|
||||
else
|
||||
{
|
||||
tail->next = list;
|
||||
tail = list;
|
||||
conf->entries = list;
|
||||
conf->tail = list;
|
||||
}
|
||||
}
|
||||
|
||||
free(line);
|
||||
}
|
||||
|
||||
if (list != conf->tail)
|
||||
free(list);
|
||||
}
|
||||
fclose(file);
|
||||
|
||||
return conf;
|
||||
}
|
||||
|
||||
config_file_t *config_file_new(const char *path)
|
||||
{
|
||||
return config_file_new_internal(path, 0);
|
||||
}
|
||||
|
||||
void config_file_free(config_file_t *conf)
|
||||
{
|
||||
if (conf != NULL)
|
||||
if (!conf)
|
||||
return;
|
||||
|
||||
struct entry_list *tmp = conf->entries;
|
||||
while (tmp)
|
||||
{
|
||||
struct entry_list *tmp = conf->entries;
|
||||
struct entry_list *old = tmp;
|
||||
while (tmp != NULL)
|
||||
{
|
||||
free(tmp->key);
|
||||
free(tmp->value);
|
||||
old = tmp;
|
||||
tmp = tmp->next;
|
||||
free(old);
|
||||
}
|
||||
free(conf);
|
||||
free(tmp->key);
|
||||
free(tmp->value);
|
||||
struct entry_list *hold = tmp;
|
||||
tmp = tmp->next;
|
||||
free(hold);
|
||||
}
|
||||
|
||||
struct include_list *inc_tmp = conf->includes;
|
||||
while (inc_tmp)
|
||||
{
|
||||
free(inc_tmp->path);
|
||||
struct include_list *hold = inc_tmp;
|
||||
inc_tmp = inc_tmp->next;
|
||||
free(hold);
|
||||
}
|
||||
|
||||
free(conf->path);
|
||||
free(conf);
|
||||
}
|
||||
|
||||
bool config_get_double(config_file_t *conf, const char *key, double *in)
|
||||
{
|
||||
struct entry_list *list = conf->entries;
|
||||
|
||||
while (list != NULL)
|
||||
while (list)
|
||||
{
|
||||
if (strcmp(key, list->key) == 0)
|
||||
{
|
||||
@@ -207,16 +419,108 @@ bool config_get_double(config_file_t *conf, const char *key, double *in)
|
||||
return false;
|
||||
}
|
||||
|
||||
bool config_get_float(config_file_t *conf, const char *key, float *in)
|
||||
{
|
||||
struct entry_list *list = conf->entries;
|
||||
|
||||
while (list)
|
||||
{
|
||||
if (strcmp(key, list->key) == 0)
|
||||
{
|
||||
#ifdef __cplusplus
|
||||
// strtof() is C99/POSIX.
|
||||
*in = (float)strtod(list->value, NULL);
|
||||
#else
|
||||
*in = strtof(list->value, NULL);
|
||||
#endif
|
||||
return true;
|
||||
}
|
||||
list = list->next;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
bool config_get_int(config_file_t *conf, const char *key, int *in)
|
||||
{
|
||||
struct entry_list *list = conf->entries;
|
||||
|
||||
while (list != NULL)
|
||||
while (list)
|
||||
{
|
||||
if (strcmp(key, list->key) == 0)
|
||||
{
|
||||
*in = strtol(list->value, NULL, 0);
|
||||
return true;
|
||||
errno = 0;
|
||||
int val = strtol(list->value, NULL, 0);
|
||||
if (errno == 0)
|
||||
{
|
||||
*in = val;
|
||||
return true;
|
||||
}
|
||||
return
|
||||
false;
|
||||
}
|
||||
list = list->next;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
bool config_get_uint64(config_file_t *conf, const char *key, uint64_t *in)
|
||||
{
|
||||
struct entry_list *list = conf->entries;
|
||||
|
||||
while (list)
|
||||
{
|
||||
if (strcmp(key, list->key) == 0)
|
||||
{
|
||||
errno = 0;
|
||||
uint64_t val = strtoull(list->value, NULL, 0);
|
||||
if (errno == 0)
|
||||
{
|
||||
*in = val;
|
||||
return true;
|
||||
}
|
||||
return
|
||||
false;
|
||||
}
|
||||
list = list->next;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
bool config_get_uint(config_file_t *conf, const char *key, unsigned *in)
|
||||
{
|
||||
struct entry_list *list = conf->entries;
|
||||
|
||||
while (list != NULL)
|
||||
{
|
||||
if (strcmp(key, list->key) == 0)
|
||||
{
|
||||
*in = strtol(list->value, NULL, 0);
|
||||
return true;
|
||||
}
|
||||
list = list->next;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
bool config_get_hex(config_file_t *conf, const char *key, unsigned *in)
|
||||
{
|
||||
struct entry_list *list = conf->entries;
|
||||
|
||||
while (list)
|
||||
{
|
||||
if (strcmp(key, list->key) == 0)
|
||||
{
|
||||
errno = 0;
|
||||
unsigned val = strtoul(list->value, NULL, 16);
|
||||
if (errno == 0)
|
||||
{
|
||||
*in = val;
|
||||
return true;
|
||||
}
|
||||
else
|
||||
return false;
|
||||
}
|
||||
list = list->next;
|
||||
}
|
||||
@@ -227,11 +531,11 @@ bool config_get_char(config_file_t *conf, const char *key, char *in)
|
||||
{
|
||||
struct entry_list *list = conf->entries;
|
||||
|
||||
while (list != NULL)
|
||||
while (list)
|
||||
{
|
||||
if (strcmp(key, list->key) == 0)
|
||||
{
|
||||
if (strlen(list->value) > 1)
|
||||
if (list->value[0] && list->value[1])
|
||||
return false;
|
||||
*in = *list->value;
|
||||
return true;
|
||||
@@ -245,7 +549,7 @@ bool config_get_string(config_file_t *conf, const char *key, char **str)
|
||||
{
|
||||
struct entry_list *list = conf->entries;
|
||||
|
||||
while (list != NULL)
|
||||
while (list)
|
||||
{
|
||||
if (strcmp(key, list->key) == 0)
|
||||
{
|
||||
@@ -257,11 +561,27 @@ bool config_get_string(config_file_t *conf, const char *key, char **str)
|
||||
return false;
|
||||
}
|
||||
|
||||
bool config_get_array(config_file_t *conf, const char *key, char *buf, size_t size)
|
||||
{
|
||||
struct entry_list *list = conf->entries;
|
||||
|
||||
while (list)
|
||||
{
|
||||
if (strcmp(key, list->key) == 0)
|
||||
{
|
||||
strlcpy(buf, list->value, size);
|
||||
return true;
|
||||
}
|
||||
list = list->next;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
bool config_get_bool(config_file_t *conf, const char *key, bool *in)
|
||||
{
|
||||
struct entry_list *list = conf->entries;
|
||||
|
||||
while (list != NULL)
|
||||
while (list)
|
||||
{
|
||||
if (strcmp(key, list->key) == 0)
|
||||
{
|
||||
@@ -287,19 +607,20 @@ void config_set_string(config_file_t *conf, const char *key, const char *val)
|
||||
{
|
||||
struct entry_list *list = conf->entries;
|
||||
struct entry_list *last = list;
|
||||
while (list != NULL)
|
||||
while (list)
|
||||
{
|
||||
if (strcmp(key, list->key) == 0)
|
||||
if (!list->readonly && (strcmp(key, list->key) == 0))
|
||||
{
|
||||
free(list->value);
|
||||
list->value = strdup(val);
|
||||
return;
|
||||
}
|
||||
|
||||
last = list;
|
||||
list = list->next;
|
||||
}
|
||||
|
||||
struct entry_list *elem = calloc(1, sizeof(*elem));
|
||||
struct entry_list *elem = (struct entry_list*)calloc(1, sizeof(*elem));
|
||||
elem->key = strdup(key);
|
||||
elem->value = strdup(val);
|
||||
|
||||
@@ -312,7 +633,18 @@ void config_set_string(config_file_t *conf, const char *key, const char *val)
|
||||
void config_set_double(config_file_t *conf, const char *key, double val)
|
||||
{
|
||||
char buf[128];
|
||||
#ifdef __cplusplus
|
||||
snprintf(buf, sizeof(buf), "%f", (float)val);
|
||||
#else
|
||||
snprintf(buf, sizeof(buf), "%lf", val);
|
||||
#endif
|
||||
config_set_string(conf, key, buf);
|
||||
}
|
||||
|
||||
void config_set_float(config_file_t *conf, const char *key, float val)
|
||||
{
|
||||
char buf[128];
|
||||
snprintf(buf, sizeof(buf), "%f", val);
|
||||
config_set_string(conf, key, buf);
|
||||
}
|
||||
|
||||
@@ -323,6 +655,17 @@ void config_set_int(config_file_t *conf, const char *key, int val)
|
||||
config_set_string(conf, key, buf);
|
||||
}
|
||||
|
||||
void config_set_uint64(config_file_t *conf, const char *key, uint64_t val)
|
||||
{
|
||||
char buf[128];
|
||||
#ifdef _WIN32
|
||||
snprintf(buf, sizeof(buf), "%I64u", val);
|
||||
#else
|
||||
snprintf(buf, sizeof(buf), "%llu", (long long unsigned)val);
|
||||
#endif
|
||||
config_set_string(conf, key, buf);
|
||||
}
|
||||
|
||||
void config_set_char(config_file_t *conf, const char *key, char val)
|
||||
{
|
||||
char buf[2];
|
||||
@@ -358,11 +701,50 @@ bool config_file_write(config_file_t *conf, const char *path)
|
||||
|
||||
void config_file_dump(config_file_t *conf, FILE *file)
|
||||
{
|
||||
struct entry_list *list = conf->entries;
|
||||
|
||||
while (list != NULL)
|
||||
struct include_list *includes = conf->includes;
|
||||
while (includes)
|
||||
{
|
||||
fprintf(file, "%s = \"%s\"\n", list->key, list->value);
|
||||
fprintf(file, "#include \"%s\"\n", includes->path);
|
||||
includes = includes->next;
|
||||
}
|
||||
|
||||
struct entry_list *list = conf->entries;
|
||||
while (list)
|
||||
{
|
||||
if (!list->readonly)
|
||||
fprintf(file, "%s = \"%s\"\n", list->key, list->value);
|
||||
list = list->next;
|
||||
}
|
||||
}
|
||||
|
||||
void config_file_dump_all(config_file_t *conf, FILE *file)
|
||||
{
|
||||
struct include_list *includes = conf->includes;
|
||||
while (includes)
|
||||
{
|
||||
fprintf(file, "#include \"%s\"\n", includes->path);
|
||||
includes = includes->next;
|
||||
}
|
||||
|
||||
struct entry_list *list = conf->entries;
|
||||
while (list)
|
||||
{
|
||||
fprintf(file, "%s = \"%s\" %s\n", list->key, list->value, list->readonly ? "(included)" : "");
|
||||
list = list->next;
|
||||
}
|
||||
}
|
||||
|
||||
bool config_entry_exists(config_file_t *conf, const char *entry)
|
||||
{
|
||||
struct entry_list *list = conf->entries;
|
||||
|
||||
while (list)
|
||||
{
|
||||
if (strcmp(entry, list->key) == 0)
|
||||
return true;
|
||||
list = list->next;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
+34
-13
@@ -1,17 +1,15 @@
|
||||
/* SSNES - A Super Nintendo Entertainment System (SNES) Emulator frontend for libsnes.
|
||||
* Copyright (C) 2010-2011 - Hans-Kristian Arntzen
|
||||
*
|
||||
* Some code herein may be based on code found in BSNES.
|
||||
/* RetroArch - A frontend for libretro.
|
||||
* Copyright (C) 2010-2012 - Hans-Kristian Arntzen
|
||||
*
|
||||
* SSNES is free software: you can redistribute it and/or modify it under the terms
|
||||
* RetroArch is free software: you can redistribute it and/or modify it under the terms
|
||||
* of the GNU General Public License as published by the Free Software Found-
|
||||
* ation, either version 3 of the License, or (at your option) any later version.
|
||||
*
|
||||
* SSNES is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
|
||||
* RetroArch is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
|
||||
* without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
|
||||
* PURPOSE. See the GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along with SSNES.
|
||||
* You should have received a copy of the GNU General Public License along with RetroArch.
|
||||
* If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
@@ -20,8 +18,9 @@
|
||||
#define __CONFIG_FILE_H
|
||||
|
||||
#include <stdint.h>
|
||||
#include <stdbool.h>
|
||||
#include "../boolean.h"
|
||||
#include <stdio.h>
|
||||
#include <stddef.h>
|
||||
|
||||
typedef struct config_file config_file_t;
|
||||
|
||||
@@ -30,28 +29,49 @@ typedef struct config_file config_file_t;
|
||||
// - # are treated as comments. Rest of the line is ignored.
|
||||
// - Format is: key = value. There can be as many spaces as you like in-between.
|
||||
// - Value can be wrapped inside "" for multiword strings. (foo = "hai u")
|
||||
//
|
||||
// - #include includes a config file in-place.
|
||||
// Path is relative to where config file was loaded unless an absolute path is chosen.
|
||||
// Key/value pairs from an #include are read-only, and cannot be modified.
|
||||
|
||||
// Loads a config file. Returns NULL if file doesn't exist. NULL path will create an empty config file.
|
||||
// Loads a config file. Returns NULL if file doesn't exist.
|
||||
// NULL path will create an empty config file.
|
||||
config_file_t *config_file_new(const char *path);
|
||||
// Frees config file.
|
||||
void config_file_free(config_file_t *conf);
|
||||
|
||||
// All extract functions return true when value is valid and exists. Returns false otherwise.
|
||||
// All extract functions return true when value is valid and exists.
|
||||
// Returns false otherwise.
|
||||
|
||||
bool config_entry_exists(config_file_t *conf, const char *entry);
|
||||
|
||||
// Extracts a double from config file.
|
||||
bool config_get_double(config_file_t *conf, const char *entry, double *in);
|
||||
// Extracts a float from config file.
|
||||
bool config_get_float(config_file_t *conf, const char *entry, float *in);
|
||||
// Extracts an int from config file.
|
||||
bool config_get_int(config_file_t *conf, const char *entry, int *in);
|
||||
// Extracts an uint from config file.
|
||||
bool config_get_uint(config_file_t *conf, const char *entry, unsigned *in);
|
||||
// Extracts an uint64 from config file.
|
||||
bool config_get_uint64(config_file_t *conf, const char *entry, uint64_t *in);
|
||||
// Extracts an unsigned int from config file treating input as hex.
|
||||
bool config_get_hex(config_file_t *conf, const char *entry, unsigned *in);
|
||||
// Extracts a single char. If value consists of several chars, this is an error.
|
||||
bool config_get_char(config_file_t *conf, const char *entry, char *in);
|
||||
// Extracts an allocated string in *in. This must be free()-d if this function succeeds.
|
||||
bool config_get_string(config_file_t *conf, const char *entry, char **in);
|
||||
// Extracts a string to a preallocated buffer. Avoid memory allocation.
|
||||
bool config_get_array(config_file_t *conf, const char *entry, char *in, size_t size);
|
||||
// Extracts a boolean from config. Valid boolean true are "true" and "1". Valid false are "false" and "0". Other values will be treated as an error.
|
||||
bool config_get_bool(config_file_t *conf, const char *entry, bool *in);
|
||||
|
||||
// Setters. Similiar to the getters.
|
||||
// Setters. Similar to the getters. Will not write to entry if the entry
|
||||
// was obtained from an #include.
|
||||
void config_set_double(config_file_t *conf, const char *entry, double value);
|
||||
void config_set_float(config_file_t *conf, const char *entry, float value);
|
||||
void config_set_int(config_file_t *conf, const char *entry, int val);
|
||||
void config_set_uint64(config_file_t *conf, const char *entry, uint64_t val);
|
||||
void config_set_char(config_file_t *conf, const char *entry, char val);
|
||||
void config_set_string(config_file_t *conf, const char *entry, const char *val);
|
||||
void config_set_bool(config_file_t *conf, const char *entry, bool val);
|
||||
@@ -61,7 +81,8 @@ bool config_file_write(config_file_t *conf, const char *path);
|
||||
|
||||
// Dump the current config to an already opened file. Does not close the file.
|
||||
void config_file_dump(config_file_t *conf, FILE *file);
|
||||
|
||||
|
||||
// Also dumps inherited values, useful for logging.
|
||||
void config_file_dump_all(config_file_t *conf, FILE *file);
|
||||
|
||||
#endif
|
||||
|
||||
@@ -0,0 +1,69 @@
|
||||
/* RetroArch - A frontend for libretro.
|
||||
* Copyright (C) 2010-2012 - Hans-Kristian Arntzen
|
||||
* Copyright (C) 2011-2012 - Daniel De Matteis
|
||||
*
|
||||
* RetroArch is free software: you can redistribute it and/or modify it under the terms
|
||||
* of the GNU General Public License as published by the Free Software Found-
|
||||
* ation, either version 3 of the License, or (at your option) any later version.
|
||||
*
|
||||
* RetroArch is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
|
||||
* without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
|
||||
* PURPOSE. See the GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along with RetroArch.
|
||||
* If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifndef CONFIG_FILE_MACROS_H__
|
||||
#define CONFIG_FILE_MACROS_H__
|
||||
|
||||
// Macros to ease config getting.
|
||||
#include <stdint.h>
|
||||
|
||||
#define CONFIG_GET_BOOL_BASE(conf, base, var, key) do { \
|
||||
bool tmp = false; \
|
||||
if (config_get_bool(conf, key, &tmp)) \
|
||||
base.var = tmp; \
|
||||
} while(0)
|
||||
|
||||
#define CONFIG_GET_INT_BASE(conf, base, var, key) do { \
|
||||
int tmp = 0; \
|
||||
if (config_get_int(conf, key, &tmp)) \
|
||||
base.var = tmp; \
|
||||
} while(0)
|
||||
|
||||
#define CONFIG_GET_UINT64_BASE(conf, base, var, key) do { \
|
||||
uint64_t tmp = 0; \
|
||||
if (config_get_int(conf, key, &tmp)) \
|
||||
base.var = tmp; \
|
||||
} while(0)
|
||||
|
||||
#define CONFIG_GET_FLOAT_BASE(conf, base, var, key) do { \
|
||||
float tmp = 0.0f; \
|
||||
if (config_get_float(conf, key, &tmp)) \
|
||||
base.var = tmp; \
|
||||
} while(0)
|
||||
|
||||
#define CONFIG_GET_STRING_BASE(conf, base, var, key) \
|
||||
config_get_array(conf, key, base.var, sizeof(base.var))
|
||||
|
||||
#define CONFIG_GET_BOOL(var, key) CONFIG_GET_BOOL_BASE(conf, g_settings, var, key)
|
||||
#define CONFIG_GET_INT(var, key) CONFIG_GET_INT_BASE(conf, g_settings, var, key)
|
||||
#define CONFIG_GET_UINT64(var, key) CONFIG_GET_UINT64_BASE(conf, g_settings, var, key)
|
||||
#define CONFIG_GET_FLOAT(var, key) CONFIG_GET_FLOAT_BASE(conf, g_settings, var, key)
|
||||
#define CONFIG_GET_STRING(var, key) CONFIG_GET_STRING_BASE(conf, g_settings, var, key)
|
||||
|
||||
#define CONFIG_GET_BOOL_EXTERN(var, key) CONFIG_GET_BOOL_BASE(conf, g_extern, var, key)
|
||||
#define CONFIG_GET_INT_EXTERN(var, key) CONFIG_GET_INT_BASE(conf, g_extern, var, key)
|
||||
#define CONFIG_GET_FLOAT_EXTERN(var, key) CONFIG_GET_FLOAT_BASE(conf, g_extern, var, key)
|
||||
#define CONFIG_GET_STRING_EXTERN(var, key) CONFIG_GET_STRING_BASE(conf, g_extern, var, key)
|
||||
|
||||
#ifdef RARCH_CONSOLE
|
||||
#define CONFIG_GET_BOOL_CONSOLE(var, key) CONFIG_GET_BOOL_BASE(conf, g_console, var, key)
|
||||
#define CONFIG_GET_INT_CONSOLE(var, key) CONFIG_GET_INT_BASE(conf, g_console, var, key)
|
||||
#define CONFIG_GET_FLOAT_CONSOLE(var, key) CONFIG_GET_FLOAT_BASE(conf, g_console, var, key)
|
||||
#define CONFIG_GET_STRING_CONSOLE(var, key) CONFIG_GET_STRING_BASE(conf, g_console, var, key)
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
||||
+262
-140
@@ -1,50 +1,43 @@
|
||||
/* SSNES - A Super Nintendo Entertainment System (SNES) Emulator frontend for libsnes.
|
||||
* Copyright (C) 2010-2011 - Hans-Kristian Arntzen
|
||||
*
|
||||
* Some code herein may be based on code found in BSNES.
|
||||
/* RetroArch - A frontend for libretro.
|
||||
* Copyright (C) 2010-2012 - Hans-Kristian Arntzen
|
||||
*
|
||||
* SSNES is free software: you can redistribute it and/or modify it under the terms
|
||||
* RetroArch is free software: you can redistribute it and/or modify it under the terms
|
||||
* of the GNU General Public License as published by the Free Software Found-
|
||||
* ation, either version 3 of the License, or (at your option) any later version.
|
||||
*
|
||||
* SSNES is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
|
||||
* RetroArch is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
|
||||
* without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
|
||||
* PURPOSE. See the GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along with SSNES.
|
||||
* You should have received a copy of the GNU General Public License along with RetroArch.
|
||||
* If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
/// Config header for SSNES
|
||||
/// Config header for RetroArch
|
||||
//
|
||||
//
|
||||
|
||||
#ifndef __CONFIG_DEF_H
|
||||
#define __CONFIG_DEF_H
|
||||
|
||||
#include <stdbool.h>
|
||||
#include "libsnes.hpp"
|
||||
#include "boolean.h"
|
||||
#include "libretro.h"
|
||||
#include "driver.h"
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
#include "config.h"
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_SDL
|
||||
#include <SDL/SDL.h>
|
||||
#else
|
||||
#error HAVE_SDL is not defined!
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_SRC
|
||||
#include <samplerate.h>
|
||||
#else
|
||||
#error HAVE_SRC is not defined!
|
||||
#endif
|
||||
|
||||
#include "input/keysym.h"
|
||||
|
||||
///////////////// Drivers
|
||||
#define VIDEO_GL 0
|
||||
#define VIDEO_XVIDEO 11
|
||||
#define VIDEO_SDL 13
|
||||
#define VIDEO_EXT 14
|
||||
#define VIDEO_WII 24
|
||||
#define VIDEO_XENON360 25
|
||||
#define VIDEO_XDK360 28
|
||||
////////////////////////
|
||||
#define AUDIO_RSOUND 1
|
||||
#define AUDIO_OSS 2
|
||||
@@ -53,29 +46,93 @@
|
||||
#define AUDIO_AL 5
|
||||
#define AUDIO_JACK 6
|
||||
#define AUDIO_SDL 8
|
||||
#define AUDIO_XAUDIO 9
|
||||
#define AUDIO_PULSE 10
|
||||
#define AUDIO_EXT 15
|
||||
#define AUDIO_DSOUND 16
|
||||
#define AUDIO_COREAUDIO 17
|
||||
#define AUDIO_PS3 18
|
||||
#define AUDIO_XENON360 20
|
||||
#define AUDIO_WII 22
|
||||
#define AUDIO_XDK360 27
|
||||
////////////////////////
|
||||
#define INPUT_SDL 7
|
||||
#define INPUT_X 12
|
||||
#define INPUT_PS3 19
|
||||
#define INPUT_XENON360 21
|
||||
#define INPUT_WII 23
|
||||
#define INPUT_XDK360 26
|
||||
////////////////////////
|
||||
|
||||
#if defined(HAVE_OPENGL) || defined(__CELLOS_LV2__)
|
||||
#define VIDEO_DEFAULT_DRIVER VIDEO_GL
|
||||
|
||||
#if HAVE_ALSA
|
||||
#define AUDIO_DEFAULT_DRIVER AUDIO_ALSA
|
||||
#elif HAVE_OSS
|
||||
#define AUDIO_DEFAULT_DRIVER AUDIO_OSS
|
||||
#elif HAVE_JACK
|
||||
#define AUDIO_DEFAULT_DRIVER AUDIO_JACK
|
||||
#elif HAVE_RSOUND
|
||||
#define AUDIO_DEFAULT_DRIVER AUDIO_RSOUND
|
||||
#elif HAVE_ROAR
|
||||
#define AUDIO_DEFAULT_DRIVER AUDIO_ROAR
|
||||
#elif HAVE_AL
|
||||
#define AUDIO_DEFAULT_DRIVER AUDIO_AL
|
||||
#elif HAVE_SDL
|
||||
#define AUDIO_DEFAULT_DRIVER AUDIO_SDL
|
||||
#elif defined(GEKKO)
|
||||
#define VIDEO_DEFAULT_DRIVER VIDEO_WII
|
||||
#elif defined(XENON)
|
||||
#define VIDEO_DEFAULT_DRIVER VIDEO_XENON360
|
||||
#elif defined(_XBOX)
|
||||
#define VIDEO_DEFAULT_DRIVER VIDEO_XDK360
|
||||
#elif defined(HAVE_XVIDEO)
|
||||
#define VIDEO_DEFAULT_DRIVER VIDEO_XVIDEO
|
||||
#elif defined(HAVE_SDL)
|
||||
#define VIDEO_DEFAULT_DRIVER VIDEO_SDL
|
||||
#elif defined(HAVE_DYLIB)
|
||||
#define VIDEO_DEFAULT_DRIVER VIDEO_EXT
|
||||
#else
|
||||
#error "Need at least one video driver."
|
||||
#endif
|
||||
|
||||
#if defined(__CELLOS_LV2__)
|
||||
#define AUDIO_DEFAULT_DRIVER AUDIO_PS3
|
||||
#elif defined(XENON)
|
||||
#define AUDIO_DEFAULT_DRIVER AUDIO_XENON360
|
||||
#elif defined(_XBOX)
|
||||
#define AUDIO_DEFAULT_DRIVER AUDIO_XDK360
|
||||
#elif defined(GEKKO)
|
||||
#define AUDIO_DEFAULT_DRIVER AUDIO_WII
|
||||
#elif defined(HAVE_ALSA)
|
||||
#define AUDIO_DEFAULT_DRIVER AUDIO_ALSA
|
||||
#elif defined(HAVE_PULSE)
|
||||
#define AUDIO_DEFAULT_DRIVER AUDIO_PULSE
|
||||
#elif defined(HAVE_OSS)
|
||||
#define AUDIO_DEFAULT_DRIVER AUDIO_OSS
|
||||
#elif defined(HAVE_JACK)
|
||||
#define AUDIO_DEFAULT_DRIVER AUDIO_JACK
|
||||
#elif defined(HAVE_COREAUDIO)
|
||||
#define AUDIO_DEFAULT_DRIVER AUDIO_COREAUDIO
|
||||
#elif defined(HAVE_AL)
|
||||
#define AUDIO_DEFAULT_DRIVER AUDIO_AL
|
||||
#elif defined(HAVE_DSOUND)
|
||||
#define AUDIO_DEFAULT_DRIVER AUDIO_DSOUND
|
||||
#elif defined(HAVE_SDL)
|
||||
#define AUDIO_DEFAULT_DRIVER AUDIO_SDL
|
||||
#elif defined(HAVE_XAUDIO)
|
||||
#define AUDIO_DEFAULT_DRIVER AUDIO_XAUDIO
|
||||
#elif defined(HAVE_RSOUND)
|
||||
#define AUDIO_DEFAULT_DRIVER AUDIO_RSOUND
|
||||
#elif defined(HAVE_ROAR)
|
||||
#define AUDIO_DEFAULT_DRIVER AUDIO_ROAR
|
||||
#elif defined(HAVE_DYLIB)
|
||||
#define AUDIO_DEFAULT_DRIVER AUDIO_EXT
|
||||
#else
|
||||
#error "Need at least one audio driver."
|
||||
#endif
|
||||
|
||||
#if defined(XENON)
|
||||
#define INPUT_DEFAULT_DRIVER INPUT_XENON360
|
||||
#elif defined(_XBOX)
|
||||
#define INPUT_DEFAULT_DRIVER INPUT_XDK360
|
||||
#elif defined(HAVE_SDL)
|
||||
#define INPUT_DEFAULT_DRIVER INPUT_SDL
|
||||
#elif defined(__CELLOS_LV2__)
|
||||
#define INPUT_DEFAULT_DRIVER INPUT_PS3
|
||||
#elif defined(GEKKO)
|
||||
#define INPUT_DEFAULT_DRIVER INPUT_WII
|
||||
#elif defined(HAVE_XVIDEO)
|
||||
#define INPUT_DEFAULT_DRIVER INPUT_X
|
||||
#else
|
||||
#error "Need at least one input driver."
|
||||
#endif
|
||||
|
||||
|
||||
////////////////
|
||||
@@ -83,13 +140,19 @@
|
||||
////////////////
|
||||
|
||||
// Windowed
|
||||
static const float xscale = 3.0; // Real x res = 296 * xscale
|
||||
static const float yscale = 3.0; // Real y res = 224 * yscale
|
||||
static const float xscale = 3.0; // Real x res = aspect * base_size * xscale
|
||||
static const float yscale = 3.0; // Real y res = base_size * yscale
|
||||
|
||||
// Fullscreen
|
||||
static const bool fullscreen = false; // To start in Fullscreen or not
|
||||
static const unsigned fullscreen_x = 1280;
|
||||
static const unsigned fullscreen_y = 720;
|
||||
static const unsigned fullscreen_x = 0; // Fullscreen resolution. A value of 0 uses the desktop resolution.
|
||||
static const unsigned fullscreen_y = 0;
|
||||
|
||||
// Force 16-bit colors.
|
||||
static const bool force_16bit = false;
|
||||
|
||||
// Forcibly disable composition. Only valid on Windows Vista/7 for now.
|
||||
static const bool disable_composition = false;
|
||||
|
||||
// Video VSYNC (recommended)
|
||||
static const bool vsync = true;
|
||||
@@ -100,14 +163,60 @@ static const bool video_smooth = true;
|
||||
// On resize and fullscreen, rendering area will stay 4:3
|
||||
static const bool force_aspect = true;
|
||||
|
||||
// Controls aspect ratio handling.
|
||||
static const float aspect_ratio = -1.0; // Automatic
|
||||
static const bool aspect_ratio_auto = false; // 1:1 PAR
|
||||
|
||||
// Crop overscanned frames (7/8 or 15/15 for interlaced frames).
|
||||
static const bool crop_overscan = true;
|
||||
|
||||
// Font size for on-screen messages.
|
||||
static const unsigned font_size = 48;
|
||||
// Attempt to scale the font size.
|
||||
// The scale factor will be window_size / desktop_size.
|
||||
static const bool font_scale = true;
|
||||
|
||||
// Offset for where messages will be placed on-screen. Values are in range [0.0, 1.0].
|
||||
static const float message_pos_offset_x = 0.05;
|
||||
static const float message_pos_offset_y = 0.05;
|
||||
// Color of the message.
|
||||
static const uint32_t message_color = 0xffff00; // RGB hex value.
|
||||
|
||||
#define SNES_ASPECT_RATIO (4.0/3)
|
||||
// Render-to-texture before rendering to screen (multi-pass shaders)
|
||||
static const bool render_to_texture = false;
|
||||
static const float fbo_scale_x = 2.0;
|
||||
static const float fbo_scale_y = 2.0;
|
||||
static const bool second_pass_smooth = true;
|
||||
|
||||
// Record video assuming game runs hi-res.
|
||||
static const bool hires_record = false;
|
||||
|
||||
// Enables lossless RGB H.264 recording if possible (if not, FFV1 is used).
|
||||
static const bool h264_record = true;
|
||||
|
||||
// Record post-filtered (CPU filter) video rather than raw SNES output.
|
||||
static const bool post_filter_record = false;
|
||||
|
||||
// OSD-messages
|
||||
static const bool font_enable = true;
|
||||
|
||||
// The accurate refresh rate of your monitor (Hz).
|
||||
// This is used to calculate audio input rate with the formula:
|
||||
// audio_input_rate = game_input_rate * display_refresh_rate / game_refresh_rate.
|
||||
// If the implementation does not report any values,
|
||||
// SNES NTSC defaults will be assumed for compatibility.
|
||||
// This value should stay close to 60Hz to avoid large pitch changes.
|
||||
// If your monitor does not run at 60Hz, or something close to it, disable VSync,
|
||||
// and leave this at its default.
|
||||
#if defined(__CELLOS_LV2__) || defined(XENON) || defined(GEKKO)
|
||||
static const float refresh_rate = 59.92;
|
||||
#else
|
||||
static const float refresh_rate = 59.95;
|
||||
#endif
|
||||
|
||||
// Allow games to set rotation. If false, rotation requests are honored, but ignored.
|
||||
// Used for setups where one manually rotates the monitor.
|
||||
static const bool allow_rotate = true;
|
||||
|
||||
////////////////
|
||||
// Audio
|
||||
@@ -119,12 +228,11 @@ static const bool audio_enable = true;
|
||||
// Output samplerate
|
||||
static const unsigned out_rate = 48000;
|
||||
|
||||
// Input samplerate from libSNES.
|
||||
// Lower this (slightly) if you are experiencing frequent audio dropouts while vsync is enabled.
|
||||
static const unsigned in_rate = 31980;
|
||||
// When changing input rate on-the-fly
|
||||
static const float audio_rate_step = 0.25;
|
||||
|
||||
// Audio device (e.g. hw:0,0 or /dev/audio). If NULL, will use defaults.
|
||||
static const char* audio_device = NULL;
|
||||
static const char *audio_device = NULL;
|
||||
|
||||
// Desired audio latency in milliseconds. Might not be honored if driver can't provide given latency.
|
||||
static const int out_latency = 64;
|
||||
@@ -132,10 +240,54 @@ static const int out_latency = 64;
|
||||
// Will sync audio. (recommended)
|
||||
static const bool audio_sync = true;
|
||||
|
||||
// Defines the quality (and cpu reqirements) of samplerate conversion.
|
||||
#define SAMPLERATE_QUALITY SRC_LINEAR
|
||||
// Experimental rate control
|
||||
static const bool rate_control = false;
|
||||
|
||||
// Rate control delta. Defines how much rate_control is allowed to adjust input rate.
|
||||
static const float rate_control_delta = 0.005;
|
||||
|
||||
//////////////
|
||||
// Misc
|
||||
//////////////
|
||||
|
||||
// Enables use of rewind. This will incur some memory footprint depending on the save state buffer.
|
||||
// This rewind only works when using bSNES core atm.
|
||||
static const bool rewind_enable = false;
|
||||
|
||||
// The buffer size for the rewind buffer. This needs to be about 15-20MB per minute. Very game dependant.
|
||||
static const unsigned rewind_buffer_size = 20 << 20; // 20MiB
|
||||
|
||||
// How many frames to rewind at a time.
|
||||
static const unsigned rewind_granularity = 1;
|
||||
|
||||
// Pause gameplay when gameplay loses focus.
|
||||
static const bool pause_nonactive = false;
|
||||
|
||||
// Saves non-volatile SRAM at a regular interval. It is measured in seconds. A value of 0 disables autosave.
|
||||
static const unsigned autosave_interval = 0;
|
||||
|
||||
// When being client over netplay, use keybinds for player 1 rather than player 2.
|
||||
static const bool netplay_client_swap_input = true;
|
||||
|
||||
// On save state load, block SRAM from being overwritten.
|
||||
// This could potentially lead to buggy games.
|
||||
static const bool block_sram_overwrite = false;
|
||||
|
||||
// When saving savestates, state index is automatically incremented before saving.
|
||||
// When the ROM is loaded, state index will be set to the highest existing value.
|
||||
static const bool savestate_auto_index = false;
|
||||
|
||||
// Automatically saves a savestate at the end of RetroArch's lifetime.
|
||||
// The path is $SRAM_PATH.auto.
|
||||
// RetroArch will automatically load any savestate with this path on startup.
|
||||
static const bool savestate_auto_save = false;
|
||||
|
||||
// Slowmotion ratio.
|
||||
static const float slowmotion_ratio = 3.0;
|
||||
|
||||
// Enable network command interface
|
||||
static const bool network_cmd_enable = false;
|
||||
static const uint16_t network_cmd_port = 55355;
|
||||
|
||||
|
||||
////////////////////
|
||||
@@ -144,106 +296,76 @@ static const bool audio_sync = true;
|
||||
|
||||
// Axis threshold (between 0.0 and 1.0)
|
||||
// How far an axis must be tilted to result in a button press
|
||||
#define AXIS_THRESHOLD 0.5
|
||||
static const float axis_threshold = 0.5;
|
||||
|
||||
// To figure out which joypad buttons to use, check jstest or similar.
|
||||
// SDL sometimes reverses the axes for some odd reason, but hey. :D
|
||||
|
||||
// Player 1
|
||||
static const struct snes_keybind snes_keybinds_1[] = {
|
||||
// SNES button | keyboard key | js btn | js axis |
|
||||
{ SNES_DEVICE_ID_JOYPAD_A, SDLK_x, 1, AXIS_NONE },
|
||||
{ SNES_DEVICE_ID_JOYPAD_B, SDLK_z, 0, AXIS_NONE },
|
||||
{ SNES_DEVICE_ID_JOYPAD_X, SDLK_s, 3, AXIS_NONE },
|
||||
{ SNES_DEVICE_ID_JOYPAD_Y, SDLK_a, 2, AXIS_NONE },
|
||||
{ SNES_DEVICE_ID_JOYPAD_L, SDLK_q, 4, AXIS_NONE },
|
||||
{ SNES_DEVICE_ID_JOYPAD_R, SDLK_w, 5, AXIS_NONE },
|
||||
{ SNES_DEVICE_ID_JOYPAD_LEFT, SDLK_LEFT, 11, AXIS_NEG(0) },
|
||||
{ SNES_DEVICE_ID_JOYPAD_RIGHT, SDLK_RIGHT, 12, AXIS_POS(0) },
|
||||
{ SNES_DEVICE_ID_JOYPAD_UP, SDLK_UP, 13, AXIS_NEG(1) },
|
||||
{ SNES_DEVICE_ID_JOYPAD_DOWN, SDLK_DOWN, 14, AXIS_POS(1) },
|
||||
{ SNES_DEVICE_ID_JOYPAD_START, SDLK_RETURN, 7, AXIS_NONE },
|
||||
{ SNES_DEVICE_ID_JOYPAD_SELECT, SDLK_RSHIFT, 6, AXIS_NONE },
|
||||
{ SSNES_FAST_FORWARD_KEY, SDLK_SPACE, 10, AXIS_NONE },
|
||||
{ SSNES_SAVE_STATE_KEY, SDLK_F2, NO_BTN, AXIS_NONE },
|
||||
{ SSNES_LOAD_STATE_KEY, SDLK_F4, NO_BTN, AXIS_NONE },
|
||||
{ SSNES_FULLSCREEN_TOGGLE_KEY, SDLK_f, NO_BTN, AXIS_NONE },
|
||||
{ SSNES_QUIT_KEY, SDLK_ESCAPE, NO_BTN, AXIS_NONE },
|
||||
{ SSNES_STATE_SLOT_MINUS, SDLK_F6, NO_BTN, AXIS_NONE },
|
||||
{ SSNES_STATE_SLOT_PLUS, SDLK_F7, NO_BTN, AXIS_NONE },
|
||||
{ -1 }
|
||||
// SNES button | keyboard key | js btn | js axis |
|
||||
{ true, RETRO_DEVICE_ID_JOYPAD_B, SK_z, NO_BTN, AXIS_NONE },
|
||||
{ true, RETRO_DEVICE_ID_JOYPAD_Y, SK_a, NO_BTN, AXIS_NONE },
|
||||
{ true, RETRO_DEVICE_ID_JOYPAD_SELECT, SK_RSHIFT, NO_BTN, AXIS_NONE },
|
||||
{ true, RETRO_DEVICE_ID_JOYPAD_START, SK_RETURN, NO_BTN, AXIS_NONE },
|
||||
{ true, RETRO_DEVICE_ID_JOYPAD_UP, SK_UP, NO_BTN, AXIS_NONE },
|
||||
{ true, RETRO_DEVICE_ID_JOYPAD_DOWN, SK_DOWN, NO_BTN, AXIS_NONE },
|
||||
{ true, RETRO_DEVICE_ID_JOYPAD_LEFT, SK_LEFT, NO_BTN, AXIS_NONE },
|
||||
{ true, RETRO_DEVICE_ID_JOYPAD_RIGHT, SK_RIGHT, NO_BTN, AXIS_NONE },
|
||||
{ true, RETRO_DEVICE_ID_JOYPAD_A, SK_x, NO_BTN, AXIS_NONE },
|
||||
{ true, RETRO_DEVICE_ID_JOYPAD_X, SK_s, NO_BTN, AXIS_NONE },
|
||||
{ true, RETRO_DEVICE_ID_JOYPAD_L, SK_q, NO_BTN, AXIS_NONE },
|
||||
{ true, RETRO_DEVICE_ID_JOYPAD_R, SK_w, NO_BTN, AXIS_NONE },
|
||||
{ true, RETRO_DEVICE_ID_JOYPAD_L2, SK_UNKNOWN, NO_BTN, AXIS_NONE },
|
||||
{ true, RETRO_DEVICE_ID_JOYPAD_R2, SK_UNKNOWN, NO_BTN, AXIS_NONE },
|
||||
{ true, RETRO_DEVICE_ID_JOYPAD_L3, SK_UNKNOWN, NO_BTN, AXIS_NONE },
|
||||
{ true, RETRO_DEVICE_ID_JOYPAD_R3, SK_UNKNOWN, NO_BTN, AXIS_NONE },
|
||||
|
||||
{ true, RARCH_FAST_FORWARD_KEY, SK_SPACE, NO_BTN, AXIS_NONE },
|
||||
{ true, RARCH_FAST_FORWARD_HOLD_KEY, SK_l, NO_BTN, AXIS_NONE },
|
||||
{ true, RARCH_LOAD_STATE_KEY, SK_F4, NO_BTN, AXIS_NONE },
|
||||
{ true, RARCH_SAVE_STATE_KEY, SK_F2, NO_BTN, AXIS_NONE },
|
||||
{ true, RARCH_FULLSCREEN_TOGGLE_KEY, SK_f, NO_BTN, AXIS_NONE },
|
||||
{ true, RARCH_QUIT_KEY, SK_ESCAPE, NO_BTN, AXIS_NONE },
|
||||
{ true, RARCH_STATE_SLOT_PLUS, SK_F7, NO_BTN, AXIS_NONE },
|
||||
{ true, RARCH_STATE_SLOT_MINUS, SK_F6, NO_BTN, AXIS_NONE },
|
||||
{ true, RARCH_AUDIO_INPUT_RATE_PLUS, SK_KP_PLUS, NO_BTN, AXIS_NONE },
|
||||
{ true, RARCH_AUDIO_INPUT_RATE_MINUS, SK_KP_MINUS, NO_BTN, AXIS_NONE },
|
||||
{ true, RARCH_REWIND, SK_r, NO_BTN, AXIS_NONE },
|
||||
{ true, RARCH_MOVIE_RECORD_TOGGLE, SK_o, NO_BTN, AXIS_NONE },
|
||||
{ true, RARCH_PAUSE_TOGGLE, SK_p, NO_BTN, AXIS_NONE },
|
||||
{ true, RARCH_FRAMEADVANCE, SK_k, NO_BTN, AXIS_NONE },
|
||||
{ true, RARCH_RESET, SK_h, NO_BTN, AXIS_NONE },
|
||||
{ true, RARCH_SHADER_NEXT, SK_m, NO_BTN, AXIS_NONE },
|
||||
{ true, RARCH_SHADER_PREV, SK_n, NO_BTN, AXIS_NONE },
|
||||
{ true, RARCH_CHEAT_INDEX_PLUS, SK_y, NO_BTN, AXIS_NONE },
|
||||
{ true, RARCH_CHEAT_INDEX_MINUS, SK_t, NO_BTN, AXIS_NONE },
|
||||
{ true, RARCH_CHEAT_TOGGLE, SK_u, NO_BTN, AXIS_NONE },
|
||||
{ true, RARCH_SCREENSHOT, SK_PRINT, NO_BTN, AXIS_NONE },
|
||||
{ true, RARCH_DSP_CONFIG, SK_c, NO_BTN, AXIS_NONE },
|
||||
{ true, RARCH_MUTE, SK_F9, NO_BTN, AXIS_NONE },
|
||||
{ true, RARCH_NETPLAY_FLIP, SK_i, NO_BTN, AXIS_NONE },
|
||||
{ true, RARCH_SLOWMOTION, SK_e, NO_BTN, AXIS_NONE },
|
||||
};
|
||||
|
||||
// Player 2
|
||||
static const struct snes_keybind snes_keybinds_2[] = {
|
||||
// SNES button | keyboard key | js btn | js axis |
|
||||
{ SNES_DEVICE_ID_JOYPAD_A, SDLK_b, 1, AXIS_NONE },
|
||||
{ SNES_DEVICE_ID_JOYPAD_B, SDLK_v, 0, AXIS_NONE },
|
||||
{ SNES_DEVICE_ID_JOYPAD_X, SDLK_g, 3, AXIS_NONE },
|
||||
{ SNES_DEVICE_ID_JOYPAD_Y, SDLK_f, 2, AXIS_NONE },
|
||||
{ SNES_DEVICE_ID_JOYPAD_L, SDLK_r, 4, AXIS_NONE },
|
||||
{ SNES_DEVICE_ID_JOYPAD_R, SDLK_t, 5, AXIS_NONE },
|
||||
{ SNES_DEVICE_ID_JOYPAD_LEFT, SDLK_j, 11, AXIS_NEG(0) },
|
||||
{ SNES_DEVICE_ID_JOYPAD_RIGHT, SDLK_l, 12, AXIS_POS(0) },
|
||||
{ SNES_DEVICE_ID_JOYPAD_UP, SDLK_i, 13, AXIS_NEG(1) },
|
||||
{ SNES_DEVICE_ID_JOYPAD_DOWN, SDLK_k, 14, AXIS_POS(1) },
|
||||
{ SNES_DEVICE_ID_JOYPAD_START, SDLK_p, 6, AXIS_NONE },
|
||||
{ SNES_DEVICE_ID_JOYPAD_SELECT, SDLK_o, 7, AXIS_NONE },
|
||||
{ -1 }
|
||||
};
|
||||
|
||||
// Player 3
|
||||
static const struct snes_keybind snes_keybinds_3[] = {
|
||||
// SNES button | keyboard key | js btn | js axis |
|
||||
{ SNES_DEVICE_ID_JOYPAD_A, SDLK_b, 1, AXIS_NONE },
|
||||
{ SNES_DEVICE_ID_JOYPAD_B, SDLK_v, 0, AXIS_NONE },
|
||||
{ SNES_DEVICE_ID_JOYPAD_X, SDLK_g, 3, AXIS_NONE },
|
||||
{ SNES_DEVICE_ID_JOYPAD_Y, SDLK_f, 2, AXIS_NONE },
|
||||
{ SNES_DEVICE_ID_JOYPAD_L, SDLK_r, 4, AXIS_NONE },
|
||||
{ SNES_DEVICE_ID_JOYPAD_R, SDLK_t, 5, AXIS_NONE },
|
||||
{ SNES_DEVICE_ID_JOYPAD_LEFT, SDLK_j, 11, AXIS_NEG(0) },
|
||||
{ SNES_DEVICE_ID_JOYPAD_RIGHT, SDLK_l, 12, AXIS_POS(0) },
|
||||
{ SNES_DEVICE_ID_JOYPAD_UP, SDLK_i, 13, AXIS_NEG(1) },
|
||||
{ SNES_DEVICE_ID_JOYPAD_DOWN, SDLK_k, 14, AXIS_POS(1) },
|
||||
{ SNES_DEVICE_ID_JOYPAD_START, SDLK_p, 6, AXIS_NONE },
|
||||
{ SNES_DEVICE_ID_JOYPAD_SELECT, SDLK_o, 7, AXIS_NONE },
|
||||
{ -1 }
|
||||
};
|
||||
|
||||
// Player 4
|
||||
static const struct snes_keybind snes_keybinds_4[] = {
|
||||
// SNES button | keyboard key | js btn | js axis |
|
||||
{ SNES_DEVICE_ID_JOYPAD_A, SDLK_b, 1, AXIS_NONE },
|
||||
{ SNES_DEVICE_ID_JOYPAD_B, SDLK_v, 0, AXIS_NONE },
|
||||
{ SNES_DEVICE_ID_JOYPAD_X, SDLK_g, 3, AXIS_NONE },
|
||||
{ SNES_DEVICE_ID_JOYPAD_Y, SDLK_f, 2, AXIS_NONE },
|
||||
{ SNES_DEVICE_ID_JOYPAD_L, SDLK_r, 4, AXIS_NONE },
|
||||
{ SNES_DEVICE_ID_JOYPAD_R, SDLK_t, 5, AXIS_NONE },
|
||||
{ SNES_DEVICE_ID_JOYPAD_LEFT, SDLK_j, 11, AXIS_NEG(0) },
|
||||
{ SNES_DEVICE_ID_JOYPAD_RIGHT, SDLK_l, 12, AXIS_POS(0) },
|
||||
{ SNES_DEVICE_ID_JOYPAD_UP, SDLK_i, 13, AXIS_NEG(1) },
|
||||
{ SNES_DEVICE_ID_JOYPAD_DOWN, SDLK_k, 14, AXIS_POS(1) },
|
||||
{ SNES_DEVICE_ID_JOYPAD_START, SDLK_p, 6, AXIS_NONE },
|
||||
{ SNES_DEVICE_ID_JOYPAD_SELECT, SDLK_o, 7, AXIS_NONE },
|
||||
{ -1 }
|
||||
};
|
||||
|
||||
// Player 5
|
||||
static const struct snes_keybind snes_keybinds_5[] = {
|
||||
// SNES button | keyboard key | js btn | js axis |
|
||||
{ SNES_DEVICE_ID_JOYPAD_A, SDLK_b, 1, AXIS_NONE },
|
||||
{ SNES_DEVICE_ID_JOYPAD_B, SDLK_v, 0, AXIS_NONE },
|
||||
{ SNES_DEVICE_ID_JOYPAD_X, SDLK_g, 3, AXIS_NONE },
|
||||
{ SNES_DEVICE_ID_JOYPAD_Y, SDLK_f, 2, AXIS_NONE },
|
||||
{ SNES_DEVICE_ID_JOYPAD_L, SDLK_r, 4, AXIS_NONE },
|
||||
{ SNES_DEVICE_ID_JOYPAD_R, SDLK_t, 5, AXIS_NONE },
|
||||
{ SNES_DEVICE_ID_JOYPAD_LEFT, SDLK_j, 11, AXIS_NEG(0) },
|
||||
{ SNES_DEVICE_ID_JOYPAD_RIGHT, SDLK_l, 12, AXIS_POS(0) },
|
||||
{ SNES_DEVICE_ID_JOYPAD_UP, SDLK_i, 13, AXIS_NEG(1) },
|
||||
{ SNES_DEVICE_ID_JOYPAD_DOWN, SDLK_k, 14, AXIS_POS(1) },
|
||||
{ SNES_DEVICE_ID_JOYPAD_START, SDLK_p, 6, AXIS_NONE },
|
||||
{ SNES_DEVICE_ID_JOYPAD_SELECT, SDLK_o, 7, AXIS_NONE },
|
||||
{ -1 }
|
||||
// Player 2-5
|
||||
static const struct snes_keybind snes_keybinds_rest[] = {
|
||||
{ true, RETRO_DEVICE_ID_JOYPAD_B, SK_UNKNOWN, NO_BTN, AXIS_NONE },
|
||||
{ true, RETRO_DEVICE_ID_JOYPAD_Y, SK_UNKNOWN, NO_BTN, AXIS_NONE },
|
||||
{ true, RETRO_DEVICE_ID_JOYPAD_SELECT, SK_UNKNOWN, NO_BTN, AXIS_NONE },
|
||||
{ true, RETRO_DEVICE_ID_JOYPAD_START, SK_UNKNOWN, NO_BTN, AXIS_NONE },
|
||||
{ true, RETRO_DEVICE_ID_JOYPAD_UP, SK_UNKNOWN, NO_BTN, AXIS_NONE },
|
||||
{ true, RETRO_DEVICE_ID_JOYPAD_DOWN, SK_UNKNOWN, NO_BTN, AXIS_NONE },
|
||||
{ true, RETRO_DEVICE_ID_JOYPAD_LEFT, SK_UNKNOWN, NO_BTN, AXIS_NONE },
|
||||
{ true, RETRO_DEVICE_ID_JOYPAD_RIGHT, SK_UNKNOWN, NO_BTN, AXIS_NONE },
|
||||
{ true, RETRO_DEVICE_ID_JOYPAD_A, SK_UNKNOWN, NO_BTN, AXIS_NONE },
|
||||
{ true, RETRO_DEVICE_ID_JOYPAD_X, SK_UNKNOWN, NO_BTN, AXIS_NONE },
|
||||
{ true, RETRO_DEVICE_ID_JOYPAD_L, SK_UNKNOWN, NO_BTN, AXIS_NONE },
|
||||
{ true, RETRO_DEVICE_ID_JOYPAD_R, SK_UNKNOWN, NO_BTN, AXIS_NONE },
|
||||
{ true, RETRO_DEVICE_ID_JOYPAD_L2, SK_UNKNOWN, NO_BTN, AXIS_NONE },
|
||||
{ true, RETRO_DEVICE_ID_JOYPAD_R2, SK_UNKNOWN, NO_BTN, AXIS_NONE },
|
||||
{ true, RETRO_DEVICE_ID_JOYPAD_L3, SK_UNKNOWN, NO_BTN, AXIS_NONE },
|
||||
{ true, RETRO_DEVICE_ID_JOYPAD_R3, SK_UNKNOWN, NO_BTN, AXIS_NONE },
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
+70
-10
@@ -1,8 +1,8 @@
|
||||
#ifndef __SSNES_FEATURES_H
|
||||
#define __SSNES_FEATURES_H
|
||||
#ifndef __RARCH_FEATURES_H
|
||||
#define __RARCH_FEATURES_H
|
||||
|
||||
#include <stddef.h>
|
||||
#include <stdbool.h>
|
||||
#include "boolean.h"
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
#include "config.h"
|
||||
@@ -14,13 +14,31 @@ static const bool _sdl_supp = true;
|
||||
static const bool _sdl_supp = false;
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_THREADS
|
||||
static const bool _thread_supp = true;
|
||||
#else
|
||||
static const bool _thread_supp = false;
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_OPENGL
|
||||
static const bool _opengl_supp = true;
|
||||
#else
|
||||
static const bool _opengl_supp = false;
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_XVIDEO
|
||||
static const bool _xvideo_supp = true;
|
||||
#else
|
||||
static const bool _xvideo_supp = false;
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_ALSA
|
||||
static const bool _alsa_supp = true;
|
||||
#else
|
||||
static const bool _alsa_supp = false;
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_OSS
|
||||
#if defined(HAVE_OSS) || defined(HAVE_OSS_BSD)
|
||||
static const bool _oss_supp = true;
|
||||
#else
|
||||
static const bool _oss_supp = false;
|
||||
@@ -50,10 +68,28 @@ static const bool _jack_supp = true;
|
||||
static const bool _jack_supp = false;
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_FILTER
|
||||
static const bool _filter_supp = true;
|
||||
#ifdef HAVE_PULSE
|
||||
static const bool _pulse_supp = true;
|
||||
#else
|
||||
static const bool _filter_supp = false;
|
||||
static const bool _pulse_supp = false;
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_DSOUND
|
||||
static const bool _dsound_supp = true;
|
||||
#else
|
||||
static const bool _dsound_supp = false;
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_XAUDIO
|
||||
static const bool _xaudio_supp = true;
|
||||
#else
|
||||
static const bool _xaudio_supp = false;
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_DYLIB
|
||||
static const bool _dylib_supp = true;
|
||||
#else
|
||||
static const bool _dylib_supp = false;
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_CG
|
||||
@@ -68,6 +104,18 @@ static const bool _xml_supp = true;
|
||||
static const bool _xml_supp = false;
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_SDL_IMAGE
|
||||
static const bool _sdl_image_supp = true;
|
||||
#else
|
||||
static const bool _sdl_image_supp = false;
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_FBO
|
||||
static const bool _fbo_supp = true;
|
||||
#else
|
||||
static const bool _fbo_supp = false;
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_DYNAMIC
|
||||
static const bool _dynamic_supp = true;
|
||||
#else
|
||||
@@ -80,10 +128,10 @@ static const bool _ffmpeg_supp = true;
|
||||
static const bool _ffmpeg_supp = false;
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_SRC
|
||||
static const bool _src_supp = true;
|
||||
#ifdef HAVE_X264RGB
|
||||
static const bool _x264rgb_supp = true;
|
||||
#else
|
||||
static const bool _src_supp = false;
|
||||
static const bool _x264rgb_supp = false;
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_CONFIGFILE
|
||||
@@ -98,4 +146,16 @@ static const bool _freetype_supp = true;
|
||||
static const bool _freetype_supp = false;
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_NETPLAY
|
||||
static const bool _netplay_supp = true;
|
||||
#else
|
||||
static const bool _netplay_supp = false;
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_PYTHON
|
||||
static const bool _python_supp = true;
|
||||
#else
|
||||
static const bool _python_supp = false;
|
||||
#endif
|
||||
|
||||
#endif
|
||||
@@ -2,9 +2,10 @@
|
||||
|
||||
echo ""
|
||||
|
||||
. qb/config.params.sh
|
||||
PACKAGE_NAME=retroarch
|
||||
PACKAGE_VERSION=0.9.6
|
||||
|
||||
parse_input "$@"
|
||||
. qb/qb.params.sh
|
||||
|
||||
. qb/qb.comp.sh
|
||||
. qb/config.libs.sh
|
||||
|
||||
@@ -0,0 +1,880 @@
|
||||
/* RetroArch - A frontend for libretro.
|
||||
* Copyright (C) 2010-2012 - Hans-Kristian Arntzen
|
||||
* Copyright (C) 2011-2012 - Daniel De Matteis
|
||||
*
|
||||
* RetroArch is free software: you can redistribute it and/or modify it under the terms
|
||||
* of the GNU General Public License as published by the Free Software Found-
|
||||
* ation, either version 3 of the License, or (at your option) any later version.
|
||||
*
|
||||
* RetroArch is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
|
||||
* without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
|
||||
* PURPOSE. See the GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along with RetroArch.
|
||||
* If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <stddef.h>
|
||||
#include <string.h>
|
||||
#include <ctype.h>
|
||||
#include "../boolean.h"
|
||||
#include "../compat/strl.h"
|
||||
#include "../libretro.h"
|
||||
#include "../general.h"
|
||||
#include "../compat/strl.h"
|
||||
#include "console_ext.h"
|
||||
#include "../file.h"
|
||||
|
||||
#ifdef HAVE_CONFIGFILE
|
||||
#include "../conf/config_file.h"
|
||||
#include "../conf/config_file_macros.h"
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_ZLIB
|
||||
#include "rzlib/zlib.h"
|
||||
#define WRITEBUFFERSIZE (1024 * 512)
|
||||
#endif
|
||||
|
||||
#ifdef _WIN32
|
||||
#include "../compat/posix_string.h"
|
||||
#endif
|
||||
|
||||
#define MAX_ARGS 32
|
||||
|
||||
/*============================================================
|
||||
ROM EXTENSIONS
|
||||
============================================================ */
|
||||
|
||||
const char *rarch_console_get_rom_ext(void)
|
||||
{
|
||||
const char *retval = NULL;
|
||||
|
||||
struct retro_system_info info;
|
||||
retro_get_system_info(&info);
|
||||
|
||||
if (info.valid_extensions)
|
||||
retval = info.valid_extensions;
|
||||
else
|
||||
retval = "ZIP|zip";
|
||||
|
||||
return retval;
|
||||
}
|
||||
|
||||
void rarch_console_name_from_id(char *name, size_t size)
|
||||
{
|
||||
if (size == 0)
|
||||
return;
|
||||
|
||||
struct retro_system_info info;
|
||||
retro_get_system_info(&info);
|
||||
const char *id = info.library_name ? info.library_name : "Unknown";
|
||||
|
||||
if (!id || strlen(id) >= size)
|
||||
{
|
||||
name[0] = '\0';
|
||||
return;
|
||||
}
|
||||
|
||||
name[strlen(id)] = '\0';
|
||||
|
||||
for (size_t i = 0; id[i] != '\0'; i++)
|
||||
{
|
||||
char c = id[i];
|
||||
if (isspace(c) || isblank(c))
|
||||
name[i] = '_';
|
||||
else
|
||||
name[i] = tolower(c);
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef HAVE_ZLIB
|
||||
static int rarch_extract_currentfile_in_zip(unzFile uf)
|
||||
{
|
||||
char filename_inzip[PATH_MAX];
|
||||
FILE *fout = NULL;
|
||||
|
||||
unz_file_info file_info;
|
||||
int err = unzGetCurrentFileInfo(uf,
|
||||
&file_info, filename_inzip, sizeof(filename_inzip),
|
||||
NULL, 0, NULL, 0);
|
||||
|
||||
if (err != UNZ_OK)
|
||||
{
|
||||
RARCH_ERR("Error %d with ZIP file in unzGetCurrentFileInfo.\n", err);
|
||||
return err;
|
||||
}
|
||||
|
||||
size_t size_buf = WRITEBUFFERSIZE;
|
||||
void *buf = malloc(size_buf);
|
||||
if (!buf)
|
||||
{
|
||||
RARCH_ERR("Error allocating memory\n");
|
||||
return UNZ_INTERNALERROR;
|
||||
}
|
||||
|
||||
char write_filename[PATH_MAX];
|
||||
|
||||
#if defined(__CELLOS_LV2__)
|
||||
snprintf(write_filename, sizeof(write_filename), "/dev_hdd1/%s", filename_inzip);
|
||||
#elif defined(_XBOX)
|
||||
snprintf(write_filename, sizeof(write_filename), "cache:\\%s", filename_inzip);
|
||||
#endif
|
||||
|
||||
err = unzOpenCurrentFile(uf);
|
||||
if (err != UNZ_OK)
|
||||
RARCH_ERR("Error %d with ZIP file in unzOpenCurrentFile.\n", err);
|
||||
else
|
||||
{
|
||||
/* success */
|
||||
fout = fopen(write_filename, "wb");
|
||||
|
||||
if (!fout)
|
||||
RARCH_ERR("Error opening %s.\n", write_filename);
|
||||
}
|
||||
|
||||
if (fout)
|
||||
{
|
||||
RARCH_LOG("Extracting: %s\n", write_filename);
|
||||
|
||||
do
|
||||
{
|
||||
err = unzReadCurrentFile(uf, buf, size_buf);
|
||||
if (err < 0)
|
||||
{
|
||||
RARCH_ERR("error %d with ZIP file in unzReadCurrentFile.\n", err);
|
||||
break;
|
||||
}
|
||||
|
||||
if (err > 0)
|
||||
{
|
||||
if (fwrite(buf, err, 1, fout) != 1)
|
||||
{
|
||||
RARCH_ERR("Error in writing extracted file.\n");
|
||||
err = UNZ_ERRNO;
|
||||
break;
|
||||
}
|
||||
}
|
||||
} while (err > 0);
|
||||
|
||||
if (fout)
|
||||
fclose(fout);
|
||||
}
|
||||
|
||||
if (err == UNZ_OK)
|
||||
{
|
||||
err = unzCloseCurrentFile (uf);
|
||||
if (err != UNZ_OK)
|
||||
RARCH_ERR("Error %d with ZIP file in unzCloseCurrentFile.\n", err);
|
||||
}
|
||||
else
|
||||
unzCloseCurrentFile(uf);
|
||||
|
||||
free(buf);
|
||||
return err;
|
||||
}
|
||||
|
||||
int rarch_extract_zipfile(const char *zip_path)
|
||||
{
|
||||
unzFile uf = unzOpen(zip_path);
|
||||
|
||||
unz_global_info gi;
|
||||
int err = unzGetGlobalInfo(uf, &gi);
|
||||
if (err != UNZ_OK)
|
||||
RARCH_ERR("error %d with ZIP file in unzGetGlobalInfo \n",err);
|
||||
|
||||
for (unsigned i = 0; i < gi.number_entry; i++)
|
||||
{
|
||||
if (rarch_extract_currentfile_in_zip(uf) != UNZ_OK)
|
||||
break;
|
||||
|
||||
if ((i + 1) < gi.number_entry)
|
||||
{
|
||||
err = unzGoToNextFile(uf);
|
||||
if (err != UNZ_OK)
|
||||
{
|
||||
RARCH_ERR("error %d with ZIP file in unzGoToNextFile\n",err);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if(g_console.info_msg_enable)
|
||||
rarch_settings_msg(S_MSG_EXTRACTED_ZIPFILE, S_DELAY_180);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
/*============================================================
|
||||
INPUT EXTENSIONS
|
||||
============================================================ */
|
||||
|
||||
#include "console_ext_input.h"
|
||||
|
||||
struct platform_bind
|
||||
{
|
||||
uint64_t joykey;
|
||||
const char *label;
|
||||
};
|
||||
|
||||
uint64_t rarch_default_keybind_lut[RARCH_FIRST_META_KEY];
|
||||
|
||||
char rarch_default_libretro_keybind_name_lut[RARCH_FIRST_META_KEY][256] = {
|
||||
"RetroPad Button B", /* RETRO_DEVICE_ID_JOYPAD_B */
|
||||
"RetroPad Button Y", /* RETRO_DEVICE_ID_JOYPAD_Y */
|
||||
"RetroPad Button Select", /* RETRO_DEVICE_ID_JOYPAD_SELECT */
|
||||
"RetroPad Button Start", /* RETRO_DEVICE_ID_JOYPAD_START */
|
||||
"RetroPad D-Pad Up", /* RETRO_DEVICE_ID_JOYPAD_UP */
|
||||
"RetroPad D-Pad Down", /* RETRO_DEVICE_ID_JOYPAD_DOWN */
|
||||
"RetroPad D-Pad Left", /* RETRO_DEVICE_ID_JOYPAD_LEFT */
|
||||
"RetroPad D-Pad Right", /* RETRO_DEVICE_ID_JOYPAD_RIGHT */
|
||||
"RetroPad Button A", /* RETRO_DEVICE_ID_JOYPAD_A */
|
||||
"RetroPad Button X", /* RETRO_DEVICE_ID_JOYPAD_X */
|
||||
"RetroPad Button L1", /* RETRO_DEVICE_ID_JOYPAD_L */
|
||||
"RetroPad Button R1", /* RETRO_DEVICE_ID_JOYPAD_R */
|
||||
"RetroPad Button L2", /* RETRO_DEVICE_ID_JOYPAD_L2 */
|
||||
"RetroPad Button R2", /* RETRO_DEVICE_ID_JOYPAD_R2 */
|
||||
"RetroPad Button L3", /* RETRO_DEVICE_ID_JOYPAD_L3 */
|
||||
"RetroPad Button R3", /* RETRO_DEVICE_ID_JOYPAD_R3 */
|
||||
};
|
||||
|
||||
#if defined(__CELLOS_LV2__)
|
||||
static const struct platform_bind platform_keys[] = {
|
||||
{ CTRL_CIRCLE_MASK, "Circle button" },
|
||||
{ CTRL_CROSS_MASK, "Cross button" },
|
||||
{ CTRL_TRIANGLE_MASK, "Triangle button" },
|
||||
{ CTRL_SQUARE_MASK, "Square button" },
|
||||
{ CTRL_UP_MASK, "D-Pad Up" },
|
||||
{ CTRL_DOWN_MASK, "D-Pad Down" },
|
||||
{ CTRL_LEFT_MASK, "D-Pad Left" },
|
||||
{ CTRL_RIGHT_MASK, "D-Pad Right" },
|
||||
{ CTRL_SELECT_MASK, "Select button" },
|
||||
{ CTRL_START_MASK, "Start button" },
|
||||
{ CTRL_L1_MASK, "L1 button" },
|
||||
{ CTRL_L2_MASK, "L2 button" },
|
||||
{ CTRL_L3_MASK, "L3 button" },
|
||||
{ CTRL_R1_MASK, "R1 button" },
|
||||
{ CTRL_R2_MASK, "R2 button" },
|
||||
{ CTRL_R3_MASK, "R3 button" },
|
||||
{ CTRL_LSTICK_LEFT_MASK, "LStick Left" },
|
||||
{ CTRL_LSTICK_RIGHT_MASK, "LStick Right" },
|
||||
{ CTRL_LSTICK_UP_MASK, "LStick Up" },
|
||||
{ CTRL_LSTICK_DOWN_MASK, "LStick Down" },
|
||||
{ CTRL_LEFT_MASK | CTRL_LSTICK_LEFT_MASK, "LStick D-Pad Left" },
|
||||
{ CTRL_RIGHT_MASK | CTRL_LSTICK_RIGHT_MASK, "LStick D-Pad Right" },
|
||||
{ CTRL_UP_MASK | CTRL_LSTICK_UP_MASK, "LStick D-Pad Up" },
|
||||
{ CTRL_DOWN_MASK | CTRL_LSTICK_DOWN_MASK, "LStick D-Pad Down" },
|
||||
{ CTRL_RSTICK_LEFT_MASK, "RStick Left" },
|
||||
{ CTRL_RSTICK_RIGHT_MASK, "RStick Right" },
|
||||
{ CTRL_RSTICK_UP_MASK, "RStick Up" },
|
||||
{ CTRL_RSTICK_DOWN_MASK, "RStick Down" },
|
||||
{ CTRL_LEFT_MASK | CTRL_RSTICK_LEFT_MASK, "RStick D-Pad Left" },
|
||||
{ CTRL_RIGHT_MASK | CTRL_RSTICK_RIGHT_MASK, "RStick D-Pad Right" },
|
||||
{ CTRL_UP_MASK | CTRL_RSTICK_UP_MASK, "RStick D-Pad Up" },
|
||||
{ CTRL_DOWN_MASK | CTRL_RSTICK_DOWN_MASK, "RStick D-Pad Down" },
|
||||
};
|
||||
#elif defined(_XBOX)
|
||||
static const struct platform_bind platform_keys[] = {
|
||||
{ XINPUT_GAMEPAD_B, "B button" },
|
||||
{ XINPUT_GAMEPAD_A, "A button" },
|
||||
{ XINPUT_GAMEPAD_Y, "Y button" },
|
||||
{ XINPUT_GAMEPAD_X, "X button" },
|
||||
{ XINPUT_GAMEPAD_DPAD_UP, "D-Pad Up" },
|
||||
{ XINPUT_GAMEPAD_DPAD_DOWN, "D-Pad Down" },
|
||||
{ XINPUT_GAMEPAD_DPAD_LEFT, "D-Pad Left" },
|
||||
{ XINPUT_GAMEPAD_DPAD_RIGHT, "D-Pad Right" },
|
||||
{ XINPUT_GAMEPAD_BACK, "Back button" },
|
||||
{ XINPUT_GAMEPAD_START, "Start button" },
|
||||
{ XINPUT_GAMEPAD_LEFT_SHOULDER, "Left Shoulder" },
|
||||
{ XINPUT_GAMEPAD_LEFT_TRIGGER, "Left Trigger" },
|
||||
{ XINPUT_GAMEPAD_LEFT_THUMB, "Left Thumb" },
|
||||
{ XINPUT_GAMEPAD_RIGHT_SHOULDER, "Right Shoulder" },
|
||||
{ XINPUT_GAMEPAD_RIGHT_TRIGGER, "Right Trigger" },
|
||||
{ XINPUT_GAMEPAD_RIGHT_THUMB, "Right Thumb" },
|
||||
{ XINPUT_GAMEPAD_LSTICK_LEFT_MASK, "LStick Left" },
|
||||
{ XINPUT_GAMEPAD_LSTICK_RIGHT_MASK, "LStick Right" },
|
||||
{ XINPUT_GAMEPAD_LSTICK_UP_MASK, "LStick Up" },
|
||||
{ XINPUT_GAMEPAD_LSTICK_DOWN_MASK, "LStick Down" },
|
||||
{ XINPUT_GAMEPAD_DPAD_LEFT | XINPUT_GAMEPAD_LSTICK_LEFT_MASK, "LStick D-Pad Left" },
|
||||
{ XINPUT_GAMEPAD_DPAD_RIGHT | XINPUT_GAMEPAD_LSTICK_RIGHT_MASK, "LStick D-Pad Right" },
|
||||
{ XINPUT_GAMEPAD_DPAD_UP | XINPUT_GAMEPAD_LSTICK_UP_MASK, "LStick D-Pad Up" },
|
||||
{ XINPUT_GAMEPAD_DPAD_DOWN | XINPUT_GAMEPAD_LSTICK_DOWN_MASK, "LStick D-Pad Down" },
|
||||
{ XINPUT_GAMEPAD_RSTICK_LEFT_MASK, "RStick Left" },
|
||||
{ XINPUT_GAMEPAD_RSTICK_RIGHT_MASK, "RStick Right" },
|
||||
{ XINPUT_GAMEPAD_RSTICK_UP_MASK, "RStick Up" },
|
||||
{ XINPUT_GAMEPAD_RSTICK_DOWN_MASK, "RStick Down" },
|
||||
{ XINPUT_GAMEPAD_DPAD_LEFT | XINPUT_GAMEPAD_RSTICK_LEFT_MASK, "RStick D-Pad Left" },
|
||||
{ XINPUT_GAMEPAD_DPAD_RIGHT | XINPUT_GAMEPAD_RSTICK_RIGHT_MASK, "RStick D-Pad Right" },
|
||||
{ XINPUT_GAMEPAD_DPAD_UP | XINPUT_GAMEPAD_RSTICK_UP_MASK, "RStick D-Pad Up" },
|
||||
{ XINPUT_GAMEPAD_DPAD_DOWN | XINPUT_GAMEPAD_RSTICK_DOWN_MASK, "RStick D-Pad Down" },
|
||||
};
|
||||
#elif defined(GEKKO)
|
||||
static const struct platform_bind platform_keys[] = {
|
||||
{ PAD_BUTTON_B, "(NGC) B button" },
|
||||
{ PAD_BUTTON_A, "(NGC) A button" },
|
||||
{ PAD_BUTTON_Y, "(NGC) Y button" },
|
||||
{ PAD_BUTTON_X, "(NGC) X button" },
|
||||
{ PAD_BUTTON_UP, "(NGC) D-Pad Up" },
|
||||
{ PAD_BUTTON_DOWN, "(NGC) D-Pad Down" },
|
||||
{ PAD_BUTTON_LEFT, "(NGC) D-Pad Left" },
|
||||
{ PAD_BUTTON_RIGHT, "(NGC) D-Pad Right" },
|
||||
{ PAD_TRIGGER_Z, "(NGC) Z trigger" },
|
||||
{ PAD_BUTTON_START, "(NGC) Start button" },
|
||||
{ PAD_TRIGGER_L, "(NGC) Left Trigger" },
|
||||
{ PAD_TRIGGER_R, "(NGC) Right Trigger" },
|
||||
//{ XINPUT_GAMEPAD_LSTICK_LEFT_MASK, "LStick Left" },
|
||||
//{ XINPUT_GAMEPAD_LSTICK_RIGHT_MASK, "LStick Right" },
|
||||
//{ XINPUT_GAMEPAD_LSTICK_UP_MASK, "LStick Up" },
|
||||
//{ XINPUT_GAMEPAD_LSTICK_DOWN_MASK, "LStick Down" },
|
||||
//{ XINPUT_GAMEPAD_DPAD_LEFT | XINPUT_GAMEPAD_LSTICK_LEFT_MASK, "LStick D-Pad Left" },
|
||||
//{ XINPUT_GAMEPAD_DPAD_RIGHT | XINPUT_GAMEPAD_LSTICK_RIGHT_MASK, "LStick D-Pad Right" },
|
||||
//{ XINPUT_GAMEPAD_DPAD_UP | XINPUT_GAMEPAD_LSTICK_UP_MASK, "LStick D-Pad Up" },
|
||||
//{ XINPUT_GAMEPAD_DPAD_DOWN | XINPUT_GAMEPAD_LSTICK_DOWN_MASK, "LStick D-Pad Down" },
|
||||
//{ XINPUT_GAMEPAD_RSTICK_LEFT_MASK, "RStick Left" },
|
||||
//{ XINPUT_GAMEPAD_RSTICK_RIGHT_MASK, "RStick Right" },
|
||||
//{ XINPUT_GAMEPAD_RSTICK_UP_MASK, "RStick Up" },
|
||||
//{ XINPUT_GAMEPAD_RSTICK_DOWN_MASK, "RStick Down" },
|
||||
//{ XINPUT_GAMEPAD_DPAD_LEFT | XINPUT_GAMEPAD_RSTICK_LEFT_MASK, "RStick D-Pad Left" },
|
||||
//{ XINPUT_GAMEPAD_DPAD_RIGHT | XINPUT_GAMEPAD_RSTICK_RIGHT_MASK, "RStick D-Pad Right" },
|
||||
//{ XINPUT_GAMEPAD_DPAD_UP | XINPUT_GAMEPAD_RSTICK_UP_MASK, "RStick D-Pad Up" },
|
||||
//{ XINPUT_GAMEPAD_DPAD_DOWN | XINPUT_GAMEPAD_RSTICK_DOWN_MASK, "RStick D-Pad Down" },
|
||||
#ifdef HW_RVL
|
||||
{ WPAD_CLASSIC_BUTTON_B, "(Wii Classici) B button" },
|
||||
{ WPAD_CLASSIC_BUTTON_A, "(Wii Classic) A button" },
|
||||
{ WPAD_CLASSIC_BUTTON_Y, "(Wii Classic) Y button" },
|
||||
{ WPAD_CLASSIC_BUTTON_X, "(Wii Classic) X button" },
|
||||
{ WPAD_CLASSIC_BUTTON_UP, "(Wii Classic) D-Pad Up" },
|
||||
{ WPAD_CLASSIC_BUTTON_DOWN, "(Wii Classic) D-Pad Down" },
|
||||
{ WPAD_CLASSIC_BUTTON_LEFT, "(Wii Classic) D-Pad Left" },
|
||||
{ WPAD_CLASSIC_BUTTON_RIGHT, "(Wii Classic) D-Pad Right" },
|
||||
{ WPAD_CLASSIC_BUTTON_MINUS, "(Wii Classic) Select/Minus button" },
|
||||
{ WPAD_CLASSIC_BUTTON_PLUS, "(Wii Classic) Start/Plus button" },
|
||||
{ WPAD_CLASSIC_BUTTON_HOME, "(Wii Classic) Home button" },
|
||||
{ WPAD_CLASSIC_BUTTON_FULL_L, "(Wii Classic) Left Trigger" },
|
||||
{ WPAD_CLASSIC_BUTTON_FULL_R, "(Wii Classic) Right Trigger" },
|
||||
{ WPAD_CLASSIC_BUTTON_ZL, "(Wii Classic) ZL button" },
|
||||
{ WPAD_CLASSIC_BUTTON_ZR, "(Wii Classic) ZR button" },
|
||||
#endif
|
||||
};
|
||||
#endif
|
||||
|
||||
uint64_t rarch_input_find_previous_platform_key(uint64_t joykey)
|
||||
{
|
||||
size_t arr_size = sizeof(platform_keys) / sizeof(platform_keys[0]);
|
||||
|
||||
if (platform_keys[0].joykey == joykey)
|
||||
return joykey;
|
||||
|
||||
for (size_t i = 1; i < arr_size; i++)
|
||||
{
|
||||
if (platform_keys[i].joykey == joykey)
|
||||
return platform_keys[i - 1].joykey;
|
||||
}
|
||||
|
||||
return NO_BTN;
|
||||
}
|
||||
|
||||
uint64_t rarch_input_find_next_platform_key(uint64_t joykey)
|
||||
{
|
||||
size_t arr_size = sizeof(platform_keys) / sizeof(platform_keys[0]);
|
||||
if (platform_keys[arr_size - 1].joykey == joykey)
|
||||
return joykey;
|
||||
|
||||
for (size_t i = 0; i < arr_size - 1; i++)
|
||||
{
|
||||
if (platform_keys[i].joykey == joykey)
|
||||
return platform_keys[i + 1].joykey;
|
||||
}
|
||||
|
||||
return NO_BTN;
|
||||
}
|
||||
|
||||
const char *rarch_input_find_platform_key_label(uint64_t joykey)
|
||||
{
|
||||
if (joykey == NO_BTN)
|
||||
return "No button";
|
||||
|
||||
size_t arr_size = sizeof(platform_keys) / sizeof(platform_keys[0]);
|
||||
for (size_t i = 0; i < arr_size; i++)
|
||||
{
|
||||
if (platform_keys[i].joykey == joykey)
|
||||
return platform_keys[i].label;
|
||||
}
|
||||
|
||||
return "Unknown";
|
||||
}
|
||||
|
||||
void rarch_input_set_keybind(unsigned player, unsigned keybind_action, uint64_t default_retro_joypad_id)
|
||||
{
|
||||
uint64_t *key = &g_settings.input.binds[player][default_retro_joypad_id].joykey;
|
||||
|
||||
switch (keybind_action)
|
||||
{
|
||||
case KEYBIND_DECREMENT:
|
||||
*key = rarch_input_find_previous_platform_key(*key);
|
||||
break;
|
||||
|
||||
case KEYBIND_INCREMENT:
|
||||
*key = rarch_input_find_next_platform_key(*key);
|
||||
break;
|
||||
|
||||
case KEYBIND_DEFAULT:
|
||||
*key = rarch_default_keybind_lut[default_retro_joypad_id];
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void rarch_input_set_default_keybinds(unsigned player)
|
||||
{
|
||||
for (unsigned i = 0; i < RARCH_FIRST_META_KEY; i++)
|
||||
{
|
||||
g_settings.input.binds[player][i].id = i;
|
||||
g_settings.input.binds[player][i].joykey = rarch_default_keybind_lut[i];
|
||||
}
|
||||
g_settings.input.dpad_emulation[player] = DPAD_EMULATION_LSTICK;
|
||||
}
|
||||
|
||||
void rarch_input_set_default_keybind_names_for_emulator(void)
|
||||
{
|
||||
struct retro_system_info info;
|
||||
retro_get_system_info(&info);
|
||||
const char *id = info.library_name ? info.library_name : "Unknown";
|
||||
|
||||
// Genesis Plus GX/Next
|
||||
if (strstr(id, "Genesis Plus GX"))
|
||||
{
|
||||
strlcpy(rarch_default_libretro_keybind_name_lut[RETRO_DEVICE_ID_JOYPAD_B],
|
||||
"B button", sizeof(rarch_default_libretro_keybind_name_lut[RETRO_DEVICE_ID_JOYPAD_B]));
|
||||
strlcpy(rarch_default_libretro_keybind_name_lut[RETRO_DEVICE_ID_JOYPAD_A],
|
||||
"C button", sizeof(rarch_default_libretro_keybind_name_lut[RETRO_DEVICE_ID_JOYPAD_A]));
|
||||
strlcpy(rarch_default_libretro_keybind_name_lut[RETRO_DEVICE_ID_JOYPAD_X],
|
||||
"Y button", sizeof(rarch_default_libretro_keybind_name_lut[RETRO_DEVICE_ID_JOYPAD_X]));
|
||||
strlcpy(rarch_default_libretro_keybind_name_lut[RETRO_DEVICE_ID_JOYPAD_Y],
|
||||
"A button", sizeof(rarch_default_libretro_keybind_name_lut[RETRO_DEVICE_ID_JOYPAD_Y]));
|
||||
strlcpy(rarch_default_libretro_keybind_name_lut[RETRO_DEVICE_ID_JOYPAD_L],
|
||||
"X button", sizeof(rarch_default_libretro_keybind_name_lut[RETRO_DEVICE_ID_JOYPAD_L]));
|
||||
strlcpy(rarch_default_libretro_keybind_name_lut[RETRO_DEVICE_ID_JOYPAD_R],
|
||||
"Z button", sizeof(rarch_default_libretro_keybind_name_lut[RETRO_DEVICE_ID_JOYPAD_R]));
|
||||
strlcpy(rarch_default_libretro_keybind_name_lut[RETRO_DEVICE_ID_JOYPAD_SELECT],
|
||||
"Mode button", sizeof(rarch_default_libretro_keybind_name_lut[RETRO_DEVICE_ID_JOYPAD_SELECT]));
|
||||
}
|
||||
}
|
||||
|
||||
/*============================================================
|
||||
VIDEO EXTENSIONS
|
||||
============================================================ */
|
||||
|
||||
struct aspect_ratio_elem aspectratio_lut[ASPECT_RATIO_END] = {
|
||||
{ "1:1", 1.0f },
|
||||
{ "2:1", 2.0f },
|
||||
{ "3:2", 1.5f },
|
||||
{ "3:4", 0.75f },
|
||||
{ "4:1", 4.0f },
|
||||
{ "4:3", 1.3333f },
|
||||
{ "4:4", 1.0f },
|
||||
{ "5:4", 1.25f },
|
||||
{ "6:5", 1.2f },
|
||||
{ "7:9", 0.7777f },
|
||||
{ "8:3", 2.6666f },
|
||||
{ "8:7", 1.1428f },
|
||||
{ "16:9", 1.7778f },
|
||||
{ "16:10", 1.6f },
|
||||
{ "16:15", 3.2f },
|
||||
{ "19:12", 1.5833f },
|
||||
{ "19:14", 1.3571f },
|
||||
{ "30:17", 1.7647f },
|
||||
{ "32:9", 3.5555f },
|
||||
{ "Auto", 1.0f },
|
||||
{ "Custom", 0.0f }
|
||||
};
|
||||
|
||||
char rotation_lut[ASPECT_RATIO_END][PATH_MAX] =
|
||||
{
|
||||
"Normal",
|
||||
"Vertical",
|
||||
"Flipped",
|
||||
"Flipped Rotated"
|
||||
};
|
||||
|
||||
void rarch_set_auto_viewport(unsigned width, unsigned height)
|
||||
{
|
||||
if(width == 0 || height == 0)
|
||||
return;
|
||||
|
||||
unsigned aspect_x, aspect_y, len, highest, i;
|
||||
|
||||
len = width < height ? width : height;
|
||||
highest = 1;
|
||||
for (i = 1; i < len; i++)
|
||||
{
|
||||
if ((width % i) == 0 && (height % i) == 0)
|
||||
highest = i;
|
||||
}
|
||||
|
||||
aspect_x = width / highest;
|
||||
aspect_y = height / highest;
|
||||
|
||||
snprintf(aspectratio_lut[ASPECT_RATIO_AUTO].name, sizeof(aspectratio_lut[ASPECT_RATIO_AUTO].name), "%d:%d (Auto)", aspect_x, aspect_y);
|
||||
aspectratio_lut[ASPECT_RATIO_AUTO].value = (int)aspect_x / (int)aspect_y;
|
||||
}
|
||||
|
||||
/*============================================================
|
||||
RetroArch MAIN WRAP
|
||||
============================================================ */
|
||||
|
||||
#ifdef HAVE_RARCH_MAIN_WRAP
|
||||
|
||||
void rarch_startup (const char * config_path)
|
||||
{
|
||||
if(g_console.initialize_rarch_enable)
|
||||
{
|
||||
if(g_console.emulator_initialized)
|
||||
rarch_main_deinit();
|
||||
|
||||
struct rarch_main_wrap args = {0};
|
||||
|
||||
args.verbose = g_extern.verbose;
|
||||
args.config_path = config_path;
|
||||
args.sram_path = g_console.default_sram_dir_enable ? g_console.default_sram_dir : NULL,
|
||||
args.state_path = g_console.default_savestate_dir_enable ? g_console.default_savestate_dir : NULL,
|
||||
args.rom_path = g_console.rom_path;
|
||||
|
||||
int init_ret = rarch_main_init_wrap(&args);
|
||||
(void)init_ret;
|
||||
g_console.emulator_initialized = 1;
|
||||
g_console.initialize_rarch_enable = 0;
|
||||
}
|
||||
}
|
||||
|
||||
int rarch_main_init_wrap(const struct rarch_main_wrap *args)
|
||||
{
|
||||
int argc = 0;
|
||||
char *argv[MAX_ARGS] = {NULL};
|
||||
|
||||
argv[argc++] = strdup("retroarch");
|
||||
|
||||
if (args->rom_path)
|
||||
argv[argc++] = strdup(args->rom_path);
|
||||
|
||||
if (args->sram_path)
|
||||
{
|
||||
argv[argc++] = strdup("-s");
|
||||
argv[argc++] = strdup(args->sram_path);
|
||||
}
|
||||
|
||||
if (args->state_path)
|
||||
{
|
||||
argv[argc++] = strdup("-S");
|
||||
argv[argc++] = strdup(args->state_path);
|
||||
}
|
||||
|
||||
if (args->config_path)
|
||||
{
|
||||
argv[argc++] = strdup("-c");
|
||||
argv[argc++] = strdup(args->config_path);
|
||||
}
|
||||
|
||||
if (args->verbose)
|
||||
argv[argc++] = strdup("-v");
|
||||
|
||||
#ifdef HAVE_FILE_LOGGER
|
||||
RARCH_LOG("foo\n");
|
||||
for(int i = 0; i < argc; i++)
|
||||
RARCH_LOG("arg #%d: %s\n", i, argv[i]);
|
||||
RARCH_LOG("bar\n");
|
||||
#endif
|
||||
|
||||
int ret = rarch_main_init(argc, argv);
|
||||
|
||||
char **tmp = argv;
|
||||
while (*tmp)
|
||||
{
|
||||
free(*tmp);
|
||||
tmp++;
|
||||
}
|
||||
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_RARCH_EXEC
|
||||
|
||||
#ifdef __CELLOS_LV2__
|
||||
#include <cell/sysmodule.h>
|
||||
#include <sys/process.h>
|
||||
#include <sysutil/sysutil_common.h>
|
||||
#include <netex/net.h>
|
||||
#include <np.h>
|
||||
#include <np/drm.h>
|
||||
#endif
|
||||
|
||||
void rarch_exec (void)
|
||||
{
|
||||
if(g_console.return_to_launcher)
|
||||
{
|
||||
RARCH_LOG("Attempt to load executable: [%s].\n", g_console.launch_app_on_exit);
|
||||
#if defined(_XBOX)
|
||||
XLaunchNewImage(g_console.launch_app_on_exit, NULL);
|
||||
#elif defined(__CELLOS_LV2__)
|
||||
char spawn_data[256];
|
||||
for(unsigned int i = 0; i < sizeof(spawn_data); ++i)
|
||||
spawn_data[i] = i & 0xff;
|
||||
|
||||
char spawn_data_size[16];
|
||||
snprintf(spawn_data_size, sizeof(spawn_data_size), "%d", 256);
|
||||
|
||||
const char * const spawn_argv[] = {
|
||||
spawn_data_size,
|
||||
"test argv for",
|
||||
"sceNpDrmProcessExitSpawn2()",
|
||||
NULL
|
||||
};
|
||||
|
||||
SceNpDrmKey * k_licensee = NULL;
|
||||
int ret = sceNpDrmProcessExitSpawn2(k_licensee, g_console.launch_app_on_exit, (const char** const)spawn_argv, NULL, (sys_addr_t)spawn_data, 256, 1000, SYS_PROCESS_PRIMARY_STACK_SIZE_1M);
|
||||
if(ret < 0)
|
||||
{
|
||||
RARCH_WARN("SELF file is not of NPDRM type, trying another approach to boot it...\n");
|
||||
sys_game_process_exitspawn(g_console.launch_app_on_exit, NULL, NULL, NULL, 0, 1000, SYS_PROCESS_PRIMARY_STACK_SIZE_1M);
|
||||
}
|
||||
sceNpTerm();
|
||||
cellSysmoduleUnloadModule(CELL_SYSMODULE_SYSUTIL_NP);
|
||||
cellSysmoduleUnloadModule(CELL_SYSMODULE_NET);
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_RSOUND
|
||||
bool rarch_console_rsound_start(const char *ip)
|
||||
{
|
||||
strlcpy(g_settings.audio.driver, "rsound", sizeof(g_settings.audio.driver));
|
||||
strlcpy(g_settings.audio.device, ip, sizeof(g_settings.audio.device));
|
||||
driver.audio_data = NULL;
|
||||
|
||||
// If driver already has started, it must be reinited.
|
||||
if (driver.audio_data)
|
||||
{
|
||||
uninit_audio();
|
||||
driver.audio_data = NULL;
|
||||
init_drivers_pre();
|
||||
init_audio();
|
||||
}
|
||||
return g_extern.audio_active;
|
||||
}
|
||||
|
||||
void rarch_console_rsound_stop(void)
|
||||
{
|
||||
strlcpy(g_settings.audio.driver, config_get_default_audio(), sizeof(g_settings.audio.driver));
|
||||
|
||||
// If driver already has started, it must be reinited.
|
||||
if (driver.audio_data)
|
||||
{
|
||||
uninit_audio();
|
||||
driver.audio_data = NULL;
|
||||
init_drivers_pre();
|
||||
init_audio();
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
/*============================================================
|
||||
STRING HANDLING
|
||||
============================================================ */
|
||||
|
||||
#ifdef _XBOX
|
||||
void rarch_convert_char_to_wchar(wchar_t *buf, const char * str, size_t size)
|
||||
{
|
||||
unsigned long dwNum = MultiByteToWideChar(CP_ACP, 0, str, -1, NULL, 0);
|
||||
size /= sizeof(wchar_t);
|
||||
rarch_assert(size >= dwNum);
|
||||
MultiByteToWideChar(CP_ACP, 0, str, -1, buf, dwNum);
|
||||
}
|
||||
#endif
|
||||
|
||||
const char * rarch_convert_wchar_to_const_char(const wchar_t * wstr)
|
||||
{
|
||||
static char str[256];
|
||||
wcstombs(str, wstr, sizeof(str));
|
||||
return str;
|
||||
}
|
||||
|
||||
/*============================================================
|
||||
CONFIG
|
||||
============================================================ */
|
||||
|
||||
#ifdef HAVE_CONFIGFILE
|
||||
void rarch_config_create_default(const char * conf_name)
|
||||
{
|
||||
FILE * f;
|
||||
RARCH_WARN("Config file \"%s\" doesn't exist. Creating...\n", conf_name);
|
||||
f = fopen(conf_name, "w");
|
||||
fclose(f);
|
||||
}
|
||||
|
||||
void rarch_config_load(const char * conf_name, const char * libretro_dir_path, const char * exe_ext, bool find_libretro_path)
|
||||
{
|
||||
if(!path_file_exists(conf_name))
|
||||
rarch_config_create_default(conf_name);
|
||||
else
|
||||
{
|
||||
config_file_t * conf = config_file_new(conf_name);
|
||||
|
||||
// g_settings
|
||||
|
||||
#ifdef HAVE_LIBRETRO_MANAGEMENT
|
||||
if(find_libretro_path)
|
||||
{
|
||||
CONFIG_GET_STRING(libretro, "libretro_path");
|
||||
|
||||
if(!strcmp(g_settings.libretro, ""))
|
||||
{
|
||||
const char *first_file = rarch_manage_libretro_set_first_file(libretro_dir_path, exe_ext);
|
||||
if(first_file != NULL)
|
||||
strlcpy(g_settings.libretro, first_file, sizeof(g_settings.libretro));
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
CONFIG_GET_STRING(cheat_database, "cheat_database");
|
||||
CONFIG_GET_BOOL(rewind_enable, "rewind_enable");
|
||||
CONFIG_GET_STRING(video.cg_shader_path, "video_cg_shader");
|
||||
#ifdef HAVE_FBO
|
||||
CONFIG_GET_STRING(video.second_pass_shader, "video_second_pass_shader");
|
||||
CONFIG_GET_FLOAT(video.fbo_scale_x, "video_fbo_scale_x");
|
||||
CONFIG_GET_FLOAT(video.fbo_scale_y, "video_fbo_scale_y");
|
||||
CONFIG_GET_BOOL(video.render_to_texture, "video_render_to_texture");
|
||||
CONFIG_GET_BOOL(video.second_pass_smooth, "video_second_pass_smooth");
|
||||
#endif
|
||||
#ifdef _XBOX
|
||||
CONFIG_GET_BOOL_CONSOLE(gamma_correction_enable, "gamma_correction_enable");
|
||||
CONFIG_GET_INT_CONSOLE(color_format, "color_format");
|
||||
#endif
|
||||
CONFIG_GET_BOOL(video.smooth, "video_smooth");
|
||||
CONFIG_GET_BOOL(video.vsync, "video_vsync");
|
||||
CONFIG_GET_FLOAT(video.aspect_ratio, "video_aspect_ratio");
|
||||
CONFIG_GET_STRING(audio.device, "audio_device");
|
||||
|
||||
for (unsigned i = 0; i < 7; i++)
|
||||
{
|
||||
char cfg[64];
|
||||
snprintf(cfg, sizeof(cfg), "input_dpad_emulation_p%u", i + 1);
|
||||
CONFIG_GET_INT(input.dpad_emulation[i], cfg);
|
||||
}
|
||||
|
||||
// g_console
|
||||
|
||||
#ifdef HAVE_FBO
|
||||
CONFIG_GET_BOOL_CONSOLE(fbo_enabled, "fbo_enabled");
|
||||
#endif
|
||||
#ifdef __CELLOS_LV2__
|
||||
CONFIG_GET_BOOL_CONSOLE(custom_bgm_enable, "custom_bgm_enable");
|
||||
#endif
|
||||
CONFIG_GET_BOOL_CONSOLE(overscan_enable, "overscan_enable");
|
||||
CONFIG_GET_BOOL_CONSOLE(screenshots_enable, "screenshots_enable");
|
||||
CONFIG_GET_BOOL_CONSOLE(throttle_enable, "throttle_enable");
|
||||
CONFIG_GET_BOOL_CONSOLE(triple_buffering_enable, "triple_buffering_enable");
|
||||
CONFIG_GET_BOOL_CONSOLE(info_msg_enable, "info_msg_enable");
|
||||
CONFIG_GET_INT_CONSOLE(aspect_ratio_index, "aspect_ratio_index");
|
||||
CONFIG_GET_INT_CONSOLE(current_resolution_id, "current_resolution_id");
|
||||
CONFIG_GET_INT_CONSOLE(viewports.custom_vp.x, "custom_viewport_x");
|
||||
CONFIG_GET_INT_CONSOLE(viewports.custom_vp.y, "custom_viewport_y");
|
||||
CONFIG_GET_INT_CONSOLE(viewports.custom_vp.width, "custom_viewport_width");
|
||||
CONFIG_GET_INT_CONSOLE(viewports.custom_vp.height, "custom_viewport_height");
|
||||
CONFIG_GET_INT_CONSOLE(screen_orientation, "screen_orientation");
|
||||
CONFIG_GET_INT_CONSOLE(sound_mode, "sound_mode");
|
||||
CONFIG_GET_STRING_CONSOLE(default_rom_startup_dir, "default_rom_startup_dir");
|
||||
CONFIG_GET_FLOAT_CONSOLE(menu_font_size, "menu_font_size");
|
||||
CONFIG_GET_FLOAT_CONSOLE(overscan_amount, "overscan_amount");
|
||||
|
||||
// g_extern
|
||||
CONFIG_GET_INT_EXTERN(state_slot, "state_slot");
|
||||
CONFIG_GET_INT_EXTERN(audio_data.mute, "audio_mute");
|
||||
}
|
||||
}
|
||||
|
||||
void rarch_config_save(const char * conf_name)
|
||||
{
|
||||
if(!path_file_exists(conf_name))
|
||||
rarch_config_create_default(conf_name);
|
||||
else
|
||||
{
|
||||
config_file_t * conf = config_file_new(conf_name);
|
||||
|
||||
if(conf == NULL)
|
||||
conf = config_file_new(NULL);
|
||||
|
||||
// g_settings
|
||||
config_set_string(conf, "libretro_path", g_settings.libretro);
|
||||
#ifdef HAVE_XML
|
||||
config_set_string(conf, "cheat_database_path", g_settings.cheat_database);
|
||||
#endif
|
||||
config_set_bool(conf, "rewind_enable", g_settings.rewind_enable);
|
||||
config_set_string(conf, "video_cg_shader", g_settings.video.cg_shader_path);
|
||||
config_set_float(conf, "video_aspect_ratio", g_settings.video.aspect_ratio);
|
||||
#ifdef HAVE_FBO
|
||||
config_set_float(conf, "video_fbo_scale_x", g_settings.video.fbo_scale_x);
|
||||
config_set_float(conf, "video_fbo_scale_y", g_settings.video.fbo_scale_y);
|
||||
config_set_string(conf, "video_second_pass_shader", g_settings.video.second_pass_shader);
|
||||
config_set_bool(conf, "video_render_to_texture", g_settings.video.render_to_texture);
|
||||
config_set_bool(conf, "video_second_pass_smooth", g_settings.video.second_pass_smooth);
|
||||
#endif
|
||||
config_set_bool(conf, "video_smooth", g_settings.video.smooth);
|
||||
config_set_bool(conf, "video_vsync", g_settings.video.vsync);
|
||||
config_set_string(conf, "audio_device", g_settings.audio.device);
|
||||
|
||||
for (unsigned i = 0; i < 7; i++)
|
||||
{
|
||||
char cfg[64];
|
||||
snprintf(cfg, sizeof(cfg), "input_dpad_emulation_p%u", i + 1);
|
||||
config_set_int(conf, cfg, g_settings.input.dpad_emulation[i]);
|
||||
}
|
||||
|
||||
#ifdef RARCH_CONSOLE
|
||||
config_set_bool(conf, "fbo_enabled", g_console.fbo_enabled);
|
||||
#ifdef __CELLOS_LV2__
|
||||
config_set_bool(conf, "custom_bgm_enable", g_console.custom_bgm_enable);
|
||||
#endif
|
||||
config_set_bool(conf, "overscan_enable", g_console.overscan_enable);
|
||||
config_set_bool(conf, "screenshots_enable", g_console.screenshots_enable);
|
||||
#ifdef _XBOX
|
||||
config_set_bool(conf, "gamma_correction_enable", g_console.gamma_correction_enable);
|
||||
config_set_int(conf, "color_format", g_console.color_format);
|
||||
#endif
|
||||
config_set_bool(conf, "throttle_enable", g_console.throttle_enable);
|
||||
config_set_bool(conf, "triple_buffering_enable", g_console.triple_buffering_enable);
|
||||
config_set_bool(conf, "info_msg_enable", g_console.info_msg_enable);
|
||||
config_set_int(conf, "sound_mode", g_console.sound_mode);
|
||||
config_set_int(conf, "aspect_ratio_index", g_console.aspect_ratio_index);
|
||||
config_set_int(conf, "current_resolution_id", g_console.current_resolution_id);
|
||||
config_set_int(conf, "custom_viewport_width", g_console.viewports.custom_vp.width);
|
||||
config_set_int(conf, "custom_viewport_height", g_console.viewports.custom_vp.height);
|
||||
config_set_int(conf, "custom_viewport_x", g_console.viewports.custom_vp.x);
|
||||
config_set_int(conf, "custom_viewport_y", g_console.viewports.custom_vp.y);
|
||||
config_set_int(conf, "screen_orientation", g_console.screen_orientation);
|
||||
config_set_string(conf, "default_rom_startup_dir", g_console.default_rom_startup_dir);
|
||||
config_set_float(conf, "menu_font_size", g_console.menu_font_size);
|
||||
config_set_float(conf, "overscan_amount", g_console.overscan_amount);
|
||||
#endif
|
||||
|
||||
// g_extern
|
||||
config_set_int(conf, "state_slot", g_extern.state_slot);
|
||||
config_set_int(conf, "audio_mute", g_extern.audio_data.mute);
|
||||
|
||||
if (!config_file_write(conf, conf_name))
|
||||
RARCH_ERR("Failed to write config file to \"%s\". Check permissions.\n", conf_name);
|
||||
|
||||
free(conf);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
@@ -0,0 +1,209 @@
|
||||
/* RetroArch - A frontend for libretro.
|
||||
* Copyright (C) 2010-2012 - Hans-Kristian Arntzen
|
||||
* Copyright (C) 2011-2012 - Daniel De Matteis
|
||||
*
|
||||
* RetroArch is free software: you can redistribute it and/or modify it under the terms
|
||||
* of the GNU General Public License as published by the Free Software Found-
|
||||
* ation, either version 3 of the License, or (at your option) any later version.
|
||||
*
|
||||
* RetroArch is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
|
||||
* without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
|
||||
* PURPOSE. See the GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along with RetroArch.
|
||||
* If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifndef CONSOLE_EXT_H__
|
||||
#define CONSOLE_EXT_H__
|
||||
|
||||
#ifdef HAVE_LIBRETRO_MANAGEMENT
|
||||
#include "libretro_mgmt.h"
|
||||
#endif
|
||||
|
||||
#include "console_settings.h"
|
||||
|
||||
#define IS_TIMER_NOT_EXPIRED(handle) (handle->frame_count < g_console.timer_expiration_frame_count)
|
||||
#define IS_TIMER_EXPIRED(handle) (!(IS_TIMER_NOT_EXPIRED(handle)))
|
||||
#define SET_TIMER_EXPIRATION(handle, value) (g_console.timer_expiration_frame_count = handle->frame_count + value)
|
||||
|
||||
/*============================================================
|
||||
VIDEO
|
||||
============================================================ */
|
||||
|
||||
enum aspect_ratio
|
||||
{
|
||||
ASPECT_RATIO_1_1 = 0,
|
||||
ASPECT_RATIO_2_1,
|
||||
ASPECT_RATIO_3_2,
|
||||
ASPECT_RATIO_3_4,
|
||||
ASPECT_RATIO_4_1,
|
||||
ASPECT_RATIO_4_3,
|
||||
ASPECT_RATIO_4_4,
|
||||
ASPECT_RATIO_5_4,
|
||||
ASPECT_RATIO_6_5,
|
||||
ASPECT_RATIO_7_9,
|
||||
ASPECT_RATIO_8_3,
|
||||
ASPECT_RATIO_8_7,
|
||||
ASPECT_RATIO_16_9,
|
||||
ASPECT_RATIO_16_10,
|
||||
ASPECT_RATIO_16_15,
|
||||
ASPECT_RATIO_19_12,
|
||||
ASPECT_RATIO_19_14,
|
||||
ASPECT_RATIO_30_17,
|
||||
ASPECT_RATIO_32_9,
|
||||
ASPECT_RATIO_AUTO,
|
||||
ASPECT_RATIO_CUSTOM,
|
||||
|
||||
ASPECT_RATIO_END,
|
||||
};
|
||||
|
||||
#define LAST_ASPECT_RATIO ASPECT_RATIO_CUSTOM
|
||||
|
||||
enum rotation
|
||||
{
|
||||
ORIENTATION_NORMAL = 0,
|
||||
ORIENTATION_VERTICAL,
|
||||
ORIENTATION_FLIPPED,
|
||||
ORIENTATION_FLIPPED_ROTATED,
|
||||
ORIENTATION_END
|
||||
};
|
||||
|
||||
#define LAST_ORIENTATION (ORIENTATION_END-1)
|
||||
|
||||
extern char rotation_lut[ASPECT_RATIO_END][PATH_MAX];
|
||||
|
||||
/* ABGR color format defines */
|
||||
|
||||
#define WHITE 0xffffffffu
|
||||
#define RED 0xff0000ffu
|
||||
#define GREEN 0xff00ff00u
|
||||
#define BLUE 0xffff0000u
|
||||
#define YELLOW 0xff00ffffu
|
||||
#define PURPLE 0xffff00ffu
|
||||
#define CYAN 0xffffff00u
|
||||
#define ORANGE 0xff0063ffu
|
||||
#define SILVER 0xff8c848cu
|
||||
#define LIGHTBLUE 0xFFFFE0E0U
|
||||
#define LIGHTORANGE 0xFFE0EEFFu
|
||||
|
||||
struct aspect_ratio_elem
|
||||
{
|
||||
char name[64];
|
||||
float value;
|
||||
};
|
||||
|
||||
extern struct aspect_ratio_elem aspectratio_lut[ASPECT_RATIO_END];
|
||||
|
||||
extern void rarch_set_auto_viewport(unsigned width, unsigned height);
|
||||
|
||||
#include "console_ext_input.h"
|
||||
|
||||
/*============================================================
|
||||
SOUND
|
||||
============================================================ */
|
||||
|
||||
enum
|
||||
{
|
||||
SOUND_MODE_NORMAL,
|
||||
#ifdef HAVE_RSOUND
|
||||
SOUND_MODE_RSOUND,
|
||||
#endif
|
||||
#ifdef HAVE_HEADSET
|
||||
SOUND_MODE_HEADSET,
|
||||
#endif
|
||||
};
|
||||
|
||||
/*============================================================
|
||||
ROM EXTENSIONS
|
||||
============================================================ */
|
||||
|
||||
// Get rom extensions for current library.
|
||||
// Returns NULL if library doesn't have any preferences in particular.
|
||||
const char *rarch_console_get_rom_ext(void);
|
||||
|
||||
// Transforms a library id to a name suitable as a pathname.
|
||||
void rarch_console_name_from_id(char *name, size_t size);
|
||||
|
||||
#ifdef HAVE_ZLIB
|
||||
int rarch_extract_zipfile(const char *zip_path);
|
||||
#endif
|
||||
|
||||
/*============================================================
|
||||
INPUT EXTENSIONS
|
||||
============================================================ */
|
||||
|
||||
const char *rarch_input_find_platform_key_label(uint64_t joykey);
|
||||
uint64_t rarch_input_find_previous_platform_key(uint64_t joykey);
|
||||
uint64_t rarch_input_find_next_platform_key(uint64_t joykey);
|
||||
|
||||
// Sets custom default keybind names (some systems emulated by the emulator
|
||||
// will need different keybind names for buttons, etc.)
|
||||
void rarch_input_set_default_keybind_names_for_emulator(void);
|
||||
|
||||
void rarch_input_set_keybind(unsigned player, unsigned keybind_action, uint64_t default_retro_joypad_id);
|
||||
|
||||
|
||||
/*============================================================
|
||||
RetroArch
|
||||
============================================================ */
|
||||
|
||||
enum {
|
||||
MENU_ITEM_LOAD_STATE = 0,
|
||||
MENU_ITEM_SAVE_STATE,
|
||||
MENU_ITEM_KEEP_ASPECT_RATIO,
|
||||
MENU_ITEM_OVERSCAN_AMOUNT,
|
||||
MENU_ITEM_ORIENTATION,
|
||||
#ifdef __CELLOS_LV2__
|
||||
MENU_ITEM_SCALE_FACTOR,
|
||||
#endif
|
||||
MENU_ITEM_RESIZE_MODE,
|
||||
MENU_ITEM_FRAME_ADVANCE,
|
||||
MENU_ITEM_SCREENSHOT_MODE,
|
||||
MENU_ITEM_RESET,
|
||||
MENU_ITEM_RETURN_TO_GAME,
|
||||
#ifdef __CELLOS_LV2__
|
||||
MENU_ITEM_RETURN_TO_MENU,
|
||||
MENU_ITEM_CHANGE_LIBRETRO,
|
||||
MENU_ITEM_RETURN_TO_MULTIMAN,
|
||||
#endif
|
||||
MENU_ITEM_RETURN_TO_DASHBOARD
|
||||
};
|
||||
|
||||
#define MENU_ITEM_LAST MENU_ITEM_RETURN_TO_DASHBOARD+1
|
||||
|
||||
#ifdef HAVE_RARCH_MAIN_WRAP
|
||||
|
||||
struct rarch_main_wrap
|
||||
{
|
||||
const char *rom_path;
|
||||
const char *sram_path;
|
||||
const char *state_path;
|
||||
const char *config_path;
|
||||
bool verbose;
|
||||
};
|
||||
|
||||
int rarch_main_init_wrap(const struct rarch_main_wrap *args);
|
||||
void rarch_startup (const char * config_path);
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_RARCH_EXEC
|
||||
void rarch_exec (void);
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_RSOUND
|
||||
bool rarch_console_rsound_start(const char *ip);
|
||||
void rarch_console_rsound_stop(void);
|
||||
#endif
|
||||
|
||||
#ifdef _XBOX
|
||||
void rarch_convert_char_to_wchar(wchar_t *buf, const char * str, size_t size);
|
||||
#endif
|
||||
|
||||
const char * rarch_convert_wchar_to_const_char(const wchar_t * wstr);
|
||||
|
||||
void rarch_config_create_default(const char * conf_name);
|
||||
void rarch_config_load(const char * conf_name, const char * libretro_dir_path, const char * exe_ext, bool find_libretro_path);
|
||||
void rarch_config_save(const char * conf_name);
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,134 @@
|
||||
/* RetroArch - A frontend for libretro.
|
||||
* Copyright (C) 2010-2012 - Hans-Kristian Arntzen
|
||||
* Copyright (C) 2011-2012 - Daniel De Matteis
|
||||
*
|
||||
* RetroArch is free software: you can redistribute it and/or modify it under the terms
|
||||
* of the GNU General Public License as published by the Free Software Found-
|
||||
* ation, either version 3 of the License, or (at your option) any later version.
|
||||
*
|
||||
* RetroArch is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
|
||||
* without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
|
||||
* PURPOSE. See the GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along with RetroArch.
|
||||
* If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifndef CONSOLE_EXT_INPUT_H__
|
||||
#define CONSOLE_EXT_INPUT_H__
|
||||
|
||||
#include "../driver.h"
|
||||
|
||||
enum keybind_set_id
|
||||
{
|
||||
KEYBIND_NOACTION = 0,
|
||||
KEYBIND_DECREMENT,
|
||||
KEYBIND_INCREMENT,
|
||||
KEYBIND_DEFAULT
|
||||
};
|
||||
|
||||
enum
|
||||
{
|
||||
MODE_EMULATION = 0,
|
||||
MODE_MENU,
|
||||
MODE_EXIT
|
||||
};
|
||||
|
||||
enum
|
||||
{
|
||||
DPAD_EMULATION_NONE = 0,
|
||||
DPAD_EMULATION_LSTICK,
|
||||
DPAD_EMULATION_RSTICK
|
||||
};
|
||||
|
||||
#if defined(__CELLOS_LV2__)
|
||||
#include "../ps3/ps3_input.h"
|
||||
enum ps3_device_id
|
||||
{
|
||||
PS3_DEVICE_ID_JOYPAD_CIRCLE = 0,
|
||||
PS3_DEVICE_ID_JOYPAD_CROSS,
|
||||
PS3_DEVICE_ID_JOYPAD_TRIANGLE,
|
||||
PS3_DEVICE_ID_JOYPAD_SQUARE,
|
||||
PS3_DEVICE_ID_JOYPAD_UP,
|
||||
PS3_DEVICE_ID_JOYPAD_DOWN,
|
||||
PS3_DEVICE_ID_JOYPAD_LEFT,
|
||||
PS3_DEVICE_ID_JOYPAD_RIGHT,
|
||||
PS3_DEVICE_ID_JOYPAD_SELECT,
|
||||
PS3_DEVICE_ID_JOYPAD_START,
|
||||
PS3_DEVICE_ID_JOYPAD_L1,
|
||||
PS3_DEVICE_ID_JOYPAD_L2,
|
||||
PS3_DEVICE_ID_JOYPAD_L3,
|
||||
PS3_DEVICE_ID_JOYPAD_R1,
|
||||
PS3_DEVICE_ID_JOYPAD_R2,
|
||||
PS3_DEVICE_ID_JOYPAD_R3,
|
||||
PS3_DEVICE_ID_LSTICK_LEFT,
|
||||
PS3_DEVICE_ID_LSTICK_RIGHT,
|
||||
PS3_DEVICE_ID_LSTICK_UP,
|
||||
PS3_DEVICE_ID_LSTICK_DOWN,
|
||||
PS3_DEVICE_ID_LSTICK_LEFT_DPAD,
|
||||
PS3_DEVICE_ID_LSTICK_RIGHT_DPAD,
|
||||
PS3_DEVICE_ID_LSTICK_UP_DPAD,
|
||||
PS3_DEVICE_ID_LSTICK_DOWN_DPAD,
|
||||
PS3_DEVICE_ID_RSTICK_LEFT,
|
||||
PS3_DEVICE_ID_RSTICK_RIGHT,
|
||||
PS3_DEVICE_ID_RSTICK_UP,
|
||||
PS3_DEVICE_ID_RSTICK_DOWN,
|
||||
PS3_DEVICE_ID_RSTICK_LEFT_DPAD,
|
||||
PS3_DEVICE_ID_RSTICK_RIGHT_DPAD,
|
||||
PS3_DEVICE_ID_RSTICK_UP_DPAD,
|
||||
PS3_DEVICE_ID_RSTICK_DOWN_DPAD,
|
||||
|
||||
RARCH_LAST_PLATFORM_KEY
|
||||
};
|
||||
|
||||
#elif defined(_XBOX)
|
||||
#include "../360/xdk360_input.h"
|
||||
|
||||
enum xdk360_device_id
|
||||
{
|
||||
XDK360_DEVICE_ID_JOYPAD_B = 0,
|
||||
XDK360_DEVICE_ID_JOYPAD_A,
|
||||
XDK360_DEVICE_ID_JOYPAD_Y,
|
||||
XDK360_DEVICE_ID_JOYPAD_X,
|
||||
XDK360_DEVICE_ID_JOYPAD_UP,
|
||||
XDK360_DEVICE_ID_JOYPAD_DOWN,
|
||||
XDK360_DEVICE_ID_JOYPAD_LEFT,
|
||||
XDK360_DEVICE_ID_JOYPAD_RIGHT,
|
||||
XDK360_DEVICE_ID_JOYPAD_BACK,
|
||||
XDK360_DEVICE_ID_JOYPAD_START,
|
||||
XDK360_DEVICE_ID_JOYPAD_LB,
|
||||
XDK360_DEVICE_ID_JOYPAD_LEFT_TRIGGER,
|
||||
XDK360_DEVICE_ID_LSTICK_THUMB,
|
||||
XDK360_DEVICE_ID_JOYPAD_RB,
|
||||
XDK360_DEVICE_ID_JOYPAD_RIGHT_TRIGGER,
|
||||
XDK360_DEVICE_ID_RSTICK_THUMB,
|
||||
XDK360_DEVICE_ID_LSTICK_LEFT,
|
||||
XDK360_DEVICE_ID_LSTICK_RIGHT,
|
||||
XDK360_DEVICE_ID_LSTICK_UP,
|
||||
XDK360_DEVICE_ID_LSTICK_DOWN,
|
||||
XDK360_DEVICE_ID_LSTICK_LEFT_DPAD,
|
||||
XDK360_DEVICE_ID_LSTICK_RIGHT_DPAD,
|
||||
XDK360_DEVICE_ID_LSTICK_UP_DPAD,
|
||||
XDK360_DEVICE_ID_LSTICK_DOWN_DPAD,
|
||||
XDK360_DEVICE_ID_RSTICK_LEFT,
|
||||
XDK360_DEVICE_ID_RSTICK_RIGHT,
|
||||
XDK360_DEVICE_ID_RSTICK_UP,
|
||||
XDK360_DEVICE_ID_RSTICK_DOWN,
|
||||
XDK360_DEVICE_ID_RSTICK_LEFT_DPAD,
|
||||
XDK360_DEVICE_ID_RSTICK_RIGHT_DPAD,
|
||||
XDK360_DEVICE_ID_RSTICK_UP_DPAD,
|
||||
XDK360_DEVICE_ID_RSTICK_DOWN_DPAD,
|
||||
|
||||
RARCH_LAST_PLATFORM_KEY
|
||||
};
|
||||
#elif defined(GEKKO)
|
||||
#include <ogc/pad.h>
|
||||
#ifdef HW_RVL
|
||||
#include <wiiuse/wpad.h>
|
||||
#endif
|
||||
#endif
|
||||
|
||||
extern uint64_t rarch_default_keybind_lut[RARCH_FIRST_META_KEY];
|
||||
extern char rarch_default_libsnes_keybind_name_lut[RARCH_FIRST_META_KEY][256];
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,253 @@
|
||||
/* RetroArch - A frontend for libretro.
|
||||
* Copyright (C) 2010-2012 - Hans-Kristian Arntzen
|
||||
* Copyright (C) 2011-2012 - Daniel De Matteis
|
||||
*
|
||||
* RetroArch is free software: you can redistribute it and/or modify it under the terms
|
||||
* of the GNU General Public License as published by the Free Software Found-
|
||||
* ation, either version 3 of the License, or (at your option) any later version.
|
||||
*
|
||||
* RetroArch is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
|
||||
* without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
|
||||
* PURPOSE. See the GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along with RetroArch.
|
||||
* If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <stddef.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "../general.h"
|
||||
#include "console_settings.h"
|
||||
|
||||
void rarch_settings_change(unsigned setting)
|
||||
{
|
||||
switch(setting)
|
||||
{
|
||||
case S_ASPECT_RATIO_DECREMENT:
|
||||
if(g_console.aspect_ratio_index > 0)
|
||||
g_console.aspect_ratio_index--;
|
||||
break;
|
||||
case S_ASPECT_RATIO_INCREMENT:
|
||||
if(g_console.aspect_ratio_index < LAST_ASPECT_RATIO)
|
||||
g_console.aspect_ratio_index++;
|
||||
break;
|
||||
case S_FRAME_ADVANCE:
|
||||
g_console.frame_advance_enable = true;
|
||||
g_console.menu_enable = false;
|
||||
g_console.mode_switch = MODE_EMULATION;
|
||||
break;
|
||||
case S_HW_TEXTURE_FILTER:
|
||||
g_settings.video.smooth = !g_settings.video.smooth;
|
||||
break;
|
||||
case S_HW_TEXTURE_FILTER_2:
|
||||
g_settings.video.second_pass_smooth = !g_settings.video.second_pass_smooth;
|
||||
break;
|
||||
case S_OVERSCAN_DECREMENT:
|
||||
g_console.overscan_amount -= 0.01f;
|
||||
g_console.overscan_enable = true;
|
||||
if(g_console.overscan_amount == 0.0f)
|
||||
g_console.overscan_enable = false;
|
||||
break;
|
||||
case S_OVERSCAN_INCREMENT:
|
||||
g_console.overscan_amount += 0.01f;
|
||||
g_console.overscan_enable = true;
|
||||
if(g_console.overscan_amount == 0.0f)
|
||||
g_console.overscan_enable = 0;
|
||||
break;
|
||||
case S_QUIT:
|
||||
g_console.menu_enable = false;
|
||||
g_console.ingame_menu_enable = false;
|
||||
g_console.mode_switch = MODE_EXIT;
|
||||
break;
|
||||
case S_RETURN_TO_DASHBOARD:
|
||||
g_console.menu_enable = false;
|
||||
g_console.initialize_rarch_enable = false;
|
||||
g_console.mode_switch = MODE_EXIT;
|
||||
break;
|
||||
case S_RETURN_TO_GAME:
|
||||
g_console.frame_advance_enable = false;
|
||||
//g_console.ingame_menu_item = 0;
|
||||
g_console.menu_enable = false;
|
||||
g_console.mode_switch = MODE_EMULATION;
|
||||
break;
|
||||
case S_RETURN_TO_LAUNCHER:
|
||||
g_console.return_to_launcher = true;
|
||||
g_console.menu_enable = false;
|
||||
g_console.mode_switch = MODE_EXIT;
|
||||
break;
|
||||
case S_RETURN_TO_MENU:
|
||||
g_console.menu_enable = false;
|
||||
g_console.ingame_menu_item = 0;
|
||||
g_console.mode_switch = MODE_MENU;
|
||||
break;
|
||||
case S_ROTATION_DECREMENT:
|
||||
if(g_console.screen_orientation > 0)
|
||||
g_console.screen_orientation--;
|
||||
break;
|
||||
case S_ROTATION_INCREMENT:
|
||||
if(g_console.screen_orientation < LAST_ORIENTATION)
|
||||
g_console.screen_orientation++;
|
||||
break;
|
||||
case S_START_RARCH:
|
||||
g_console.menu_enable = false;
|
||||
g_console.initialize_rarch_enable = 1;
|
||||
g_console.mode_switch = MODE_EMULATION;
|
||||
break;
|
||||
case S_REWIND:
|
||||
g_settings.rewind_enable = !g_settings.rewind_enable;
|
||||
break;
|
||||
case S_SAVESTATE_DECREMENT:
|
||||
if(g_extern.state_slot != 0)
|
||||
g_extern.state_slot--;
|
||||
break;
|
||||
case S_SAVESTATE_INCREMENT:
|
||||
g_extern.state_slot++;
|
||||
break;
|
||||
case S_SCALE_ENABLED:
|
||||
g_console.fbo_enabled = !g_console.fbo_enabled;
|
||||
break;
|
||||
case S_SCALE_FACTOR_DECREMENT:
|
||||
g_settings.video.fbo_scale_x -= 1.0f;
|
||||
g_settings.video.fbo_scale_y -= 1.0f;
|
||||
break;
|
||||
case S_SCALE_FACTOR_INCREMENT:
|
||||
g_settings.video.fbo_scale_x += 1.0f;
|
||||
g_settings.video.fbo_scale_y += 1.0f;
|
||||
break;
|
||||
case S_THROTTLE:
|
||||
g_console.throttle_enable = !g_console.throttle_enable;
|
||||
break;
|
||||
case S_TRIPLE_BUFFERING:
|
||||
g_console.triple_buffering_enable = !g_console.triple_buffering_enable;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void rarch_settings_default(unsigned setting)
|
||||
{
|
||||
switch(setting)
|
||||
{
|
||||
case S_DEF_ASPECT_RATIO:
|
||||
g_console.aspect_ratio_index = ASPECT_RATIO_4_3;
|
||||
break;
|
||||
case S_DEF_HW_TEXTURE_FILTER:
|
||||
g_settings.video.smooth = 1;
|
||||
break;
|
||||
case S_DEF_HW_TEXTURE_FILTER_2:
|
||||
g_settings.video.second_pass_smooth = 1;
|
||||
break;
|
||||
case S_DEF_OVERSCAN:
|
||||
g_console.overscan_amount = 0.0f;
|
||||
g_console.overscan_enable = false;
|
||||
break;
|
||||
case S_DEF_ROTATION:
|
||||
g_console.screen_orientation = ORIENTATION_NORMAL;
|
||||
break;
|
||||
case S_DEF_THROTTLE:
|
||||
g_console.throttle_enable = true;
|
||||
break;
|
||||
case S_DEF_TRIPLE_BUFFERING:
|
||||
g_console.triple_buffering_enable = true;
|
||||
break;
|
||||
case S_DEF_SAVE_STATE:
|
||||
g_extern.state_slot = 0;
|
||||
break;
|
||||
case S_DEF_SCALE_ENABLED:
|
||||
g_console.fbo_enabled = true;
|
||||
g_settings.video.fbo_scale_x = 2.0f;
|
||||
g_settings.video.fbo_scale_y = 2.0f;
|
||||
break;
|
||||
case S_DEF_SCALE_FACTOR:
|
||||
g_settings.video.fbo_scale_x = 2.0f;
|
||||
g_settings.video.fbo_scale_y = 2.0f;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void rarch_settings_msg(unsigned setting, unsigned delay)
|
||||
{
|
||||
char str[PATH_MAX];
|
||||
msg_queue_clear(g_extern.msg_queue);
|
||||
|
||||
switch(setting)
|
||||
{
|
||||
case S_MSG_CACHE_PARTITION:
|
||||
snprintf(str, sizeof(str), "INFO - All the contents of the ZIP files you have selected in the filebrowser\nare extracted to this partition.");
|
||||
break;
|
||||
case S_MSG_CHANGE_CONTROLS:
|
||||
snprintf(str, sizeof(str), "INFO - Press LEFT/RIGHT to change the controls, and press\n[RetroPad Start] to reset a button to default values.");
|
||||
break;
|
||||
case S_MSG_EXTRACTED_ZIPFILE:
|
||||
snprintf(str, sizeof(str), "INFO - ZIP file successfully extracted to cache partition.");
|
||||
break;
|
||||
case S_MSG_NOT_IMPLEMENTED:
|
||||
snprintf(str, sizeof(str), "TODO - Not yet implemented.");
|
||||
break;
|
||||
case S_MSG_RESIZE_SCREEN:
|
||||
snprintf(str, sizeof(str), "INFO - Resize the screen by moving around the two analog sticks.\nPress [RetroPad X] to reset to default values, and [RetroPad A] to go back.\nTo select the resized screen mode, set Aspect Ratio to: 'Custom'.");
|
||||
break;
|
||||
case S_MSG_RESTART_RARCH:
|
||||
snprintf(str, sizeof(str), "INFO - You need to restart RetroArch for this change to take effect.");
|
||||
break;
|
||||
case S_MSG_SELECT_LIBRETRO_CORE:
|
||||
snprintf(str, sizeof(str), "INFO - Select a Libretro core from the menu by pressing [RetroPad B].");
|
||||
break;
|
||||
case S_MSG_SELECT_SHADER:
|
||||
snprintf(str, sizeof(str), "INFO - Select a shader from the menu by pressing [RetroPad A].");
|
||||
break;
|
||||
case S_MSG_SHADER_LOADING_SUCCEEDED:
|
||||
snprintf(str, sizeof(str), "INFO - Shader successfully loaded.");
|
||||
break;
|
||||
}
|
||||
|
||||
msg_queue_push(g_extern.msg_queue, str, 1, delay);
|
||||
}
|
||||
|
||||
#ifdef _XBOX
|
||||
void rarch_settings_create_menu_item_label(wchar_t * strwbuf, unsigned setting, size_t size)
|
||||
#else
|
||||
void rarch_settings_create_menu_item_label(char * str, unsigned setting, size_t size)
|
||||
#endif
|
||||
{
|
||||
#ifdef _XBOX
|
||||
char str[PATH_MAX];
|
||||
size_t SIZEOF_STR = sizeof(str);
|
||||
#else
|
||||
size_t SIZEOF_STR = size;
|
||||
#endif
|
||||
|
||||
switch (setting)
|
||||
{
|
||||
case S_LBL_ASPECT_RATIO:
|
||||
snprintf(str, SIZEOF_STR, "Aspect Ratio: %s", aspectratio_lut[g_console.aspect_ratio_index].name);
|
||||
break;
|
||||
case S_LBL_SHADER:
|
||||
snprintf(str, SIZEOF_STR, "Shader #1: %s", g_settings.video.cg_shader_path);
|
||||
break;
|
||||
case S_LBL_SHADER_2:
|
||||
snprintf(str, SIZEOF_STR, "Shader #2: %s", g_settings.video.second_pass_shader);
|
||||
break;
|
||||
case S_LBL_RARCH_VERSION:
|
||||
snprintf(str, SIZEOF_STR, "RetroArch %s", PACKAGE_VERSION);
|
||||
break;
|
||||
case S_LBL_SCALE_FACTOR:
|
||||
snprintf(str, SIZEOF_STR, "Scale Factor: %f (X) / %f (Y)", g_settings.video.fbo_scale_x, g_settings.video.fbo_scale_y);
|
||||
break;
|
||||
case S_LBL_ROTATION:
|
||||
snprintf(str, SIZEOF_STR, "Rotation: %s", rotation_lut[g_console.screen_orientation]);
|
||||
break;
|
||||
case S_LBL_LOAD_STATE_SLOT:
|
||||
snprintf(str, SIZEOF_STR, "Load State #%d", g_extern.state_slot);
|
||||
break;
|
||||
case S_LBL_SAVE_STATE_SLOT:
|
||||
snprintf(str, SIZEOF_STR, "Save State #%d", g_extern.state_slot);
|
||||
break;
|
||||
}
|
||||
|
||||
#ifdef _XBOX
|
||||
rarch_convert_char_to_wchar(strwbuf, str, size);
|
||||
#endif
|
||||
}
|
||||
@@ -0,0 +1,102 @@
|
||||
/* RetroArch - A frontend for libretro.
|
||||
* Copyright (C) 2010-2012 - Hans-Kristian Arntzen
|
||||
* Copyright (C) 2011-2012 - Daniel De Matteis
|
||||
*
|
||||
* RetroArch is free software: you can redistribute it and/or modify it under the terms
|
||||
* of the GNU General Public License as published by the Free Software Found-
|
||||
* ation, either version 3 of the License, or (at your option) any later version.
|
||||
*
|
||||
* RetroArch is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
|
||||
* without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
|
||||
* PURPOSE. See the GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along with RetroArch.
|
||||
* If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifndef CONSOLE_SETTINGS_H
|
||||
#define CONSOLE_SETTINGS_H
|
||||
|
||||
enum
|
||||
{
|
||||
S_DELAY_180 = 180,
|
||||
S_DELAY_270 = 270
|
||||
};
|
||||
|
||||
enum
|
||||
{
|
||||
S_ASPECT_RATIO_DECREMENT = 0,
|
||||
S_ASPECT_RATIO_INCREMENT,
|
||||
S_FRAME_ADVANCE,
|
||||
S_HW_TEXTURE_FILTER,
|
||||
S_HW_TEXTURE_FILTER_2,
|
||||
S_OVERSCAN_DECREMENT,
|
||||
S_OVERSCAN_INCREMENT,
|
||||
S_QUIT,
|
||||
S_RETURN_TO_DASHBOARD,
|
||||
S_RETURN_TO_GAME,
|
||||
S_RETURN_TO_LAUNCHER,
|
||||
S_RETURN_TO_MENU,
|
||||
S_ROTATION_DECREMENT,
|
||||
S_ROTATION_INCREMENT,
|
||||
S_REWIND,
|
||||
S_SAVESTATE_DECREMENT,
|
||||
S_SAVESTATE_INCREMENT,
|
||||
S_SCALE_ENABLED,
|
||||
S_SCALE_FACTOR_DECREMENT,
|
||||
S_SCALE_FACTOR_INCREMENT,
|
||||
S_START_RARCH,
|
||||
S_THROTTLE,
|
||||
S_TRIPLE_BUFFERING
|
||||
};
|
||||
|
||||
enum
|
||||
{
|
||||
S_DEF_ASPECT_RATIO = 0,
|
||||
S_DEF_HW_TEXTURE_FILTER,
|
||||
S_DEF_HW_TEXTURE_FILTER_2,
|
||||
S_DEF_OVERSCAN,
|
||||
S_DEF_ROTATION,
|
||||
S_DEF_THROTTLE,
|
||||
S_DEF_TRIPLE_BUFFERING,
|
||||
S_DEF_SAVE_STATE,
|
||||
S_DEF_SCALE_ENABLED,
|
||||
S_DEF_SCALE_FACTOR
|
||||
};
|
||||
|
||||
enum
|
||||
{
|
||||
S_MSG_CACHE_PARTITION = 0,
|
||||
S_MSG_CHANGE_CONTROLS,
|
||||
S_MSG_EXTRACTED_ZIPFILE,
|
||||
S_MSG_NOT_IMPLEMENTED,
|
||||
S_MSG_RESIZE_SCREEN,
|
||||
S_MSG_RESTART_RARCH,
|
||||
S_MSG_SELECT_LIBRETRO_CORE,
|
||||
S_MSG_SELECT_SHADER,
|
||||
S_MSG_SHADER_LOADING_SUCCEEDED
|
||||
};
|
||||
|
||||
enum
|
||||
{
|
||||
S_LBL_ASPECT_RATIO = 0,
|
||||
S_LBL_RARCH_VERSION,
|
||||
S_LBL_ROTATION,
|
||||
S_LBL_SHADER,
|
||||
S_LBL_SHADER_2,
|
||||
S_LBL_SCALE_FACTOR,
|
||||
S_LBL_LOAD_STATE_SLOT,
|
||||
S_LBL_SAVE_STATE_SLOT,
|
||||
};
|
||||
|
||||
void rarch_settings_change(unsigned setting);
|
||||
void rarch_settings_default(unsigned setting);
|
||||
void rarch_settings_msg(unsigned setting, unsigned delay);
|
||||
|
||||
#ifdef _XBOX
|
||||
void rarch_settings_create_menu_item_label(wchar_t * strwbuf, unsigned setting, size_t size);
|
||||
#else
|
||||
void rarch_settings_create_menu_item_label(char * str, unsigned setting, size_t size);
|
||||
#endif
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,246 @@
|
||||
/* RetroArch - A frontend for libretro.
|
||||
* Copyright (C) 2010-2012 - Hans-Kristian Arntzen
|
||||
* Copyright (C) 2011-2012 - Daniel De Matteis
|
||||
*
|
||||
* RetroArch is free software: you can redistribute it and/or modify it under the terms
|
||||
* of the GNU General Public License as published by the Free Software Found-
|
||||
* ation, either version 3 of the License, or (at your option) any later version.
|
||||
*
|
||||
* RetroArch is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
|
||||
* without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
|
||||
* PURPOSE. See the GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along with RetroArch.
|
||||
* If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifdef _XBOX
|
||||
#include <xtl.h>
|
||||
#endif
|
||||
#include "file_browser.h"
|
||||
|
||||
static int less_than_key(const void * a, const void * b)
|
||||
{
|
||||
DirectoryEntry * a_dir = (DirectoryEntry*)a;
|
||||
DirectoryEntry * b_dir = (DirectoryEntry*)b;
|
||||
|
||||
/* compare a directory to a file directory is always lesser than*/
|
||||
if ((a_dir->d_type == FS_TYPES_DIRECTORY && b_dir->d_type == FS_TYPES_FILE))
|
||||
return -1;
|
||||
else if (a_dir->d_type == FS_TYPES_FILE && b_dir->d_type == FS_TYPES_DIRECTORY)
|
||||
return 1;
|
||||
|
||||
return strcasecmp(a_dir->d_name, b_dir->d_name);
|
||||
}
|
||||
|
||||
static const char * filebrowser_get_extension(const char * filename)
|
||||
{
|
||||
const char * ext = strrchr(filename, '.');
|
||||
|
||||
if (ext)
|
||||
return ext+1;
|
||||
else
|
||||
return "";
|
||||
}
|
||||
|
||||
static void filebrowser_clear_current_entries(filebrowser_t * filebrowser)
|
||||
{
|
||||
for(uint32_t i = 0; i < MAX_FILE_LIMIT; i++)
|
||||
{
|
||||
filebrowser->cur[filebrowser->file_count].d_type = 0;
|
||||
filebrowser->cur[filebrowser->file_count].d_namlen = 0;
|
||||
strlcpy(filebrowser->cur[filebrowser->file_count].d_name, "\0", sizeof(filebrowser->cur[filebrowser->file_count].d_name));
|
||||
}
|
||||
}
|
||||
|
||||
static void filebrowser_parse_directory(filebrowser_t * filebrowser,
|
||||
const char * path, const char * extensions)
|
||||
{
|
||||
int error = 0;
|
||||
#if defined(_XBOX)
|
||||
filebrowser->file_count = 0;
|
||||
|
||||
WIN32_FIND_DATA ffd;
|
||||
HANDLE hFind = INVALID_HANDLE_VALUE;
|
||||
|
||||
char path_buf[PATH_MAX];
|
||||
|
||||
if (strlcpy(path_buf, path, sizeof(path_buf)) >= sizeof(path_buf))
|
||||
{
|
||||
error = 1;
|
||||
goto error;
|
||||
}
|
||||
if (strlcat(path_buf, "\\*", sizeof(path_buf)) >= sizeof(path_buf))
|
||||
{
|
||||
error = 1;
|
||||
goto error;
|
||||
}
|
||||
|
||||
hFind = FindFirstFile(path_buf, &ffd);
|
||||
if (hFind == INVALID_HANDLE_VALUE)
|
||||
{
|
||||
error = 1;
|
||||
goto error;
|
||||
}
|
||||
|
||||
do
|
||||
{
|
||||
strlcpy(filebrowser->dir[filebrowser->directory_stack_size], path, sizeof(filebrowser->dir[filebrowser->directory_stack_size]));
|
||||
bool found_dir = false;
|
||||
|
||||
if(!(ffd.dwFileAttributes & FS_TYPES_DIRECTORY))
|
||||
{
|
||||
char tmp_extensions[512];
|
||||
strlcpy(tmp_extensions, extensions, sizeof(tmp_extensions));
|
||||
const char * current_extension = filebrowser_get_extension(ffd.cFileName);
|
||||
bool found_rom = false;
|
||||
|
||||
if(current_extension)
|
||||
{
|
||||
char * pch = strtok(tmp_extensions, "|");
|
||||
while (pch != NULL)
|
||||
{
|
||||
if(strcmp(current_extension, pch) == 0)
|
||||
{
|
||||
found_rom = true;
|
||||
break;
|
||||
}
|
||||
pch = strtok(NULL, "|");
|
||||
}
|
||||
}
|
||||
|
||||
if(!found_rom)
|
||||
continue;
|
||||
}
|
||||
else if (ffd.dwFileAttributes & FS_TYPES_DIRECTORY)
|
||||
found_dir = true;
|
||||
|
||||
filebrowser->cur[filebrowser->file_count].d_type = found_dir ? FS_TYPES_DIRECTORY : FS_TYPES_FILE;
|
||||
snprintf(filebrowser->cur[filebrowser->file_count].d_name, sizeof(filebrowser->cur[filebrowser->file_count].d_name), ffd.cFileName);
|
||||
|
||||
filebrowser->file_count++;
|
||||
}while (FindNextFile(hFind, &ffd) != 0 && (filebrowser->file_count + 1) < MAX_FILE_LIMIT);
|
||||
#elif defined(__CELLOS_LV2__)
|
||||
int fd;
|
||||
|
||||
/* bad path*/
|
||||
if (strcmp(path,"") == 0)
|
||||
{
|
||||
error = 1;
|
||||
goto error;
|
||||
}
|
||||
|
||||
/* delete old path*/
|
||||
filebrowser_clear_current_entries(filebrowser);
|
||||
|
||||
if (cellFsOpendir(path, &fd) == CELL_FS_SUCCEEDED)
|
||||
{
|
||||
uint64_t nread = 0;
|
||||
|
||||
strlcpy(filebrowser->dir[filebrowser->directory_stack_size], path, sizeof(filebrowser->dir[filebrowser->directory_stack_size]));
|
||||
|
||||
filebrowser->file_count = 0;
|
||||
filebrowser->currently_selected = 0;
|
||||
|
||||
CellFsDirent dirent;
|
||||
|
||||
while (cellFsReaddir(fd, &dirent, &nread) == CELL_FS_SUCCEEDED)
|
||||
{
|
||||
if (nread == 0)
|
||||
break;
|
||||
|
||||
if ((dirent.d_type != FS_TYPES_FILE) && (dirent.d_type != FS_TYPES_DIRECTORY))
|
||||
continue;
|
||||
|
||||
if (dirent.d_type == FS_TYPES_DIRECTORY && !(strcmp(dirent.d_name, ".")))
|
||||
continue;
|
||||
|
||||
if (dirent.d_type == FS_TYPES_FILE)
|
||||
{
|
||||
char tmp_extensions[512];
|
||||
strlcpy(tmp_extensions, extensions, sizeof(tmp_extensions));
|
||||
const char * current_extension = filebrowser_get_extension(dirent.d_name);
|
||||
bool found_rom = false;
|
||||
|
||||
if(current_extension)
|
||||
{
|
||||
char * pch = strtok(tmp_extensions, "|");
|
||||
while (pch != NULL)
|
||||
{
|
||||
if(strcmp(current_extension, pch) == 0)
|
||||
{
|
||||
found_rom = true;
|
||||
break;
|
||||
}
|
||||
pch = strtok(NULL, "|");
|
||||
}
|
||||
}
|
||||
|
||||
if(!found_rom)
|
||||
continue;
|
||||
}
|
||||
|
||||
filebrowser->cur[filebrowser->file_count].d_type = dirent.d_type;
|
||||
filebrowser->cur[filebrowser->file_count].d_namlen = dirent.d_namlen;
|
||||
strlcpy(filebrowser->cur[filebrowser->file_count].d_name, dirent.d_name, sizeof(filebrowser->cur[filebrowser->file_count].d_name));
|
||||
|
||||
++filebrowser->file_count;
|
||||
}
|
||||
|
||||
cellFsClosedir(fd);
|
||||
}
|
||||
else
|
||||
{
|
||||
error = 1;
|
||||
goto error;
|
||||
}
|
||||
#endif
|
||||
qsort(filebrowser->cur, filebrowser->file_count, sizeof(DirectoryEntry), less_than_key);
|
||||
error:
|
||||
if(error)
|
||||
{
|
||||
RARCH_ERR("Failed to open directory: \"%s\"\n", path);
|
||||
}
|
||||
#ifdef _XBOX
|
||||
FindClose(hFind);
|
||||
#endif
|
||||
}
|
||||
|
||||
void filebrowser_new(filebrowser_t * filebrowser, const char * start_dir,
|
||||
const char * extensions)
|
||||
{
|
||||
filebrowser_clear_current_entries(filebrowser);
|
||||
filebrowser->directory_stack_size = 0;
|
||||
strlcpy(filebrowser->extensions, extensions, sizeof(filebrowser->extensions));
|
||||
|
||||
filebrowser_parse_directory(filebrowser, start_dir, filebrowser->extensions);
|
||||
}
|
||||
|
||||
|
||||
void filebrowser_reset_start_directory(filebrowser_t * filebrowser, const char * start_dir,
|
||||
const char * extensions)
|
||||
{
|
||||
filebrowser->directory_stack_size = 0;
|
||||
strlcpy(filebrowser->extensions, extensions, sizeof(filebrowser->extensions));
|
||||
|
||||
filebrowser_parse_directory(filebrowser, start_dir, filebrowser->extensions);
|
||||
}
|
||||
|
||||
void filebrowser_push_directory(filebrowser_t * filebrowser, const char * path,
|
||||
bool with_extension)
|
||||
{
|
||||
filebrowser->directory_stack_size++;
|
||||
if(with_extension)
|
||||
filebrowser_parse_directory(filebrowser, path, filebrowser->extensions);
|
||||
else
|
||||
filebrowser_parse_directory(filebrowser, path, "empty");
|
||||
}
|
||||
|
||||
void filebrowser_pop_directory (filebrowser_t * filebrowser)
|
||||
{
|
||||
if (filebrowser->directory_stack_size > 0)
|
||||
filebrowser->directory_stack_size--;
|
||||
|
||||
filebrowser_parse_directory(filebrowser, filebrowser->dir[filebrowser->directory_stack_size],
|
||||
filebrowser->extensions);
|
||||
}
|
||||
@@ -0,0 +1,104 @@
|
||||
/* RetroArch - A frontend for libretro.
|
||||
* Copyright (C) 2010-2012 - Hans-Kristian Arntzen
|
||||
* Copyright (C) 2011-2012 - Daniel De Matteis
|
||||
*
|
||||
* RetroArch is free software: you can redistribute it and/or modify it under the terms
|
||||
* of the GNU General Public License as published by the Free Software Found-
|
||||
* ation, either version 3 of the License, or (at your option) any later version.
|
||||
*
|
||||
* RetroArch is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
|
||||
* without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
|
||||
* PURPOSE. See the GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along with RetroArch.
|
||||
* If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifndef FILEBROWSER_H_
|
||||
#define FILEBROWSER_H_
|
||||
|
||||
#define MAXJOLIET 255
|
||||
|
||||
#include <stdint.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
#ifdef __CELLOS_LV2__
|
||||
#include <stdbool.h>
|
||||
#include <cell/cell_fs.h>
|
||||
#include <sys/types.h>
|
||||
#define FS_MAX_PATH 256
|
||||
#define FS_MAX_FS_PATH_LENGTH 255
|
||||
#define MAX_FILE_LIMIT 30000
|
||||
#elif defined(_XBOX)
|
||||
#define FS_MAX_PATH MAX_PATH
|
||||
#define FS_MAX_FS_PATH_LENGTH 2048
|
||||
#define MAX_FILE_LIMIT 4096
|
||||
#endif
|
||||
|
||||
#if defined(_XBOX)
|
||||
#define FS_TYPES_DIRECTORY (FILE_ATTRIBUTE_DIRECTORY)
|
||||
#define FS_TYPES_FILE (FILE_ATTRIBUTE_NORMAL)
|
||||
#elif defined(__CELLOS_LV2__)
|
||||
#define FS_TYPES_DIRECTORY (CELL_FS_TYPE_DIRECTORY)
|
||||
#define FS_TYPES_FILE (CELL_FS_TYPE_REGULAR)
|
||||
#endif
|
||||
|
||||
typedef struct {
|
||||
uint8_t d_type;
|
||||
uint8_t d_namlen;
|
||||
char d_name[FS_MAX_PATH];
|
||||
} DirectoryEntry;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
uint32_t file_count; /* amount of files in current dir*/
|
||||
uint32_t currently_selected; /* currently select browser entry*/
|
||||
uint32_t directory_stack_size;
|
||||
char dir[128][FS_MAX_FS_PATH_LENGTH]; /* info of the current directory*/
|
||||
DirectoryEntry cur[MAX_FILE_LIMIT]; /* current file listing*/
|
||||
char extensions[512]; /* allowed extensions*/
|
||||
} filebrowser_t;
|
||||
|
||||
void filebrowser_new(filebrowser_t * filebrowser, const char * start_dir, const char * extensions);
|
||||
void filebrowser_reset_start_directory(filebrowser_t * filebrowser, const char * start_dir, const char * extensions);
|
||||
void filebrowser_push_directory(filebrowser_t * filebrowser, const char * path, bool with_extension);
|
||||
void filebrowser_pop_directory (filebrowser_t * filebrowser);
|
||||
|
||||
#define FILEBROWSER_GET_CURRENT_DIRECTORY_NAME(filebrowser) (filebrowser.dir[filebrowser.directory_stack_size])
|
||||
#define FILEBROWSER_GET_CURRENT_DIRECTORY_FILE_COUNT(filebrowser) (filebrowser.file_count)
|
||||
#define FILEBROWSER_GOTO_ENTRY(filebrowser, i) filebrowser.currently_selected = i;
|
||||
|
||||
#define FILEBROWSER_INCREMENT_ENTRY(filebrowser) \
|
||||
{ \
|
||||
filebrowser.currently_selected++; \
|
||||
if (filebrowser.currently_selected >= filebrowser.file_count) \
|
||||
filebrowser.currently_selected = 0; \
|
||||
}
|
||||
|
||||
#define FILEBROWSER_INCREMENT_ENTRY_POINTER(filebrowser) \
|
||||
{ \
|
||||
filebrowser->currently_selected++; \
|
||||
if (filebrowser->currently_selected >= filebrowser->file_count) \
|
||||
filebrowser->currently_selected = 0; \
|
||||
}
|
||||
|
||||
#define FILEBROWSER_DECREMENT_ENTRY(filebrowser) \
|
||||
{ \
|
||||
filebrowser.currently_selected--; \
|
||||
if (filebrowser.currently_selected >= filebrowser.file_count) \
|
||||
filebrowser.currently_selected = filebrowser.file_count - 1; \
|
||||
}
|
||||
|
||||
#define FILEBROWSER_DECREMENT_ENTRY_POINTER(filebrowser) \
|
||||
{ \
|
||||
filebrowser->currently_selected--; \
|
||||
if (filebrowser->currently_selected >= filebrowser->file_count) \
|
||||
filebrowser->currently_selected = filebrowser->file_count - 1; \
|
||||
}
|
||||
|
||||
#define FILEBROWSER_GET_CURRENT_FILENAME(filebrowser) (filebrowser.cur[filebrowser.currently_selected].d_name)
|
||||
#define FILEBROWSER_GET_CURRENT_ENTRY_INDEX(filebrowser) (filebrowser.currently_selected)
|
||||
#define FILEBROWSER_IS_CURRENT_A_FILE(filebrowser) (filebrowser.cur[filebrowser.currently_selected].d_type == CELL_FS_TYPE_REGULAR)
|
||||
#define FILEBROWSER_IS_CURRENT_A_DIRECTORY(filebrowser) (filebrowser.cur[filebrowser.currently_selected].d_type == CELL_FS_TYPE_DIRECTORY)
|
||||
|
||||
#endif /* FILEBROWSER_H_ */
|
||||
Executable
BIN
Binary file not shown.
|
After Width: | Height: | Size: 192 KiB |
@@ -0,0 +1,30 @@
|
||||
/* RetroArch - A frontend for libretro.
|
||||
* Copyright (C) 2010-2012 - Hans-Kristian Arntzen
|
||||
* Copyright (C) 2011-2012 - Daniel De Matteis
|
||||
*
|
||||
* RetroArch is free software: you can redistribute it and/or modify it under the terms
|
||||
* of the GNU General Public License as published by the Free Software Found-
|
||||
* ation, either version 3 of the License, or (at your option) any later version.
|
||||
*
|
||||
* RetroArch is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
|
||||
* without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
|
||||
* PURPOSE. See the GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along with RetroArch.
|
||||
* If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
#ifndef _FUNC_HOOKS_H
|
||||
#define _FUNC_HOOKS_H
|
||||
|
||||
/*============================================================
|
||||
GENERAL
|
||||
============================================================ */
|
||||
#if defined(__CELLOS_LV2__) || defined(_XBOX) || defined(GEKKO)
|
||||
#define HAVE_GRIFFIN_OVERRIDE_VIDEO_FRAME_FUNC 1
|
||||
#endif
|
||||
|
||||
#define rarch_render_cached_frame() \
|
||||
const char *msg = msg_queue_pull(g_extern.msg_queue); \
|
||||
video_frame_func(g_extern.frame_cache.data, g_extern.frame_cache.width, g_extern.frame_cache.height, g_extern.frame_cache.pitch, msg);
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,240 @@
|
||||
/* RetroArch - A frontend for libretro.
|
||||
* Copyright (C) 2010-2012 - Hans-Kristian Arntzen
|
||||
* Copyright (C) 2011-2012 - Daniel De Matteis
|
||||
*
|
||||
* RetroArch is free software: you can redistribute it and/or modify it under the terms
|
||||
* of the GNU General Public License as published by the Free Software Found-
|
||||
* ation, either version 3 of the License, or (at your option) any later version.
|
||||
*
|
||||
* RetroArch is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
|
||||
* without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
|
||||
* PURPOSE. See the GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along with RetroArch.
|
||||
* If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#if defined(_XBOX)
|
||||
#include "../../msvc/msvc_compat.h"
|
||||
#endif
|
||||
|
||||
/*============================================================
|
||||
CONSOLE EXTENSIONS
|
||||
============================================================ */
|
||||
#include "../console_ext.c"
|
||||
#include "../console_settings.c"
|
||||
|
||||
#ifdef HAVE_LIBRETRO_MANAGEMENT
|
||||
#include "../libretro_mgmt.c"
|
||||
#endif
|
||||
|
||||
/*============================================================
|
||||
COMPATIBILITY
|
||||
============================================================ */
|
||||
#include "../../compat/compat.c"
|
||||
|
||||
/*============================================================
|
||||
CONFIG FILE
|
||||
============================================================ */
|
||||
#ifdef _XBOX
|
||||
#undef __RARCH_POSIX_STRING_H
|
||||
#undef __RARCH_MSVC_COMPAT_H
|
||||
#undef strcasecmp
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_CONFIGFILE
|
||||
#include "../../conf/config_file.c"
|
||||
#endif
|
||||
|
||||
#include "func_hooks.h"
|
||||
|
||||
/*============================================================
|
||||
VIDEO CONTEXT
|
||||
============================================================ */
|
||||
|
||||
#ifdef HAVE_VID_CONTEXT
|
||||
|
||||
#if defined(__CELLOS_LV2__)
|
||||
#include "../../gfx/context/ps3_ctx.c"
|
||||
#elif defined(_XBOX)
|
||||
#include "../../gfx/context/xdk360_ctx.c"
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
||||
/*============================================================
|
||||
VIDEO SHADERS
|
||||
============================================================ */
|
||||
|
||||
#ifdef HAVE_CG
|
||||
#include "../../gfx/shader_cg.c"
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_HLSL
|
||||
#include "../../gfx/shader_hlsl.c"
|
||||
#endif
|
||||
|
||||
/*============================================================
|
||||
VIDEO IMAGE
|
||||
============================================================ */
|
||||
|
||||
#if defined(__CELLOS_LV2__)
|
||||
#include "../../ps3/image.c"
|
||||
#endif
|
||||
|
||||
/*============================================================
|
||||
VIDEO DRIVER
|
||||
============================================================ */
|
||||
|
||||
#ifdef HAVE_OPENGL
|
||||
#include "../../gfx/gl.c"
|
||||
#endif
|
||||
|
||||
#if defined(_XBOX)
|
||||
#include "../../360/xdk360_video.cpp"
|
||||
#elif defined(GEKKO)
|
||||
#include "../../wii/video.c"
|
||||
#endif
|
||||
|
||||
/*============================================================
|
||||
FONTS
|
||||
============================================================ */
|
||||
|
||||
#if defined(__CELLOS_LV2__)
|
||||
#include "../../gfx/fonts/ps3_libdbgfont.c"
|
||||
#elif defined(_XBOX)
|
||||
#include "../../360/fonts.cpp"
|
||||
#elif defined(GEKKO)
|
||||
#include "../../gfx/fonts/fonts.c"
|
||||
#endif
|
||||
|
||||
/*============================================================
|
||||
INPUT
|
||||
============================================================ */
|
||||
#if defined(__CELLOS_LV2__)
|
||||
#include "../../ps3/ps3_input.c"
|
||||
#elif defined(_XBOX)
|
||||
#include "../../360/xdk360_input.c"
|
||||
#elif defined(GEKKO)
|
||||
#include "../../wii/input.c"
|
||||
#endif
|
||||
|
||||
/*============================================================
|
||||
STATE TRACKER
|
||||
============================================================ */
|
||||
#include "../../gfx/state_tracker.c"
|
||||
|
||||
/*============================================================
|
||||
DRIVERS
|
||||
============================================================ */
|
||||
#include "../../driver.c"
|
||||
|
||||
/*============================================================
|
||||
FIFO BUFFER
|
||||
============================================================ */
|
||||
#include "../../fifo_buffer.c"
|
||||
|
||||
/*============================================================
|
||||
AUDIO HERMITE
|
||||
============================================================ */
|
||||
#include "../../audio/hermite.c"
|
||||
|
||||
/*============================================================
|
||||
RSOUND
|
||||
============================================================ */
|
||||
#ifdef HAVE_RSOUND
|
||||
#include "../../console/librsound/librsound.c"
|
||||
#include "../../audio/rsound.c"
|
||||
#endif
|
||||
|
||||
/*============================================================
|
||||
AUDIO UTILS
|
||||
============================================================ */
|
||||
#include "../../audio/utils.c"
|
||||
|
||||
/*============================================================
|
||||
AUDIO
|
||||
============================================================ */
|
||||
#if defined(__CELLOS_LV2__)
|
||||
#include "../../ps3/ps3_audio.c"
|
||||
#elif defined(_XBOX)
|
||||
#include "../../360/xdk360_audio.cpp"
|
||||
#elif defined(GEKKO)
|
||||
#include "../../wii/audio.c"
|
||||
#endif
|
||||
|
||||
/*============================================================
|
||||
DYNAMIC
|
||||
============================================================ */
|
||||
#include "../../dynamic.c"
|
||||
|
||||
/*============================================================
|
||||
FILE
|
||||
============================================================ */
|
||||
#ifdef HAVE_FILEBROWSER
|
||||
#include "../fileio/file_browser.c"
|
||||
#endif
|
||||
#include "../../file.c"
|
||||
#include "../../file_path.c"
|
||||
|
||||
/*============================================================
|
||||
MESSAGE
|
||||
============================================================ */
|
||||
#include "../../message.c"
|
||||
|
||||
/*============================================================
|
||||
PATCH
|
||||
============================================================ */
|
||||
#include "../../patch.c"
|
||||
|
||||
/*============================================================
|
||||
SETTINGS
|
||||
============================================================ */
|
||||
#include "../../settings.c"
|
||||
|
||||
/*============================================================
|
||||
REWIND
|
||||
============================================================ */
|
||||
#include "../../rewind.c"
|
||||
|
||||
/*============================================================
|
||||
MAIN
|
||||
============================================================ */
|
||||
#if defined(__CELLOS_LV2__)
|
||||
#include "../../ps3/main.c"
|
||||
#elif defined(_XBOX)
|
||||
#include "../../360/main.c"
|
||||
#elif defined(GEKKO)
|
||||
#include "../../wii/main.c"
|
||||
#endif
|
||||
|
||||
/*============================================================
|
||||
RETROARCH
|
||||
============================================================ */
|
||||
#include "../../retroarch.c"
|
||||
|
||||
/*============================================================
|
||||
THREAD
|
||||
============================================================ */
|
||||
#ifndef GEKKO
|
||||
#include "../../thread.c"
|
||||
#endif
|
||||
|
||||
/*============================================================
|
||||
NETPLAY
|
||||
============================================================ */
|
||||
#ifdef HAVE_NETPLAY
|
||||
#include "../../netplay.c"
|
||||
#endif
|
||||
|
||||
/*============================================================
|
||||
MENU
|
||||
============================================================ */
|
||||
#if defined(__CELLOS_LV2__)
|
||||
#include "../../ps3/menu.c"
|
||||
#elif defined(_XBOX)
|
||||
#include "../../360/menu.cpp"
|
||||
#elif defined(GEKKO)
|
||||
#include "../rgui/rgui.c"
|
||||
#include "../rgui/list.c"
|
||||
#endif
|
||||
@@ -0,0 +1,106 @@
|
||||
/* RetroArch - A frontend for libretro.
|
||||
* Copyright (C) 2010-2012 - Hans-Kristian Arntzen
|
||||
* Copyright (C) 2011-2012 - Daniel De Matteis
|
||||
*
|
||||
* RetroArch is free software: you can redistribute it and/or modify it under the terms
|
||||
* of the GNU General Public License as published by the Free Software Found-
|
||||
* ation, either version 3 of the License, or (at your option) any later version.
|
||||
*
|
||||
* RetroArch is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
|
||||
* without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
|
||||
* PURPOSE. See the GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along with RetroArch.
|
||||
* If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
#define audio_init_func(device, rate, latency) driver.audio->init(device, rate, latency)
|
||||
#define audio_write_func(buf, size) driver.audio->write(driver.audio_data, buf, size)
|
||||
#define audio_stop_func() driver.audio->stop(driver.audio_data)
|
||||
#define audio_start_func() driver.audio->start(driver.audio_data)
|
||||
#define audio_set_nonblock_state_func(state) driver.audio->set_nonblock_state(driver.audio_data, state)
|
||||
#define audio_free_func() driver.audio->free(driver.audio_data)
|
||||
#define audio_use_float_func() driver.audio->use_float(driver.audio_data)
|
||||
#define audio_write_avail_func() driver.audio->write_avail(driver.audio_data)
|
||||
#define audio_buffer_size_func() driver.audio->buffer_size(driver.audio_data)
|
||||
|
||||
/*============================================================
|
||||
PLAYSTATION3
|
||||
============================================================ */
|
||||
|
||||
#ifdef __CELLOS_LV2__
|
||||
#define video_init_func(video_info, input, input_data) \
|
||||
gl_init(video_info, input, input_data)
|
||||
#define video_frame_func(data, width, height, pitch, msg) \
|
||||
gl_frame(driver.video_data, data, width, height, pitch, msg)
|
||||
#define video_set_nonblock_state_func(state) driver.video->set_nonblock_state(driver.video_data, state)
|
||||
#define video_alive_func() gl_alive(driver.video_data)
|
||||
#define video_focus_func() gl_focus(driver.video_data)
|
||||
#define video_xml_shader_func(path) driver.video->xml_shader(driver.video_data, path)
|
||||
#define video_free_func() gl_free(driver.video_data)
|
||||
#define video_set_rotation_func(rotation) gl_set_rotation(driver.video_data, rotation)
|
||||
#define video_set_aspect_ratio_func(aspectratio_idx) gfx_ctx_set_aspect_ratio(driver.video_data, aspectratio_idx)
|
||||
|
||||
#define gfx_ctx_window_has_focus() (true)
|
||||
#define gfx_ctx_swap_buffers() (psglSwap())
|
||||
|
||||
#define input_init_func() ps3_input_initialize()
|
||||
#define input_poll_func() ps3_input_poll(driver.input_data)
|
||||
#define input_input_state_func(snes_keybinds, port, device, index, id) \
|
||||
ps3_input_state(driver.input_data, snes_keybinds, port, device, index, id)
|
||||
#define input_key_pressed_func(key) ps3_key_pressed(driver.input_data, key)
|
||||
#define input_free_func() ps3_free_input(driver.input_data)
|
||||
|
||||
/*============================================================
|
||||
XBOX 360
|
||||
============================================================ */
|
||||
|
||||
#elif defined(_XBOX)
|
||||
|
||||
#define video_init_func(video_info, input, input_data) \
|
||||
xdk360_init(video_info, input, input_data)
|
||||
#define video_frame_func(data, width, height, pitch, msg) \
|
||||
xdk360_frame(driver.video_data, data, width, height, pitch, msg)
|
||||
#define video_set_nonblock_state_func(state) driver.video->set_nonblock_state(driver.video_data, state)
|
||||
#define video_alive_func() xdk360_alive(driver.video_data)
|
||||
#define video_focus_func() xdk360_focus(driver.video_data)
|
||||
#define video_xml_shader_func(path) driver.video->xml_shader(driver.video_data, path)
|
||||
#define video_free_func() xdk360_free(driver.video_data)
|
||||
#define video_set_rotation_func(rotation) xdk360_set_rotation(driver.video_data, rotation)
|
||||
#define video_set_aspect_ratio_func(aspectratio_idx) gfx_ctx_set_aspect_ratio(driver.video_data, aspectratio_idx)
|
||||
|
||||
#define gfx_ctx_window_has_focus() (true)
|
||||
#define gfx_ctx_swap_buffers() (d3d9->d3d_render_device->Present(NULL, NULL, NULL, NULL))
|
||||
|
||||
#define input_init_func() xdk360_input_initialize()
|
||||
#define input_poll_func() xdk360_input_poll(driver.input_data)
|
||||
#define input_input_state_func(snes_keybinds, port, device, index, id) \
|
||||
xdk360_input_state(driver.input_data, snes_keybinds, port, device, index, id)
|
||||
#define input_key_pressed_func(key) xdk360_key_pressed(driver.input_data, key)
|
||||
#define input_free_func() xdk360_free_input(driver.input_data)
|
||||
|
||||
/*============================================================
|
||||
GAMECUBE / WII
|
||||
============================================================ */
|
||||
|
||||
#elif defined(GEKKO)
|
||||
|
||||
#define video_init_func(video_info, input, input_data) wii_init(video_info, input, input_data)
|
||||
#define video_frame_func(data, width, height, pitch, msg) \
|
||||
wii_frame(driver.video_data, data, width, height, pitch, msg)
|
||||
#define video_set_nonblock_state_func(state) wii_set_nonblock_state(driver.video_data, state)
|
||||
#define video_alive_func() wii_alive(driver.video_data)
|
||||
#define video_focus_func() wii_focus(driver.video_data)
|
||||
#define video_xml_shader_func(path) driver.video->xml_shader(driver.video_data, path)
|
||||
#define video_free_func() wii_free(driver.video_data)
|
||||
#define video_set_rotation_func(orientation) wii_set_rotation(driver.video_data, orientation)
|
||||
#define video_set_aspect_ratio_func(aspectratio_idx) wii_set_aspect_ratio(driver.video_data, aspectratio_idx)
|
||||
|
||||
#define input_init_func() wii_input_initialize()
|
||||
#define input_poll_func() wii_input_poll(driver.input_data)
|
||||
#define input_input_state_func(snes_keybinds, port, device, index, id) \
|
||||
wii_input_state(driver.input_data, snes_keybinds, port, device, index, id)
|
||||
#define input_key_pressed_func(key) wii_key_pressed(driver.input_data, key)
|
||||
#define input_free_func() wii_free_input(driver.input_data)
|
||||
#define gfx_ctx_window_has_focus() (true)
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,58 @@
|
||||
/* RetroArch - A frontend for libretro.
|
||||
* Copyright (C) 2010-2012 - Hans-Kristian Arntzen
|
||||
* Copyright (C) 2011-2012 - Daniel De Matteis
|
||||
*
|
||||
* RetroArch is free software: you can redistribute it and/or modify it under the terms
|
||||
* of the GNU General Public License as published by the Free Software Found-
|
||||
* ation, either version 3 of the License, or (at your option) any later version.
|
||||
*
|
||||
* RetroArch is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
|
||||
* without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
|
||||
* PURPOSE. See the GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along with RetroArch.
|
||||
* If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifndef _RARCH_FUNC_HOOKS_H
|
||||
#define _RARCH_FUNC_HOOKS_H
|
||||
|
||||
/*============================================================
|
||||
PLAYSTATION3
|
||||
============================================================ */
|
||||
|
||||
#ifdef __CELLOS_LV2__
|
||||
|
||||
#define HAVE_GRIFFIN_OVERRIDE_AUDIO_FLUSH_FUNC 1
|
||||
|
||||
static bool audio_flush(const int16_t *data, size_t samples)
|
||||
{
|
||||
const float *output_data = NULL;
|
||||
unsigned output_frames = 0;
|
||||
|
||||
audio_convert_s16_to_float(g_extern.audio_data.data, data, samples);
|
||||
|
||||
struct resampler_data src_data = {0};
|
||||
src_data.data_in = g_extern.audio_data.data;
|
||||
src_data.data_out = g_extern.audio_data.outsamples;
|
||||
src_data.input_frames = (samples / 2);
|
||||
|
||||
src_data.ratio = g_extern.audio_data.src_ratio;
|
||||
if (g_extern.is_slowmotion)
|
||||
src_data.ratio *= g_settings.slowmotion_ratio;
|
||||
|
||||
resampler_process(g_extern.audio_data.source, &src_data);
|
||||
|
||||
output_data = g_extern.audio_data.outsamples;
|
||||
output_frames = src_data.output_frames;
|
||||
|
||||
if (audio_write_func(output_data, output_frames * sizeof(float) * 2) < 0)
|
||||
return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,136 @@
|
||||
/* RetroArch - A frontend for libretro.
|
||||
* Copyright (C) 2010-2012 - Hans-Kristian Arntzen
|
||||
* Copyright (C) 2011-2012 - Daniel De Matteis
|
||||
*
|
||||
* RetroArch is free software: you can redistribute it and/or modify it under the terms
|
||||
* of the GNU General Public License as published by the Free Software Found-
|
||||
* ation, either version 3 of the License, or (at your option) any later version.
|
||||
*
|
||||
* RetroArch is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
|
||||
* without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
|
||||
* PURPOSE. See the GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along with RetroArch.
|
||||
* If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
#include "console_ext.h"
|
||||
|
||||
const char *rarch_manage_libretro_install(const char *full_path, const char *path, const char *exe_ext)
|
||||
{
|
||||
int ret;
|
||||
const char *retstr = NULL;
|
||||
char tmp_path2[1024], tmp_pathnewfile[1024];
|
||||
|
||||
RARCH_LOG("Assumed path of CORE executable: [%s]\n", full_path);
|
||||
|
||||
if (path_file_exists(full_path))
|
||||
{
|
||||
// if CORE executable exists, this means we have just installed
|
||||
// a new libretro port and therefore we need to change it to a more
|
||||
// sane name.
|
||||
|
||||
rarch_console_name_from_id(tmp_path2, sizeof(tmp_path2));
|
||||
strlcat(tmp_path2, exe_ext, sizeof(tmp_path2));
|
||||
snprintf(tmp_pathnewfile, sizeof(tmp_pathnewfile), "%s%s", path, tmp_path2);
|
||||
|
||||
if (path_file_exists(tmp_pathnewfile))
|
||||
{
|
||||
// if libretro core already exists, this means we are
|
||||
// upgrading the libretro core - so delete pre-existing
|
||||
// file first.
|
||||
|
||||
RARCH_LOG("Upgrading emulator core...\n");
|
||||
#if defined(__CELLOS_LV2__)
|
||||
ret = cellFsUnlink(tmp_pathnewfile);
|
||||
if (ret == CELL_FS_SUCCEEDED)
|
||||
#elif defined(_XBOX)
|
||||
ret = DeleteFile(tmp_pathnewfile);
|
||||
if (ret != 0)
|
||||
#endif
|
||||
{
|
||||
RARCH_LOG("Succeeded in removing pre-existing libretro core: [%s].\n", tmp_pathnewfile);
|
||||
}
|
||||
else
|
||||
RARCH_ERR("Failed to remove pre-existing libretro core: [%s].\n", tmp_pathnewfile);
|
||||
}
|
||||
|
||||
//now attempt the renaming.
|
||||
#if defined(__CELLOS_LV2__)
|
||||
ret = cellFsRename(full_path, tmp_pathnewfile);
|
||||
|
||||
if (ret != CELL_FS_SUCCEEDED)
|
||||
#elif defined(_XBOX)
|
||||
ret = MoveFileExA(full_path, tmp_pathnewfile, NULL);
|
||||
if (ret == 0)
|
||||
#endif
|
||||
{
|
||||
RARCH_ERR("Failed to rename CORE executable.\n");
|
||||
}
|
||||
else
|
||||
{
|
||||
RARCH_LOG("Libsnes core [%s] renamed to: [%s].\n", full_path, tmp_pathnewfile);
|
||||
retstr = tmp_pathnewfile;
|
||||
goto done;
|
||||
}
|
||||
}
|
||||
|
||||
RARCH_WARN("CORE executable was not found, or some other errors occurred. Will attempt to load libretro core path from config file.\n");
|
||||
done:
|
||||
return retstr;
|
||||
}
|
||||
|
||||
const char *rarch_manage_libretro_set_first_file(const char *libretro_path, const char * exe_ext)
|
||||
{
|
||||
//We need to set libretro to the first entry in the cores
|
||||
//directory so that it will be saved to the config file
|
||||
|
||||
char ** dir_list = dir_list_new(libretro_path, exe_ext);
|
||||
|
||||
const char * retstr = NULL;
|
||||
const char * first_exe;
|
||||
|
||||
if (!dir_list)
|
||||
{
|
||||
RARCH_ERR("Couldn't read directory.\n");
|
||||
goto error;
|
||||
}
|
||||
|
||||
first_exe = dir_list[0];
|
||||
|
||||
if(first_exe)
|
||||
{
|
||||
#ifdef _XBOX
|
||||
char fname_tmp[PATH_MAX];
|
||||
fill_pathname_base(fname_tmp, first_exe, sizeof(fname_tmp));
|
||||
|
||||
if(strcmp(fname_tmp, "RetroArch-Salamander.xex") == 0)
|
||||
{
|
||||
RARCH_WARN("First entry is RetroArch Salamander itself, increment entry by one and check if it exists.\n");
|
||||
first_exe = dir_list[1];
|
||||
fill_pathname_base(fname_tmp, first_exe, sizeof(fname_tmp));
|
||||
|
||||
if(!first_exe)
|
||||
{
|
||||
RARCH_ERR("Unlikely error happened - no second entry - no choice but to set it to RetroArch Salamander\n");
|
||||
first_exe = dir_list[0];
|
||||
fill_pathname_base(fname_tmp, first_exe, sizeof(fname_tmp));
|
||||
}
|
||||
}
|
||||
|
||||
retstr = fname_tmp;
|
||||
#else
|
||||
retstr = first_exe;
|
||||
#endif
|
||||
RARCH_LOG("Set first entry in libretro core dir to libretro path: [%s].\n", retstr);
|
||||
goto end;
|
||||
}
|
||||
|
||||
error:
|
||||
RARCH_ERR("Failed to set first entry to libretro path.\n");
|
||||
end:
|
||||
dir_list_free(dir_list);
|
||||
return retstr;
|
||||
}
|
||||
Loaded 100 of 285 files, more files were not shown because too many files have changed in this diff.
Show more
Reference in new issue
Block a user