mirror of
https://github.com/kanjitalk755/macemu.git
synced 2025-04-09 20:39:19 +00:00
Compare commits
694 Commits
2.5_201907
...
master
Author | SHA1 | Date | |
---|---|---|---|
|
f0bbcb0c85 | ||
|
a1c7fd67a7 | ||
|
c669f71706 | ||
|
583d890b93 | ||
|
bc1e51f80e | ||
|
76c1c997ac | ||
|
b932545c7b | ||
|
8699662c4d | ||
|
6ddff7bc02 | ||
|
6c30a1a0b8 | ||
|
067e89ce6d | ||
|
ca8e10b2df | ||
|
70507f89da | ||
|
d66b125513 | ||
|
197068b6f8 | ||
|
f43d2193f1 | ||
|
d80663fe37 | ||
|
c6474010b5 | ||
|
0655501e55 | ||
|
308c407e03 | ||
|
622f0f4dd9 | ||
|
a267492d79 | ||
|
42a87bfe84 | ||
|
39f59dab3b | ||
|
bb2ad33ba4 | ||
|
e9c5e21f3c | ||
|
e5d6fe4e3c | ||
|
618419ff0f | ||
|
3ec0b33c4c | ||
|
01dc76b0f4 | ||
|
e8255c59a4 | ||
|
cb42bdf64d | ||
|
05cd8b0a8d | ||
|
2efce1ddd0 | ||
|
a223adc4e1 | ||
|
d29a6f3d03 | ||
|
1a4d4d8149 | ||
|
e47c29272f | ||
|
c0c669a00e | ||
|
f1f7e96d38 | ||
|
63e28afb8e | ||
|
484095cad5 | ||
|
1d86c9a751 | ||
|
47e9921bb7 | ||
|
ca33a19cfd | ||
|
61575d2d58 | ||
|
877aaf4d03 | ||
|
5d11cb7d49 | ||
|
c3813dd752 | ||
|
58706f582c | ||
|
772252f24c | ||
|
9175c4285b | ||
|
5b72b58226 | ||
|
edfe4bc6b6 | ||
|
2816889d2e | ||
|
629d0d0874 | ||
|
1bedfac618 | ||
|
3498324bdb | ||
|
51e3a90866 | ||
|
3eff56b91d | ||
|
420a51ce6e | ||
|
5b8d1064e5 | ||
|
bc5b8237ed | ||
|
36b5206b90 | ||
|
2a859c323b | ||
|
08877b7aeb | ||
|
749655f063 | ||
|
774c537356 | ||
|
40b9e5ce68 | ||
|
55c5ecb464 | ||
|
b459223aa9 | ||
|
5aacd4477c | ||
|
9b0ea7ce2c | ||
|
866aa59088 | ||
|
1de5be48ed | ||
|
28b211bb43 | ||
|
8e4d39b8c5 | ||
|
075db1949b | ||
|
64cd8155e0 | ||
|
7ae4a71c6c | ||
|
d59278dd96 | ||
|
f39b6e8e62 | ||
|
64a72eaea2 | ||
|
97bbac8770 | ||
|
fd81480959 | ||
|
44d3df3c4b | ||
|
d57d0689c0 | ||
|
e013a88546 | ||
|
3d1cffdc20 | ||
|
2a1353896f | ||
|
96e7f8566c | ||
|
53a47339c6 | ||
|
62b934e641 | ||
|
43bc4ce944 | ||
|
f396254b62 | ||
|
77b9ebdf5b | ||
|
d59eed0cfc | ||
|
1bcc32cd0c | ||
|
d3aa80f703 | ||
|
4c11b34872 | ||
|
02a6762d2e | ||
|
95e2632f6a | ||
|
7665c0637d | ||
|
aa77d0269f | ||
|
3f46296a36 | ||
|
678fffa5f5 | ||
|
666797fdee | ||
|
30a0789f4d | ||
|
e35f659764 | ||
|
52c5db16e4 | ||
|
62b88fa0ae | ||
|
1928f2ecef | ||
|
eeb50415ca | ||
|
79f2e7e8e4 | ||
|
2148b0b636 | ||
|
03e1593387 | ||
|
eb1545a147 | ||
|
16c265c515 | ||
|
8c1580ebc8 | ||
|
208c2645da | ||
|
94b687a626 | ||
|
bcc06d8d33 | ||
|
80d1946efd | ||
|
d1b288ba19 | ||
|
2658de9556 | ||
|
e517d73f0c | ||
|
b63490dadb | ||
|
bc5544e506 | ||
|
4b6beeca17 | ||
|
5d84c6d0fc | ||
|
d7c030312d | ||
|
be389a9f11 | ||
|
a07cc8ae56 | ||
|
293ef33a28 | ||
|
979523b5ca | ||
|
076390e911 | ||
|
db897d0d42 | ||
|
e12789a57e | ||
|
aa9f112de3 | ||
|
784ac7bb7e | ||
|
45e3bd1d3e | ||
|
08707d3a25 | ||
|
0a1d9c35bf | ||
|
3176aa887d | ||
|
9088a674ad | ||
|
1d8dd979ab | ||
|
1ddb7d3a42 | ||
|
e059b64ac8 | ||
|
b6d62c2f14 | ||
|
9395e119af | ||
|
021bb50149 | ||
|
3d49e9790b | ||
|
19308135c3 | ||
|
2533f7ac05 | ||
|
9a7751f1a2 | ||
|
0942bdcbf9 | ||
|
d2c2647e3a | ||
|
1d8e348e4b | ||
|
81bdda2a5b | ||
|
e90180a2c3 | ||
|
a94a41885b | ||
|
6f94fdd7b0 | ||
|
51fc1905c4 | ||
|
c4c153c49c | ||
|
d66da33874 | ||
|
c4a22a51d6 | ||
|
1199f8115e | ||
|
ef3f61c30d | ||
|
36de3833bf | ||
|
aa6f09ec7a | ||
|
5739ba9e8a | ||
|
cfec811999 | ||
|
5915d869fa | ||
|
78a4e7212b | ||
|
92c4c72000 | ||
|
0365386fa1 | ||
|
d6112f4a30 | ||
|
ed3decddf1 | ||
|
d4ec4e5323 | ||
|
1a2d818e47 | ||
|
db877c0443 | ||
|
4217fc73cd | ||
|
b3ebcd595c | ||
|
3f7896976a | ||
|
ae9d917d5e | ||
|
0118e99764 | ||
|
cb67534d28 | ||
|
f61701df3c | ||
|
4b58ce3ea8 | ||
|
c727bc0df7 | ||
|
fdeb8617da | ||
|
6da609938e | ||
|
aaf67fd59a | ||
|
af96a51acb | ||
|
bf784a2c30 | ||
|
094995722b | ||
|
604baaa289 | ||
|
2a74fdaab6 | ||
|
1dd1d2713d | ||
|
01ba8564ed | ||
|
d284e9976b | ||
|
7482de353b | ||
|
3f00759e54 | ||
|
a9d1f35cdf | ||
|
0083bc7ea7 | ||
|
2fa17a0783 | ||
|
811dddf70b | ||
|
29d0ea13ae | ||
|
249dfc84ae | ||
|
4c1c549ed6 | ||
|
1b36e7e118 | ||
|
ffb525800b | ||
|
3b7a89aad9 | ||
|
4724ce7aee | ||
|
95f1d46bae | ||
|
92778586de | ||
|
988eef8c5c | ||
|
cfb9d5a501 | ||
|
05adbff2f5 | ||
|
1de48de65d | ||
|
36b2862d21 | ||
|
e28a9fc3a9 | ||
|
6edec590ab | ||
|
75cdbd1d7b | ||
|
bfad0d3bba | ||
|
dae2be8c48 | ||
|
177a297527 | ||
|
b1ab353085 | ||
|
4ac4cbba45 | ||
|
ed86a18497 | ||
|
481b675e1a | ||
|
befe6d2db0 | ||
|
03ed87c966 | ||
|
4b1bc7c38c | ||
|
756021f267 | ||
|
5777129302 | ||
|
d9e0761bd9 | ||
|
11e88dd94f | ||
|
41648c23c5 | ||
|
d36be9168d | ||
|
4f94ef52c1 | ||
|
f017f9df58 | ||
|
5900e4895a | ||
|
9009a2741f | ||
|
d7e93d8f37 | ||
|
2e9eea3201 | ||
|
d03303cdf7 | ||
|
b4be0cdbb2 | ||
|
45578ddd45 | ||
|
e933e7885f | ||
|
2666bef882 | ||
|
81ccbfa1e7 | ||
|
a66b73a516 | ||
|
425dac6a7c | ||
|
d4baa318e4 | ||
|
1f5465ad77 | ||
|
fcf2c1d9b6 | ||
|
0f7f1543ed | ||
|
732029a512 | ||
|
3b1868ae56 | ||
|
86665c4c30 | ||
|
6285165090 | ||
|
789a39a2c6 | ||
|
2ea84d86c7 | ||
|
e069d84f5b | ||
|
f07b34a451 | ||
|
33c3419b08 | ||
|
c359aabc2d | ||
|
d993158df8 | ||
|
2a5ac90370 | ||
|
d05e5ab711 | ||
|
88a1fb2921 | ||
|
44f6eff928 | ||
|
a3534d2eea | ||
|
f1502fb6bd | ||
|
a5064455cb | ||
|
f385c22ed2 | ||
|
ad6047ea24 | ||
|
a722785575 | ||
|
b2df4fed1f | ||
|
ab586a5a09 | ||
|
90edd35246 | ||
|
cce0ed4c87 | ||
|
763fe81f0d | ||
|
0538eb0cc0 | ||
|
56343905e3 | ||
|
ef2f8724fe | ||
|
15f56749ba | ||
|
ea3832423c | ||
|
d346521b92 | ||
|
9621850735 | ||
|
4d16bb88b4 | ||
|
42e70e85c6 | ||
|
6385243609 | ||
|
bdcc9d2da4 | ||
|
1de3d694f2 | ||
|
ac68d68920 | ||
|
5d1bfd1059 | ||
|
e9a9573a20 | ||
|
c28a00f58a | ||
|
420dc1d504 | ||
|
ba89fc7a72 | ||
|
78fdb44d02 | ||
|
bc9c7675f9 | ||
|
caf10f1223 | ||
|
5862662bc9 | ||
|
e42b8f6076 | ||
|
ce00063701 | ||
|
164aa8c3fe | ||
|
9cf0c98dd6 | ||
|
1d710a0cad | ||
|
1aaeaf05c4 | ||
|
65028aec4a | ||
|
8a28ad6e39 | ||
|
4f0743562e | ||
|
49eee29597 | ||
|
20d2de95ce | ||
|
a39eff553c | ||
|
e750aecafe | ||
|
72989fffe2 | ||
|
176da65363 | ||
|
8064215081 | ||
|
7471c357c3 | ||
|
ce3e2f3693 | ||
|
6d3fbba4cd | ||
|
65772919a1 | ||
|
623abaa243 | ||
|
2e5654e583 | ||
|
2f1f196251 | ||
|
39cbc73a9f | ||
|
e75d2ca5d6 | ||
|
09046e0a2f | ||
|
4cf65a3faf | ||
|
fbddf063cb | ||
|
89e8a05815 | ||
|
556ec0cf80 | ||
|
8ebc4c90c3 | ||
|
73fc469c4c | ||
|
5620ef8c43 | ||
|
b539de9753 | ||
|
3f4eed670f | ||
|
0fd17a98ff | ||
|
69bf439fac | ||
|
144b117886 | ||
|
6d92f13bcd | ||
|
cad8df587d | ||
|
eb9142ac14 | ||
|
0c8529eca1 | ||
|
436c5df15f | ||
|
cadd3350ea | ||
|
f198632834 | ||
|
85f8971d8d | ||
|
497b5bc5a9 | ||
|
e00c6f2091 | ||
|
b6725730f5 | ||
|
6f6e9b8d82 | ||
|
d684527b27 | ||
|
6c38946bf0 | ||
|
0d213f9d00 | ||
|
c151e24bb8 | ||
|
6a88d08551 | ||
|
a179f00a62 | ||
|
62081d50d1 | ||
|
faeb5fa2e1 | ||
|
ff0a825356 | ||
|
6d74ff5600 | ||
|
5163e17f14 | ||
|
a1ef6be18a | ||
|
a453ae105a | ||
|
d7215df688 | ||
|
cff2024c2e | ||
|
0df082d4e1 | ||
|
991496a4f4 | ||
|
c0ceb74931 | ||
|
d547db0648 | ||
|
d0b3dcd623 | ||
|
271b7322d3 | ||
|
6b4cc38de6 | ||
|
c8c1a76381 | ||
|
af8e91f446 | ||
|
b1a7f71ef4 | ||
|
a897561c11 | ||
|
85da18e38f | ||
|
c044312b3c | ||
|
0a79f5d1b1 | ||
|
6c20f2c4d9 | ||
|
87d4660aa6 | ||
|
0b9b6401d6 | ||
|
3ce86cee1f | ||
|
a14362b183 | ||
|
cc5d99431f | ||
|
1892cf0a7e | ||
|
73f194f422 | ||
|
232efdaa8c | ||
|
edf8d14f09 | ||
|
83d7702f28 | ||
|
43cb7718e6 | ||
|
d20ba5d179 | ||
|
dd9cfec0e7 | ||
|
02c037b5cb | ||
|
ca9191fcb1 | ||
|
561f1dfcde | ||
|
9708089c1e | ||
|
37b36ef332 | ||
|
4e98699ee1 | ||
|
be17ba9044 | ||
|
7313b0284c | ||
|
d851a65548 | ||
|
6de9a5032d | ||
|
21c16f991e | ||
|
3cf23176f6 | ||
|
25e2d4af6f | ||
|
40e2d3d84b | ||
|
833f21c225 | ||
|
2a904af8e7 | ||
|
177555e0d1 | ||
|
95437fbf89 | ||
|
09429e6021 | ||
|
07880c76ed | ||
|
98e12fbc2e | ||
|
d58aa827a4 | ||
|
722b777ee8 | ||
|
3861177919 | ||
|
6f87eaca84 | ||
|
92a1ee2128 | ||
|
4b93738773 | ||
|
ec032ffd75 | ||
|
64b38dbec8 | ||
|
413190d12f | ||
|
0eae77599e | ||
|
4da2082c07 | ||
|
bb5caf093a | ||
|
565c133662 | ||
|
e5c4699923 | ||
|
639f05da7e | ||
|
d853f9abae | ||
|
ba111a5cb7 | ||
|
bb080a262e | ||
|
b4b652d696 | ||
|
d1fcff0a08 | ||
|
792ad5ccff | ||
|
ffee1ebad2 | ||
|
6985ad67fe | ||
|
630f4ffafb | ||
|
1f2b35fef2 | ||
|
d906fb23b0 | ||
|
7c6b9a67f6 | ||
|
1da83854b0 | ||
|
29bb3d5a5a | ||
|
13017f711f | ||
|
82524ba034 | ||
|
2e96512f26 | ||
|
5f1b41eb42 | ||
|
03ebc5375b | ||
|
8f12a0fffb | ||
|
7513fab5ad | ||
|
342fbbce34 | ||
|
5b31736785 | ||
|
478fc39650 | ||
|
d7fb0ac298 | ||
|
8124b61d2b | ||
|
4191a86895 | ||
|
c7a7e034ed | ||
|
2c8678417c | ||
|
059d88ce75 | ||
|
12ac0d3032 | ||
|
ed5f7f22b8 | ||
|
7441d04a28 | ||
|
3e32a6da32 | ||
|
47fca465ba | ||
|
084a8fbd74 | ||
|
1775fb3776 | ||
|
80399941b2 | ||
|
a5e7e80cda | ||
|
c3ccdcec5d | ||
|
30cf26e1f6 | ||
|
66a69dc79b | ||
|
6d522db16c | ||
|
245da3b142 | ||
|
89bcd3dc3e | ||
|
2595059146 | ||
|
bae7a4d16b | ||
|
e63c6b91dc | ||
|
40f6c77775 | ||
|
7e83b9c49e | ||
|
a21ad0d7c4 | ||
|
98f3cab953 | ||
|
ef57fd2c5f | ||
|
6f4da45eeb | ||
|
864b4a1652 | ||
|
b49d9b7485 | ||
|
03f5cc8c79 | ||
|
0b38469385 | ||
|
d30528795b | ||
|
bdf5a276d3 | ||
|
56665d30a3 | ||
|
16081b2878 | ||
|
18701c97df | ||
|
8e88e462ee | ||
|
e6cd178881 | ||
|
1bfb0e94a3 | ||
|
9ef2f87adb | ||
|
dc8bb7e2a3 | ||
|
d28599f49d | ||
|
a46759990d | ||
|
5cbf07e9f5 | ||
|
b0bdceac34 | ||
|
b2d281e5ab | ||
|
f13f25db3e | ||
|
607f4ed354 | ||
|
9895200f79 | ||
|
23da9e72eb | ||
|
bebeacc895 | ||
|
8e110b063c | ||
|
eb722fc799 | ||
|
7eb7a477d0 | ||
|
a01387b1af | ||
|
a528b0a40f | ||
|
cbad6f95ea | ||
|
9a905723db | ||
|
8a4b84b9d7 | ||
|
7790aa7e0c | ||
|
5670c82b0d | ||
|
c6e1af7ff4 | ||
|
767b97311b | ||
|
617a723a16 | ||
|
0e01e5c91e | ||
|
27d3d93b7c | ||
|
c0dfecdd1a | ||
|
8ca7815baf | ||
|
946f4bb77d | ||
|
b3c4d46ca9 | ||
|
ecef51bc47 | ||
|
c4956c40f8 | ||
|
6fe0d3ab7c | ||
|
573adb507f | ||
|
9dabd45086 | ||
|
2a6dc7e328 | ||
|
40cb4bf236 | ||
|
12f8469172 | ||
|
d936e9938d | ||
|
a667dc9787 | ||
|
ef2f205d6b | ||
|
cd269a9ce1 | ||
|
f1b0a20b37 | ||
|
aeb585527d | ||
|
a4a2c88ed7 | ||
|
1918557e78 | ||
|
00f02d9d0c | ||
|
59ce931955 | ||
|
f9eae2025f | ||
|
7062e864c8 | ||
|
e4ee28b199 | ||
|
0ad7a968ba | ||
|
1601829d22 | ||
|
ef1569b4d1 | ||
|
831e7a2268 | ||
|
8b44b00da3 | ||
|
837c82d8b8 | ||
|
07e9db881c | ||
|
7c61312974 | ||
|
744df7adf3 | ||
|
28e0485156 | ||
|
7b13571587 | ||
|
c4570fe272 | ||
|
6d2acbb07b | ||
|
d83c53437e | ||
|
ccf38a4005 | ||
|
f86b9b2abd | ||
|
bb69145861 | ||
|
1a875b1c10 | ||
|
899734d81d | ||
|
57b3f7cf21 | ||
|
c23967b03b | ||
|
eb35678f0d | ||
|
19033a4a39 | ||
|
f5b277548b | ||
|
7ad9ab0da2 | ||
|
2e001f465e | ||
|
507508b66d | ||
|
36b6d0769b | ||
|
cfcfde0480 | ||
|
63ddee1be1 | ||
|
193a7d56c5 | ||
|
b5fbba6e53 | ||
|
9dc485c56a | ||
|
67dd2e6676 | ||
|
71cbb23b42 | ||
|
35439819d3 | ||
|
281a8a9f68 | ||
|
18a908c770 | ||
|
a84735d3e9 | ||
|
02c0627452 | ||
|
9817848482 | ||
|
ae6d8239db | ||
|
75b333f805 | ||
|
45f57ceca1 | ||
|
f07cc69531 | ||
|
28cd764a31 | ||
|
447c7b365d | ||
|
9a18393fc5 | ||
|
539e436893 | ||
|
35e6d4fcdf | ||
|
f7da6ba4e5 | ||
|
2ba2d12f8b | ||
|
f171c611c2 | ||
|
8e9fa50385 | ||
|
96a42689fd | ||
|
858f8257a6 | ||
|
977056a075 | ||
|
03fc337242 | ||
|
28bc58ccd2 | ||
|
48a41966fd | ||
|
730ca109b7 | ||
|
fcdfd2f799 | ||
|
a489b71bb2 | ||
|
6bfe17c3fc | ||
|
2a691ce7d4 | ||
|
c7594f569a | ||
|
64d6c0668f | ||
|
e4c34683a4 | ||
|
ff2dc11f09 | ||
|
2bcfae861f | ||
|
01052ca89d | ||
|
9a3bd0b258 | ||
|
a25325fc7d | ||
|
6267af0315 | ||
|
668c2ba107 | ||
|
143b0827dd | ||
|
5d77f86575 | ||
|
507813529e | ||
|
e583d05868 | ||
|
242e8af3a7 | ||
|
2bc581d4f6 | ||
|
cf406ec953 | ||
|
76c5a97efe | ||
|
ddf1bcf094 | ||
|
0c622863cf | ||
|
30fdd103a2 | ||
|
50c98de60f | ||
|
320fae37a4 | ||
|
e4332cc72a | ||
|
5f04c95b79 | ||
|
f7023246d9 | ||
|
90b65715ae | ||
|
8c0a84c536 | ||
|
e99d4e579c | ||
|
8353a9ed44 | ||
|
77e20bda2a | ||
|
1758ef58b5 | ||
|
1bf6e93461 | ||
|
023251dee1 | ||
|
76d285a6f2 | ||
|
c4b1b1937e | ||
|
dee3f7e1c5 | ||
|
1d84d40518 | ||
|
7710322fd3 | ||
|
fcc1598086 | ||
|
b8fb05fbd0 | ||
|
24005dc4ed | ||
|
b1270264a1 | ||
|
4f162dc6e3 | ||
|
3c6788fd26 | ||
|
c01bd008db | ||
|
1c99d52b91 | ||
|
c4276955ba | ||
|
45a34e2763 | ||
|
b609065bc4 | ||
|
3583b00a77 | ||
|
e08090095f | ||
|
9aec39d3cb | ||
|
b7cfe89445 | ||
|
ce68f366cb | ||
|
eedf6880db | ||
|
8a02128473 | ||
|
5db556214c | ||
|
fc8835aa6f | ||
|
8f863effbc | ||
|
5aa782acc0 | ||
|
f994087291 | ||
|
19b53082a3 | ||
|
c939be2d2d | ||
|
531b1d7df4 | ||
|
0e667be7be | ||
|
15e47a1f07 | ||
|
241162f261 | ||
|
e91a03f40f | ||
|
57b9ad0d95 | ||
|
f1c78e659c | ||
|
01ba04139f | ||
|
94b790728e | ||
|
cf3b2786ae | ||
|
a250b40c80 | ||
|
772bb53d88 |
20
.travis.yml
20
.travis.yml
@ -1,20 +0,0 @@
|
||||
language: cpp
|
||||
|
||||
matrix:
|
||||
include:
|
||||
- os: linux
|
||||
dist: trusty
|
||||
sudo: required
|
||||
compiler: gcc
|
||||
|
||||
addons:
|
||||
apt:
|
||||
packages:
|
||||
- libsdl1.2-dev
|
||||
- libgtk2.0-dev
|
||||
|
||||
script:
|
||||
- cd BasiliskII/src/Unix
|
||||
- NO_CONFIGURE=1 ./autogen.sh
|
||||
- ./configure --enable-sdl-video --enable-sdl-audio --disable-vosf --disable-jit-compiler --with-x --with-gtk --with-mon
|
||||
- make -j 4
|
153
BasiliskII/src/CrossPlatform/sigsegv.cpp
Executable file → Normal file
153
BasiliskII/src/CrossPlatform/sigsegv.cpp
Executable file → Normal file
@ -274,13 +274,20 @@ static void powerpc_decode_instruction(instruction_t *instruction, unsigned int
|
||||
#define SIGSEGV_REGISTER_FILE ((unsigned long *)SIGSEGV_CONTEXT_REGS), SIGSEGV_SPARC_GWINDOWS, SIGSEGV_SPARC_RWINDOW
|
||||
#define SIGSEGV_SKIP_INSTRUCTION sparc_skip_instruction
|
||||
#endif
|
||||
#if defined(__i386__)
|
||||
#if (defined(i386) || defined(__i386__))
|
||||
#include <sys/regset.h>
|
||||
#define SIGSEGV_CONTEXT_REGS (((ucontext_t *)scp)->uc_mcontext.gregs)
|
||||
#define SIGSEGV_FAULT_INSTRUCTION SIGSEGV_CONTEXT_REGS[EIP]
|
||||
#define SIGSEGV_REGISTER_FILE (SIGSEGV_REGISTER_TYPE *)SIGSEGV_CONTEXT_REGS
|
||||
#define SIGSEGV_SKIP_INSTRUCTION ix86_skip_instruction
|
||||
#endif
|
||||
#if (defined(x86_64) || defined(__x86_64__))
|
||||
#include <sys/regset.h>
|
||||
#define SIGSEGV_CONTEXT_REGS (((ucontext_t *)scp)->uc_mcontext.gregs)
|
||||
#define SIGSEGV_FAULT_INSTRUCTION SIGSEGV_CONTEXT_REGS[REG_RIP]
|
||||
#define SIGSEGV_REGISTER_FILE (SIGSEGV_REGISTER_TYPE *)SIGSEGV_CONTEXT_REGS
|
||||
#define SIGSEGV_SKIP_INSTRUCTION ix86_skip_instruction
|
||||
#endif
|
||||
#endif
|
||||
#if defined(__FreeBSD__) || defined(__OpenBSD__)
|
||||
#if (defined(i386) || defined(__i386__))
|
||||
@ -302,6 +309,12 @@ static void powerpc_decode_instruction(instruction_t *instruction, unsigned int
|
||||
#define SIGSEGV_FAULT_INSTRUCTION SIGSEGV_CONTEXT_REGS[_REG_EIP]
|
||||
#define SIGSEGV_REGISTER_FILE (SIGSEGV_REGISTER_TYPE *)SIGSEGV_CONTEXT_REGS
|
||||
#define SIGSEGV_SKIP_INSTRUCTION ix86_skip_instruction
|
||||
#elif (defined(x86_64) || defined(__x86_64__))
|
||||
#include <sys/ucontext.h>
|
||||
#define SIGSEGV_CONTEXT_REGS (((ucontext_t *)scp)->uc_mcontext.__gregs)
|
||||
#define SIGSEGV_FAULT_INSTRUCTION SIGSEGV_CONTEXT_REGS[_REG_RIP]
|
||||
#define SIGSEGV_REGISTER_FILE (SIGSEGV_REGISTER_TYPE *)SIGSEGV_CONTEXT_REGS
|
||||
#define SIGSEGV_SKIP_INSTRUCTION ix86_skip_instruction
|
||||
#endif
|
||||
#if (defined(powerpc) || defined(__powerpc__))
|
||||
#include <sys/ucontext.h>
|
||||
@ -323,12 +336,12 @@ static void powerpc_decode_instruction(instruction_t *instruction, unsigned int
|
||||
#endif
|
||||
#if (defined(i386) || defined(__i386__))
|
||||
#define SIGSEGV_CONTEXT_REGS (((ucontext_t *)scp)->uc_mcontext.gregs)
|
||||
#define SIGSEGV_FAULT_INSTRUCTION SIGSEGV_CONTEXT_REGS[14] /* should use REG_EIP instead */
|
||||
#define SIGSEGV_FAULT_INSTRUCTION SIGSEGV_CONTEXT_REGS[REG_EIP]
|
||||
#define SIGSEGV_REGISTER_FILE (SIGSEGV_REGISTER_TYPE *)SIGSEGV_CONTEXT_REGS
|
||||
#define SIGSEGV_SKIP_INSTRUCTION ix86_skip_instruction
|
||||
#elif (defined(x86_64) || defined(__x86_64__))
|
||||
#define SIGSEGV_CONTEXT_REGS (((ucontext_t *)scp)->uc_mcontext.gregs)
|
||||
#define SIGSEGV_FAULT_INSTRUCTION SIGSEGV_CONTEXT_REGS[16] /* should use REG_RIP instead */
|
||||
#define SIGSEGV_FAULT_INSTRUCTION SIGSEGV_CONTEXT_REGS[REG_RIP]
|
||||
#define SIGSEGV_REGISTER_FILE (SIGSEGV_REGISTER_TYPE *)SIGSEGV_CONTEXT_REGS
|
||||
#define SIGSEGV_SKIP_INSTRUCTION ix86_skip_instruction
|
||||
#elif (defined(ia64) || defined(__ia64__))
|
||||
@ -346,6 +359,11 @@ static void powerpc_decode_instruction(instruction_t *instruction, unsigned int
|
||||
#define SIGSEGV_FAULT_INSTRUCTION (SIGSEGV_CONTEXT_REGS.arm_pc)
|
||||
#define SIGSEGV_REGISTER_FILE (&SIGSEGV_CONTEXT_REGS.arm_r0)
|
||||
#define SIGSEGV_SKIP_INSTRUCTION arm_skip_instruction
|
||||
#elif (defined(aarch64) || defined(__aarch64__))
|
||||
#define SIGSEGV_CONTEXT_REGS (((ucontext_t *)scp)->uc_mcontext)
|
||||
#define SIGSEGV_FAULT_INSTRUCTION (SIGSEGV_CONTEXT_REGS.pc)
|
||||
#define SIGSEGV_REGISTER_FILE ((unsigned long *)&SIGSEGV_CONTEXT_REGS.regs)
|
||||
#define SIGSEGV_SKIP_INSTRUCTION aarch64_skip_instruction
|
||||
#elif (defined(mips) || defined(__mips__))
|
||||
#define SIGSEGV_CONTEXT_REGS (((ucontext_t *)scp)->uc_mcontext)
|
||||
#define SIGSEGV_FAULT_INSTRUCTION (SIGSEGV_CONTEXT_REGS.pc)
|
||||
@ -747,38 +765,37 @@ handleExceptions(void *priv)
|
||||
|
||||
#ifdef HAVE_SIGSEGV_SKIP_INSTRUCTION
|
||||
// Decode and skip X86 instruction
|
||||
#if (defined(i386) || defined(__i386__) || defined(_M_IX86)) || (defined(__x86_64__) || defined(_M_X64))
|
||||
#if (defined(i386) || defined(__i386__) || defined(_M_IX86) || defined(x86_64) || defined(__x86_64__) || defined(_M_X64))
|
||||
#if defined(__linux__)
|
||||
enum {
|
||||
#if (defined(i386) || defined(__i386__))
|
||||
X86_REG_EIP = 14,
|
||||
X86_REG_EAX = 11,
|
||||
X86_REG_ECX = 10,
|
||||
X86_REG_EDX = 9,
|
||||
X86_REG_EBX = 8,
|
||||
X86_REG_ESP = 7,
|
||||
X86_REG_EBP = 6,
|
||||
X86_REG_ESI = 5,
|
||||
X86_REG_EDI = 4
|
||||
#endif
|
||||
#if defined(__x86_64__)
|
||||
X86_REG_R8 = 0,
|
||||
X86_REG_R9 = 1,
|
||||
X86_REG_R10 = 2,
|
||||
X86_REG_R11 = 3,
|
||||
X86_REG_R12 = 4,
|
||||
X86_REG_R13 = 5,
|
||||
X86_REG_R14 = 6,
|
||||
X86_REG_R15 = 7,
|
||||
X86_REG_EDI = 8,
|
||||
X86_REG_ESI = 9,
|
||||
X86_REG_EBP = 10,
|
||||
X86_REG_EBX = 11,
|
||||
X86_REG_EDX = 12,
|
||||
X86_REG_EAX = 13,
|
||||
X86_REG_ECX = 14,
|
||||
X86_REG_ESP = 15,
|
||||
X86_REG_EIP = 16
|
||||
X86_REG_EIP = REG_EIP,
|
||||
X86_REG_EAX = REG_EAX,
|
||||
X86_REG_ECX = REG_ECX,
|
||||
X86_REG_EDX = REG_EDX,
|
||||
X86_REG_EBX = REG_EBX,
|
||||
X86_REG_ESP = REG_ESP,
|
||||
X86_REG_EBP = REG_EBP,
|
||||
X86_REG_ESI = REG_ESI,
|
||||
X86_REG_EDI = REG_EDI
|
||||
#elif (defined(x86_64) || defined(__x86_64__))
|
||||
X86_REG_R8 = REG_R8,
|
||||
X86_REG_R9 = REG_R9,
|
||||
X86_REG_R10 = REG_R10,
|
||||
X86_REG_R11 = REG_R11,
|
||||
X86_REG_R12 = REG_R12,
|
||||
X86_REG_R13 = REG_R13,
|
||||
X86_REG_R14 = REG_R14,
|
||||
X86_REG_R15 = REG_R15,
|
||||
X86_REG_EDI = REG_RDI,
|
||||
X86_REG_ESI = REG_RSI,
|
||||
X86_REG_EBP = REG_RBP,
|
||||
X86_REG_EBX = REG_RBX,
|
||||
X86_REG_EDX = REG_RDX,
|
||||
X86_REG_EAX = REG_RAX,
|
||||
X86_REG_ECX = REG_RCX,
|
||||
X86_REG_ESP = REG_RSP,
|
||||
X86_REG_EIP = REG_RIP
|
||||
#endif
|
||||
};
|
||||
#endif
|
||||
@ -794,6 +811,24 @@ enum {
|
||||
X86_REG_EBP = _REG_EBP,
|
||||
X86_REG_ESI = _REG_ESI,
|
||||
X86_REG_EDI = _REG_EDI
|
||||
#elif (defined(x86_64) || defined(__x86_64__))
|
||||
X86_REG_EIP = _REG_RIP,
|
||||
X86_REG_EAX = _REG_RAX,
|
||||
X86_REG_ECX = _REG_RCX,
|
||||
X86_REG_EDX = _REG_RDX,
|
||||
X86_REG_EBX = _REG_RBX,
|
||||
X86_REG_ESP = _REG_RSP,
|
||||
X86_REG_EBP = _REG_RBP,
|
||||
X86_REG_ESI = _REG_RSI,
|
||||
X86_REG_EDI = _REG_RDI,
|
||||
X86_REG_R8 = _REG_R8,
|
||||
X86_REG_R9 = _REG_R9,
|
||||
X86_REG_R10 = _REG_R10,
|
||||
X86_REG_R11 = _REG_R11,
|
||||
X86_REG_R12 = _REG_R12,
|
||||
X86_REG_R13 = _REG_R13,
|
||||
X86_REG_R14 = _REG_R14,
|
||||
X86_REG_R15 = _REG_R15
|
||||
#endif
|
||||
};
|
||||
#endif
|
||||
@ -809,8 +844,7 @@ enum {
|
||||
X86_REG_EBP = 2,
|
||||
X86_REG_ESI = 1,
|
||||
X86_REG_EDI = 0
|
||||
#endif
|
||||
#if (defined(x86_64) || defined(__x86_64__))
|
||||
#elif (defined(x86_64) || defined(__x86_64__))
|
||||
X86_REG_EDI = 0,
|
||||
X86_REG_ESI = 1,
|
||||
X86_REG_EDX = 2,
|
||||
@ -833,7 +867,7 @@ enum {
|
||||
#endif
|
||||
#if defined(__OpenBSD__)
|
||||
enum {
|
||||
#if defined(__i386__)
|
||||
#if (defined(i386) || defined(__i386__))
|
||||
// EDI is the first register we consider
|
||||
#define OREG(REG) offsetof(struct sigcontext, sc_##REG)
|
||||
#define DREG(REG) ((OREG(REG) - OREG(edi)) / 4)
|
||||
@ -854,7 +888,7 @@ enum {
|
||||
#if defined(__sun__)
|
||||
// Same as for Linux, need to check for x86-64
|
||||
enum {
|
||||
#if defined(__i386__)
|
||||
#if (defined(i386) || defined(__i386__))
|
||||
X86_REG_EIP = EIP,
|
||||
X86_REG_EAX = EAX,
|
||||
X86_REG_ECX = ECX,
|
||||
@ -864,6 +898,24 @@ enum {
|
||||
X86_REG_EBP = EBP,
|
||||
X86_REG_ESI = ESI,
|
||||
X86_REG_EDI = EDI
|
||||
#elif (defined(x86_64) || defined(__x86_64__))
|
||||
X86_REG_R8 = REG_R8,
|
||||
X86_REG_R9 = REG_R9,
|
||||
X86_REG_R10 = REG_R10,
|
||||
X86_REG_R11 = REG_R11,
|
||||
X86_REG_R12 = REG_R12,
|
||||
X86_REG_R13 = REG_R13,
|
||||
X86_REG_R14 = REG_R14,
|
||||
X86_REG_R15 = REG_R15,
|
||||
X86_REG_EDI = REG_RDI,
|
||||
X86_REG_ESI = REG_RSI,
|
||||
X86_REG_EBP = REG_RBP,
|
||||
X86_REG_EBX = REG_RBX,
|
||||
X86_REG_EDX = REG_RDX,
|
||||
X86_REG_EAX = REG_RAX,
|
||||
X86_REG_ECX = REG_RCX,
|
||||
X86_REG_ESP = REG_RSP,
|
||||
X86_REG_EIP = REG_RIP
|
||||
#endif
|
||||
};
|
||||
#endif
|
||||
@ -1018,6 +1070,15 @@ static bool ix86_skip_instruction(SIGSEGV_REGISTER_TYPE * regs)
|
||||
transfer_size = SIZE_WORD;
|
||||
}
|
||||
|
||||
#if defined(__x86_64__) || defined(_M_X64)
|
||||
// Address size override
|
||||
if (*eip == 0x67) {
|
||||
// 32-bit address
|
||||
eip++;
|
||||
len++;
|
||||
}
|
||||
#endif
|
||||
|
||||
// REX prefix
|
||||
#if defined(__x86_64__) || defined(_M_X64)
|
||||
struct rex_t {
|
||||
@ -2499,6 +2560,22 @@ static bool arm_skip_instruction(unsigned long * regs)
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef _STRUCT_ARM_THREAD_STATE64
|
||||
static bool aarch64_skip_instruction(unsigned long *regs) {
|
||||
_STRUCT_ARM_THREAD_STATE64 *ts = (_STRUCT_ARM_THREAD_STATE64 *)regs;
|
||||
if (!ts->__pc) return false;
|
||||
ts->__pc += 4;
|
||||
return true;
|
||||
}
|
||||
#endif
|
||||
#ifdef __linux__
|
||||
static bool aarch64_skip_instruction(unsigned long *regs) {
|
||||
unsigned long long *r = (unsigned long long *)regs;
|
||||
if (!r[32]) return false;
|
||||
r[32] += 4;
|
||||
return true;
|
||||
}
|
||||
#endif
|
||||
|
||||
// Fallbacks
|
||||
#ifndef SIGSEGV_FAULT_ADDRESS_FAST
|
||||
@ -3230,7 +3307,7 @@ static sigsegv_return_t sigsegv_insn_handler(sigsegv_info_t *sip)
|
||||
// More sophisticated tests for instruction skipper
|
||||
static bool arch_insn_skipper_tests()
|
||||
{
|
||||
#if (defined(i386) || defined(__i386__)) || (defined(__x86_64__) || defined(_M_X64))
|
||||
#if (defined(i386) || defined(__i386__) || defined(x86_64) || defined(__x86_64__) || defined(_M_X64))
|
||||
static const unsigned char code[] = {
|
||||
0x8a, 0x00, // mov (%eax),%al
|
||||
0x8a, 0x2c, 0x18, // mov (%eax,%ebx,1),%ch
|
||||
@ -3244,7 +3321,7 @@ static bool arch_insn_skipper_tests()
|
||||
0x8b, 0x0c, 0x18, // mov (%eax,%ebx,1),%ecx
|
||||
0x89, 0x00, // mov %eax,(%eax)
|
||||
0x89, 0x0c, 0x18, // mov %ecx,(%eax,%ebx,1)
|
||||
#if defined(__x86_64__) || defined(_M_X64)
|
||||
#if defined(x86_64) || defined(__x86_64__) || defined(_M_X64)
|
||||
0x44, 0x8a, 0x00, // mov (%rax),%r8b
|
||||
0x44, 0x8a, 0x20, // mov (%rax),%r12b
|
||||
0x42, 0x8a, 0x3c, 0x10, // mov (%rax,%r10,1),%dil
|
||||
|
@ -105,6 +105,22 @@ extern "C" {
|
||||
#define SIGSEGV_SKIP_INSTRUCTION ix86_skip_instruction
|
||||
#define SIGSEGV_REGISTER_FILE ((SIGSEGV_REGISTER_TYPE *)&SIP->thr_state.MACH_FIELD_NAME(rax)) /* RAX is the first GPR we consider */
|
||||
#endif
|
||||
|
||||
#ifdef __aarch64__
|
||||
#if __DARWIN_UNIX03 && defined _STRUCT_ARM_THREAD_STATE64
|
||||
#define MACH_FIELD_NAME(X) __CONCAT(__,X)
|
||||
#endif
|
||||
#define SIGSEGV_EXCEPTION_STATE_TYPE arm_exception_state64_t
|
||||
#define SIGSEGV_EXCEPTION_STATE_FLAVOR ARM_EXCEPTION_STATE64
|
||||
#define SIGSEGV_EXCEPTION_STATE_COUNT ARM_EXCEPTION_STATE64_COUNT
|
||||
#define SIGSEGV_FAULT_ADDRESS SIP->exc_state.MACH_FIELD_NAME(far)
|
||||
#define SIGSEGV_THREAD_STATE_TYPE arm_thread_state64_t
|
||||
#define SIGSEGV_THREAD_STATE_FLAVOR ARM_THREAD_STATE64
|
||||
#define SIGSEGV_THREAD_STATE_COUNT ARM_THREAD_STATE64_COUNT
|
||||
#define SIGSEGV_REGISTER_FILE ((SIGSEGV_REGISTER_TYPE *)&SIP->thr_state.MACH_FIELD_NAME(x[0])) /* x[0] is the first GPR we consider */
|
||||
#define SIGSEGV_SKIP_INSTRUCTION aarch64_skip_instruction
|
||||
#endif
|
||||
|
||||
#ifdef __x86_64__
|
||||
#define SIGSEGV_FAULT_ADDRESS_FAST (((uint64_t)code[1])|0x100000000)
|
||||
#else
|
||||
|
@ -305,6 +305,7 @@ static void Blit_Copy_Raw(uint8 * dest, const uint8 * source, uint32 length)
|
||||
#define FB_DEPTH 24
|
||||
#include "video_blit.h"
|
||||
|
||||
#if !(REAL_ADDRESSING || DIRECT_ADDRESSING || USE_SDL_VIDEO)
|
||||
/* -------------------------------------------------------------------------- */
|
||||
/* --- 1-bit indexed to 8-bit color mode conversion --- */
|
||||
/* -------------------------------------------------------------------------- */
|
||||
@ -325,6 +326,7 @@ static void Blit_Expand_1_To_8_Color(uint8 * dest, const uint8 * p, uint32 lengt
|
||||
*q++ = CONVERT_BW(c & 1);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
/* -------------------------------------------------------------------------- */
|
||||
/* --- 1/2/4-bit indexed to 8-bit mode conversion --- */
|
||||
@ -507,7 +509,11 @@ static Screen_blit_func_info Screen_blitters[] = {
|
||||
{ 16, 0x00f800, 0x0007e0, 0x00001f, Blit_RGB565_NBO , Blit_RGB565_OBO }, // OK (NBO)
|
||||
{ 24, 0xff0000, 0x00ff00, 0x0000ff, Blit_RGB888_NBO , Blit_Copy_Raw }, // OK (NBO)
|
||||
{ 24, 0x0000ff, 0x00ff00, 0xff0000, Blit_BGR888_NBO , Blit_BGR888_OBO }, // NT
|
||||
#ifdef ENABLE_VOSF
|
||||
{ 32, 0xff0000, 0x00ff00, 0x0000ff, Blit_RGB888_NBO , Blit_Copy_Raw }, // OK (NBO)
|
||||
#else
|
||||
{ 32, 0xff000000, 0x00ff0000, 0x0000ff00, Blit_RGB888_NBO , Blit_Copy_Raw }, // OK (NBO)
|
||||
#endif
|
||||
{ 32, 0x0000ff, 0x00ff00, 0xff0000, Blit_BGR888_NBO , Blit_BGR888_OBO }, // NT
|
||||
#endif
|
||||
{ 32, 0xff00, 0xff0000, 0xff000000, Blit_Copy_Raw , Blit_Copy_Raw } // OK
|
||||
@ -529,9 +535,7 @@ bool Screen_blitter_init(VisualFormat const & visual_format, bool native_byte_or
|
||||
// Windowed 1-bit mode uses a 1-bit X image, so there's no need for special blitting routines
|
||||
Screen_blit = Blit_Copy_Raw;
|
||||
|
||||
#if __MACOSX__ && !defined(SHEEPSHAVER)
|
||||
// dludwig@pobox.com, HACK: This works on OSX (64-bit, at least), but not Linux (32-bit?). Why?
|
||||
// To note, __MACOSX__ is an SDL-declared macro (for platform identification at compile time).
|
||||
#if !DIRECT_ADDRESSING && defined(__aarch64__)
|
||||
} else if (mac_depth == 16) {
|
||||
|
||||
Screen_blit = Blit_Copy_Raw;
|
||||
|
@ -46,7 +46,11 @@ extern void update_sdl_video(SDL_Surface *screen, int numrects, SDL_Rect *rects)
|
||||
#define VIDEO_DRV_DGA_INIT driver_base *drv
|
||||
#define VIDEO_DRV_LOCK_PIXELS SDL_VIDEO_LOCK_SURFACE(drv->s)
|
||||
#define VIDEO_DRV_UNLOCK_PIXELS SDL_VIDEO_UNLOCK_SURFACE(drv->s)
|
||||
#if SDL_VERSION_ATLEAST(3, 0, 0)
|
||||
#define VIDEO_DRV_DEPTH SDL_GetPixelFormatDetails(drv->s->format)->bits_per_pixel
|
||||
#else
|
||||
#define VIDEO_DRV_DEPTH drv->s->format->BitsPerPixel
|
||||
#endif
|
||||
#define VIDEO_DRV_WIDTH drv->s->w
|
||||
#define VIDEO_DRV_HEIGHT drv->s->h
|
||||
#define VIDEO_DRV_ROW_BYTES drv->s->pitch
|
||||
@ -540,6 +544,7 @@ static void update_display_window_vosf(VIDEO_DRV_WIN_INIT)
|
||||
|
||||
#ifndef TEST_VOSF_PERFORMANCE
|
||||
#if REAL_ADDRESSING || DIRECT_ADDRESSING
|
||||
|
||||
static void update_display_dga_vosf(VIDEO_DRV_DGA_INIT)
|
||||
{
|
||||
VIDEO_MODE_INIT;
|
||||
@ -574,8 +579,10 @@ static void update_display_dga_vosf(VIDEO_DRV_DGA_INIT)
|
||||
const uint32 n_pixels = 64;
|
||||
const uint32 n_chunks = VIDEO_MODE_X / n_pixels;
|
||||
const uint32 n_pixels_left = VIDEO_MODE_X - (n_chunks * n_pixels);
|
||||
const uint32 src_chunk_size = src_bytes_per_row / n_chunks;
|
||||
const uint32 dst_chunk_size = dst_bytes_per_row / n_chunks;
|
||||
const uint32 src_chunk_size = TrivialBytesPerRow(n_pixels, VIDEO_MODE_DEPTH);
|
||||
const uint32 dst_chunk_size = TrivialBytesPerRow(n_pixels, DepthModeForPixelDepth(VIDEO_DRV_DEPTH));
|
||||
assert(src_chunk_size * n_chunks <= src_bytes_per_row);
|
||||
assert(dst_chunk_size * n_chunks <= dst_bytes_per_row);
|
||||
const uint32 src_chunk_size_left = src_bytes_per_row - (n_chunks * src_chunk_size);
|
||||
const uint32 dst_chunk_size_left = dst_bytes_per_row - (n_chunks * dst_chunk_size);
|
||||
|
||||
@ -643,8 +650,6 @@ static void update_display_dga_vosf(VIDEO_DRV_DGA_INIT)
|
||||
memcpy(the_buffer_copy + i1, the_buffer + i1, src_chunk_size_left);
|
||||
Screen_blit(the_host_buffer + i2, the_buffer + i1, src_chunk_size_left);
|
||||
}
|
||||
i1 += src_chunk_size_left;
|
||||
i2 += dst_chunk_size_left;
|
||||
#ifdef USE_SDL_VIDEO
|
||||
const int x = n_chunks * n_pixels;
|
||||
if (x < bb[bbi].x) {
|
||||
@ -658,7 +663,8 @@ static void update_display_dga_vosf(VIDEO_DRV_DGA_INIT)
|
||||
bb[bbi].w = x + n_pixels_left - bb[bbi].x;
|
||||
#endif
|
||||
}
|
||||
i2 += scr_bytes_left;
|
||||
i1 += src_chunk_size_left;
|
||||
i2 += dst_chunk_size_left + scr_bytes_left;
|
||||
#ifdef USE_SDL_VIDEO
|
||||
bb[bbi].h++;
|
||||
if (bb[bbi].w && (j == y1 || j == y2 - 1 || j == y2)) {
|
||||
|
@ -37,6 +37,7 @@
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <limits.h>
|
||||
#include <assert.h>
|
||||
#include "vm_alloc.h"
|
||||
|
||||
#if defined(__APPLE__) && defined(__MACH__)
|
||||
@ -71,7 +72,7 @@ typedef unsigned long vm_uintptr_t;
|
||||
#ifndef MAP_32BIT
|
||||
#define MAP_32BIT 0
|
||||
#endif
|
||||
#ifdef __FreeBSD__
|
||||
#if defined(__FreeBSD__) || defined(__NetBSD__)
|
||||
#define FORCE_MAP_32BIT MAP_FIXED
|
||||
#else
|
||||
#define FORCE_MAP_32BIT MAP_32BIT
|
||||
@ -86,7 +87,7 @@ typedef unsigned long vm_uintptr_t;
|
||||
#define MAP_EXTRA_FLAGS (MAP_32BIT)
|
||||
|
||||
#ifdef HAVE_MMAP_VM
|
||||
#if (defined(__linux__) && defined(__i386__)) || defined(__FreeBSD__) || HAVE_LINKER_SCRIPT
|
||||
#if (defined(__linux__) && defined(__i386__)) || defined(__sun__) || defined(__FreeBSD__) || defined(__NetBSD__) || HAVE_LINKER_SCRIPT
|
||||
/* Force a reasonnable address below 0x80000000 on x86 so that we
|
||||
don't get addresses above when the program is run on AMD64.
|
||||
NOTE: this is empirically determined on Linux/x86. */
|
||||
@ -222,6 +223,21 @@ void vm_exit(void)
|
||||
#endif
|
||||
}
|
||||
|
||||
static void *reserved_buf;
|
||||
static const size_t RESERVED_SIZE = 80 * 1024 * 1024; // for 6K Retina
|
||||
|
||||
void *vm_acquire_reserved(size_t size) {
|
||||
assert(reserved_buf && size <= RESERVED_SIZE);
|
||||
return reserved_buf;
|
||||
}
|
||||
|
||||
int vm_init_reserved(void *hostAddress) {
|
||||
int result = vm_acquire_fixed(hostAddress, RESERVED_SIZE);
|
||||
if (result >= 0)
|
||||
reserved_buf = hostAddress;
|
||||
return result;
|
||||
}
|
||||
|
||||
/* Allocate zero-filled memory of SIZE bytes. The mapping is private
|
||||
and default protection bits are read / write. The return value
|
||||
is the actual mapping address chosen or VM_MAP_FAILED for errors. */
|
||||
@ -243,22 +259,30 @@ void * vm_acquire(size_t size, int options)
|
||||
|
||||
#if defined(HAVE_MACH_VM)
|
||||
// vm_allocate() returns a zero-filled memory region
|
||||
kern_return_t ret_code = vm_allocate(mach_task_self(), (vm_address_t *)&addr, size, TRUE);
|
||||
kern_return_t ret_code = vm_allocate(mach_task_self(), (vm_address_t *)&addr, reserved_buf ? size : size + RESERVED_SIZE, TRUE);
|
||||
if (ret_code != KERN_SUCCESS) {
|
||||
errno = vm_error(ret_code);
|
||||
return VM_MAP_FAILED;
|
||||
}
|
||||
if (!reserved_buf)
|
||||
reserved_buf = (char *)addr + size;
|
||||
#elif defined(HAVE_MMAP_VM)
|
||||
int fd = zero_fd;
|
||||
int the_map_flags = translate_map_flags(options) | map_flags;
|
||||
|
||||
#ifdef __aarch64__
|
||||
if ((addr = mmap((caddr_t)next_address, reserved_buf ? size : size + RESERVED_SIZE, VM_PAGE_DEFAULT, the_map_flags, fd, 0)) == (void *)MAP_FAILED)
|
||||
return VM_MAP_FAILED;
|
||||
if (!reserved_buf)
|
||||
reserved_buf = (char *)addr + size;
|
||||
#else
|
||||
if ((addr = mmap((caddr_t)next_address, size, VM_PAGE_DEFAULT, the_map_flags, fd, 0)) == (void *)MAP_FAILED)
|
||||
return VM_MAP_FAILED;
|
||||
|
||||
#endif
|
||||
#if USE_JIT
|
||||
// Sanity checks for 64-bit platforms
|
||||
if (sizeof(void *) == 8 && (options & VM_MAP_32BIT) && !((char *)addr <= (char *)0xffffffff))
|
||||
return VM_MAP_FAILED;
|
||||
|
||||
#endif
|
||||
next_address = (char *)addr + size;
|
||||
#elif defined(HAVE_WIN32_VM)
|
||||
int alloc_type = MEM_RESERVE | MEM_COMMIT;
|
||||
|
@ -99,6 +99,10 @@ extern void vm_exit(void);
|
||||
|
||||
extern void * vm_acquire(size_t size, int options = VM_MAP_DEFAULT);
|
||||
|
||||
extern void * vm_acquire_reserved(size_t size);
|
||||
|
||||
extern int vm_init_reserved(void * host_address);
|
||||
|
||||
/* Allocate zero-filled memory at exactly ADDR (which must be page-aligned).
|
||||
Returns 0 if successful, -1 on errors. */
|
||||
|
||||
|
@ -51,23 +51,23 @@ void AudioDevice::Init(AudioDeviceID devid, bool isInput)
|
||||
UInt32 propsize;
|
||||
|
||||
propsize = sizeof(UInt32);
|
||||
verify_noerr(AudioDeviceGetProperty(mID, 0, mIsInput, kAudioDevicePropertySafetyOffset, &propsize, &mSafetyOffset));
|
||||
__Verify_noErr(AudioDeviceGetProperty(mID, 0, mIsInput, kAudioDevicePropertySafetyOffset, &propsize, &mSafetyOffset));
|
||||
|
||||
propsize = sizeof(UInt32);
|
||||
verify_noerr(AudioDeviceGetProperty(mID, 0, mIsInput, kAudioDevicePropertyBufferFrameSize, &propsize, &mBufferSizeFrames));
|
||||
__Verify_noErr(AudioDeviceGetProperty(mID, 0, mIsInput, kAudioDevicePropertyBufferFrameSize, &propsize, &mBufferSizeFrames));
|
||||
|
||||
propsize = sizeof(AudioStreamBasicDescription);
|
||||
verify_noerr(AudioDeviceGetProperty(mID, 0, mIsInput, kAudioDevicePropertyStreamFormat, &propsize, &mFormat));
|
||||
__Verify_noErr(AudioDeviceGetProperty(mID, 0, mIsInput, kAudioDevicePropertyStreamFormat, &propsize, &mFormat));
|
||||
|
||||
}
|
||||
|
||||
void AudioDevice::SetBufferSize(UInt32 size)
|
||||
{
|
||||
UInt32 propsize = sizeof(UInt32);
|
||||
verify_noerr(AudioDeviceSetProperty(mID, NULL, 0, mIsInput, kAudioDevicePropertyBufferFrameSize, propsize, &size));
|
||||
__Verify_noErr(AudioDeviceSetProperty(mID, NULL, 0, mIsInput, kAudioDevicePropertyBufferFrameSize, propsize, &size));
|
||||
|
||||
propsize = sizeof(UInt32);
|
||||
verify_noerr(AudioDeviceGetProperty(mID, 0, mIsInput, kAudioDevicePropertyBufferFrameSize, &propsize, &mBufferSizeFrames));
|
||||
__Verify_noErr(AudioDeviceGetProperty(mID, 0, mIsInput, kAudioDevicePropertyBufferFrameSize, &propsize, &mBufferSizeFrames));
|
||||
}
|
||||
|
||||
int AudioDevice::CountChannels()
|
||||
@ -92,6 +92,6 @@ int AudioDevice::CountChannels()
|
||||
|
||||
char * AudioDevice::GetName(char *buf, UInt32 maxlen)
|
||||
{
|
||||
verify_noerr(AudioDeviceGetProperty(mID, 0, mIsInput, kAudioDevicePropertyDeviceName, &maxlen, buf));
|
||||
__Verify_noErr(AudioDeviceGetProperty(mID, 0, mIsInput, kAudioDevicePropertyDeviceName, &maxlen, buf));
|
||||
return buf;
|
||||
}
|
||||
|
Binary file not shown.
File diff suppressed because it is too large
Load Diff
@ -11,7 +11,7 @@
|
||||
<key>CFBundleIconFile</key>
|
||||
<string>BasiliskII.icns</string>
|
||||
<key>CFBundleIdentifier</key>
|
||||
<string></string>
|
||||
<string>$(PRODUCT_BUNDLE_IDENTIFIER)</string>
|
||||
<key>CFBundleInfoDictionaryVersion</key>
|
||||
<string>6.0</string>
|
||||
<key>CFBundleName</key>
|
||||
|
@ -18,6 +18,8 @@
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*/
|
||||
#ifndef MACOSX_SOUND_IF
|
||||
#define MACOSX_SOUND_IF
|
||||
|
||||
typedef int (*audioCallback)(void);
|
||||
|
||||
@ -39,3 +41,5 @@ class OSXsoundOutput {
|
||||
unsigned int bufferSizeFrames();
|
||||
int sendAudioBuffer(void *buffer, int numFrames);
|
||||
};
|
||||
|
||||
#endif
|
||||
|
29
BasiliskII/src/MacOSX/Makefile.gencpu
Normal file
29
BasiliskII/src/MacOSX/Makefile.gencpu
Normal file
@ -0,0 +1,29 @@
|
||||
SRC = $(PROJECT_DIR)/../uae_cpu
|
||||
DST = $(BUILT_PRODUCTS_DIR)/gencpu_output
|
||||
VPATH = $(SRC) $(SRC)/compiler
|
||||
CFLAGS = -DUSE_XCODE=1 -DUSE_JIT_FPU -I. -I../uae_cpu -I../UNIX
|
||||
CXXFLAGS = -stdlib=libc++ $(CFLAGS)
|
||||
|
||||
all: $(DST)/gencpu $(DST)/gencomp
|
||||
cd $(DST); ./gencpu; ./gencomp
|
||||
|
||||
$(DST)/gencpu: $(addprefix $(DST)/, defs68k.o readcpu.o gencpu.o)
|
||||
$(CXX) $(CXXFLAGS) -o $@ $^
|
||||
|
||||
$(DST)/gencomp: $(addprefix $(DST)/, defs68k.o readcpu.o gencomp.o)
|
||||
$(CXX) $(CXXFLAGS) -o $@ $^
|
||||
|
||||
$(DST)/%.o: %.c
|
||||
$(CC) $(CFLAGS) -o $@ -c $<
|
||||
|
||||
$(DST)/%.o: %.cpp
|
||||
$(CXX) $(CXXFLAGS) -o $@ -c $<
|
||||
|
||||
$(DST)/defs68k.c: $(DST)/build68k
|
||||
$< < $(SRC)/table68k > $@
|
||||
|
||||
$(DST)/build68k: $(SRC)/build68k.c
|
||||
mkdir -p $(DST)
|
||||
$(CC) $(CFLAGS) -o $@ $<
|
||||
|
||||
clean:; rm -fr $(DST)
|
29
BasiliskII/src/MacOSX/Makefile.gencpu_2021
Normal file
29
BasiliskII/src/MacOSX/Makefile.gencpu_2021
Normal file
@ -0,0 +1,29 @@
|
||||
SRC = $(PROJECT_DIR)/../uae_cpu_2021
|
||||
DST = $(BUILT_PRODUCTS_DIR)/gencpu_output_2021
|
||||
VPATH = $(SRC) $(SRC)/compiler
|
||||
CFLAGS = -DUSE_XCODE=1 -DUSE_JIT_FPU -I. -I../uae_cpu_2021 -I../UNIX
|
||||
CXXFLAGS = -stdlib=libc++ $(CFLAGS)
|
||||
|
||||
all: $(DST)/gencpu $(DST)/gencomp
|
||||
cd $(DST); ./gencpu; ./gencomp
|
||||
|
||||
$(DST)/gencpu: $(addprefix $(DST)/, defs68k.o readcpu.o gencpu.o)
|
||||
$(CXX) $(CXXFLAGS) -o $@ $^
|
||||
|
||||
$(DST)/gencomp: $(addprefix $(DST)/, defs68k.o readcpu.o gencomp.o)
|
||||
$(CXX) $(CXXFLAGS) -o $@ $^
|
||||
|
||||
$(DST)/%.o: %.c
|
||||
$(CC) $(CFLAGS) -o $@ -c $<
|
||||
|
||||
$(DST)/%.o: %.cpp
|
||||
$(CXX) $(CXXFLAGS) -o $@ -c $<
|
||||
|
||||
$(DST)/defs68k.c: $(DST)/build68k
|
||||
$< < $(SRC)/table68k > $@
|
||||
|
||||
$(DST)/build68k: $(SRC)/build68k.c
|
||||
mkdir -p $(DST)
|
||||
$(CC) $(CFLAGS) -o $@ $<
|
||||
|
||||
clean:; rm -fr $(DST)
|
@ -19,6 +19,8 @@
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*/
|
||||
|
||||
#ifndef USE_SDL_AUDIO
|
||||
|
||||
#include "sysdeps.h"
|
||||
|
||||
#include <sys/ioctl.h>
|
||||
@ -269,3 +271,5 @@ static int audioInt(void)
|
||||
TriggerInterrupt();
|
||||
return 0;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
@ -59,12 +59,6 @@ static bool should_clear = false;
|
||||
|
||||
static NSMutableDictionary *g_macScrap;
|
||||
|
||||
// flavor UTIs
|
||||
|
||||
static NSString * const UTF16_TEXT_FLAVOR_NAME = @"public.utf16-plain-text";
|
||||
static NSString * const TEXT_FLAVOR_NAME = @"com.apple.traditional-mac-plain-text";
|
||||
static NSString * const STYL_FLAVOR_NAME = @"net.cebix.basilisk.styl-data";
|
||||
|
||||
// font face types
|
||||
|
||||
enum {
|
||||
|
@ -681,7 +681,11 @@
|
||||
#define SIZEOF_LONG 8
|
||||
|
||||
/* The size of `long double', as computed by sizeof. */
|
||||
#ifdef CPU_x86_64
|
||||
#define SIZEOF_LONG_DOUBLE 16
|
||||
#else
|
||||
#define SIZEOF_LONG_DOUBLE 8
|
||||
#endif
|
||||
|
||||
/* The size of `long long', as computed by sizeof. */
|
||||
#define SIZEOF_LONG_LONG 8
|
||||
@ -815,7 +819,32 @@
|
||||
<inttypes.h> don't define. */
|
||||
/* #undef uintmax_t */
|
||||
|
||||
#define FPU_UAE 1
|
||||
//#define FPU_IMPLEMENTATION 1
|
||||
#ifndef CPU_x86_64
|
||||
#define UPDATE_UAE
|
||||
#endif
|
||||
|
||||
#ifdef UPDATE_UAE
|
||||
#define DIRECT_ADDRESSING 1
|
||||
#define CPU_64_BIT
|
||||
#define USE_INLINING
|
||||
#ifdef CPU_x86_64
|
||||
#define FPU_IEEE
|
||||
#define WINUAE_ARANYM
|
||||
#else
|
||||
#define FPU_MPFR
|
||||
#endif
|
||||
#else
|
||||
#define FPU_IEEE
|
||||
#endif
|
||||
|
||||
#if USE_JIT
|
||||
#define DIRECT_ADDRESSING 1
|
||||
#define USE_JIT_FPU
|
||||
#define X86_64_ASSEMBLY
|
||||
#define OPTIMIZED_FLAGS
|
||||
#endif
|
||||
|
||||
#define ENABLE_MACOSX_ETHERHELPER
|
||||
#define BINCUE 1
|
||||
|
||||
#endif
|
||||
|
580
BasiliskII/src/MacOSX/etherhelpertool.c
Normal file
580
BasiliskII/src/MacOSX/etherhelpertool.c
Normal file
@ -0,0 +1,580 @@
|
||||
/*
|
||||
* etherhelpertool.c - Reads and writes raw ethernet packets usng bpf
|
||||
* interface.
|
||||
*
|
||||
* Copyright (C) 2010, Daniel Sumorok
|
||||
*
|
||||
* Basilisk II (C) 1997-2008 Christian Bauer
|
||||
*
|
||||
* This program 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 Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program 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 this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
|
||||
#include <sys/types.h>
|
||||
#include <sys/socket.h>
|
||||
#include <net/if_dl.h>
|
||||
#include <ifaddrs.h>
|
||||
#include <errno.h>
|
||||
#include <sys/select.h>
|
||||
|
||||
#include <unistd.h>
|
||||
|
||||
#include <net/if.h>
|
||||
#include <sys/time.h>
|
||||
#include <sys/ioctl.h>
|
||||
#include <net/bpf.h>
|
||||
#include <fcntl.h>
|
||||
|
||||
#include <strings.h>
|
||||
|
||||
#include <Carbon/Carbon.h>
|
||||
|
||||
#define STR_MAX 256
|
||||
#define MAX_ARGV 10
|
||||
|
||||
static int open_bpf(char *ifname);
|
||||
static int open_tap(char *ifname);
|
||||
static int retreive_auth_info(void);
|
||||
static int main_loop(int sd, int use_bpf);
|
||||
static int run_cmd(const char *cmd);
|
||||
static void handler(int signum);
|
||||
static int install_signal_handlers();
|
||||
static void do_exit();
|
||||
|
||||
static char remove_bridge[STR_MAX];
|
||||
static const char *exec_name = "etherhelpertool";
|
||||
|
||||
int main(int argc, char **argv)
|
||||
{
|
||||
char *if_name;
|
||||
int ret = 255;
|
||||
int sd;
|
||||
int tapNum;
|
||||
int use_bpf;
|
||||
|
||||
if (argc != 2) {
|
||||
return 255;
|
||||
}
|
||||
|
||||
if_name = argv[1];
|
||||
|
||||
do {
|
||||
ret = retreive_auth_info();
|
||||
if (ret != 0) {
|
||||
fprintf(stderr, "%s: authorization failed.\n",
|
||||
exec_name);
|
||||
ret = 254;
|
||||
break;
|
||||
}
|
||||
|
||||
if (strncmp(if_name, "tap", 3) == 0) {
|
||||
sd = open_tap(if_name);
|
||||
use_bpf = 0;
|
||||
} else {
|
||||
sd = open_bpf(if_name);
|
||||
use_bpf = 1;
|
||||
}
|
||||
|
||||
if (sd < 0) {
|
||||
fprintf(stderr, "%s: open device failed.\n",
|
||||
exec_name);
|
||||
ret = 253;
|
||||
break;
|
||||
}
|
||||
|
||||
if (install_signal_handlers() != 0) {
|
||||
fprintf(stderr,
|
||||
"%s: failed to install signal handers.\n",
|
||||
exec_name);
|
||||
ret = 252;
|
||||
break;
|
||||
}
|
||||
|
||||
ret = main_loop(sd, use_bpf);
|
||||
close(sd);
|
||||
} while (0);
|
||||
|
||||
do_exit();
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int main_loop(int sd, int use_bpf)
|
||||
{
|
||||
fd_set readSet;
|
||||
char *outgoing, *incoming;
|
||||
unsigned short *out_len;
|
||||
unsigned short *in_len;
|
||||
int in_index, out_index;
|
||||
u_int blen = 0;
|
||||
int ret;
|
||||
int fret = 0;
|
||||
struct bpf_hdr *hdr;
|
||||
int pkt_len;
|
||||
int frame_len;
|
||||
int pad;
|
||||
char c = 0;
|
||||
|
||||
if (use_bpf) {
|
||||
if (ioctl(sd, BIOCGBLEN, &blen) < 0) {
|
||||
fprintf(stderr,
|
||||
"%s: ioctl() failed.\n",
|
||||
exec_name);
|
||||
return -1;
|
||||
}
|
||||
} else {
|
||||
blen = 4096;
|
||||
}
|
||||
|
||||
incoming = malloc(blen);
|
||||
if (incoming == NULL) {
|
||||
fprintf(stderr,
|
||||
"%s: malloc() failed.\n",
|
||||
exec_name);
|
||||
return -2;
|
||||
}
|
||||
|
||||
outgoing = malloc(blen);
|
||||
if (outgoing == NULL) {
|
||||
free(outgoing);
|
||||
fprintf(stderr,
|
||||
"%s: malloc() failed.\n",
|
||||
exec_name);
|
||||
return -3;
|
||||
}
|
||||
|
||||
in_index = 0;
|
||||
out_index = 0;
|
||||
|
||||
out_len = (unsigned short *)outgoing;
|
||||
|
||||
/* Let our parent know we are ready for business. */
|
||||
write(0, &c, 1);
|
||||
|
||||
while (1) {
|
||||
int i;
|
||||
FD_ZERO(&readSet);
|
||||
FD_SET(0, &readSet);
|
||||
FD_SET(sd, &readSet);
|
||||
|
||||
ret = select(sd + 1, &readSet, NULL, NULL, NULL);
|
||||
if (ret < 0) {
|
||||
fprintf(stderr,
|
||||
"%s: select() failed.\n",
|
||||
exec_name);
|
||||
fret = -4;
|
||||
break;
|
||||
}
|
||||
|
||||
if (FD_ISSET(0, &readSet)) {
|
||||
if (out_index < 2) {
|
||||
ret = read(0, outgoing + out_index, 2-out_index);
|
||||
} else {
|
||||
ret = read(0, outgoing + out_index, *out_len - out_index + 2);
|
||||
}
|
||||
|
||||
if (ret < 1) {
|
||||
if(ret < 0) {
|
||||
fprintf(stderr,
|
||||
"%s: read() failed.\n",
|
||||
exec_name);
|
||||
}
|
||||
fret = -5;
|
||||
break;
|
||||
}
|
||||
|
||||
out_index += ret;
|
||||
if (out_index > 1) {
|
||||
if ((*out_len + 2) > blen) {
|
||||
fret = -6;
|
||||
break;
|
||||
}
|
||||
|
||||
if (out_index == (*out_len + 2)) {
|
||||
ret = write(sd, out_len + 1, *out_len);
|
||||
if (ret != *out_len) {
|
||||
fprintf(stderr,
|
||||
"%s: write() failed.\n",
|
||||
exec_name);
|
||||
fret = -7;
|
||||
break;
|
||||
}
|
||||
out_index = 0;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
if (use_bpf && FD_ISSET(sd, &readSet)) {
|
||||
int i;
|
||||
|
||||
ret = read(sd, incoming, blen);
|
||||
if (ret < 1) {
|
||||
if(ret < 0) {
|
||||
fprintf(stderr,
|
||||
"%s: read() failed %d.\n",
|
||||
exec_name, errno);
|
||||
}
|
||||
fret = -8;
|
||||
break;
|
||||
}
|
||||
|
||||
hdr = (struct bpf_hdr *)incoming;
|
||||
in_len = (unsigned short *)(incoming + 16);
|
||||
|
||||
do {
|
||||
pkt_len = hdr->bh_caplen;
|
||||
frame_len = pkt_len + 18;
|
||||
|
||||
if ((pkt_len < 0) || (frame_len > ret) || (frame_len < 0)) {
|
||||
fret = -9;
|
||||
break;
|
||||
}
|
||||
*in_len = pkt_len;
|
||||
|
||||
if (write(0, in_len, pkt_len + 2) < (pkt_len + 2)) {
|
||||
fret = -10;
|
||||
break;
|
||||
}
|
||||
|
||||
if ((frame_len & 0x03) == 0) {
|
||||
pad = 0;
|
||||
} else {
|
||||
pad = 4 - (frame_len & 0x03);
|
||||
}
|
||||
|
||||
ret -= (frame_len + pad);
|
||||
hdr = (struct bpf_hdr *)((unsigned char *)hdr + frame_len + pad);
|
||||
in_len = (unsigned short *)((unsigned char *)hdr + 16);
|
||||
} while (ret > 0);
|
||||
|
||||
if (fret != 0) {
|
||||
fprintf(stderr,
|
||||
"%s: fret == %d.\n",
|
||||
exec_name, fret);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (!use_bpf && FD_ISSET(sd, &readSet)) {
|
||||
in_len = (unsigned short *)incoming;
|
||||
|
||||
pkt_len = read(sd, in_len + 1, blen-2);
|
||||
if (pkt_len < 14) {
|
||||
fprintf(stderr,
|
||||
"%s: read() returned %d.\n",
|
||||
exec_name, pkt_len);
|
||||
fret = -8;
|
||||
break;
|
||||
}
|
||||
|
||||
*in_len = pkt_len;
|
||||
if (write(0, in_len, pkt_len + 2) < (pkt_len + 2)) {
|
||||
fprintf(stderr,
|
||||
"%s: write() failed\n",
|
||||
exec_name);
|
||||
fret = -10;
|
||||
break;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
free(incoming);
|
||||
free(outgoing);
|
||||
|
||||
return fret;
|
||||
}
|
||||
|
||||
static int retreive_auth_info(void)
|
||||
{
|
||||
AuthorizationRef aRef;
|
||||
OSStatus status;
|
||||
AuthorizationRights myRights;
|
||||
AuthorizationRights *newRights;
|
||||
AuthorizationItem *myItem;
|
||||
AuthorizationItem myItems[1];
|
||||
AuthorizationItemSet *mySet;
|
||||
int i;
|
||||
|
||||
status = AuthorizationCopyPrivilegedReference(&aRef, kAuthorizationFlagDefaults);
|
||||
if (status != errAuthorizationSuccess) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
status = AuthorizationCopyInfo(aRef, NULL, &mySet);
|
||||
if (status != errAuthorizationSuccess) {
|
||||
AuthorizationFree(aRef, kAuthorizationFlagDestroyRights);
|
||||
return -1;
|
||||
}
|
||||
|
||||
myItems[0].name = "system.privilege.admin";
|
||||
myItems[0].valueLength = 0;
|
||||
myItems[0].value = NULL;
|
||||
myItems[0].flags = 0;
|
||||
|
||||
myRights.count = sizeof (myItems) / sizeof (myItems[0]);
|
||||
myRights.items = myItems;
|
||||
|
||||
status = AuthorizationCopyRights(aRef, &myRights, NULL,
|
||||
kAuthorizationFlagExtendRights,
|
||||
&newRights);
|
||||
if (status != errAuthorizationSuccess) {
|
||||
AuthorizationFreeItemSet(mySet);
|
||||
AuthorizationFree(aRef, kAuthorizationFlagDestroyRights);
|
||||
return -2;
|
||||
}
|
||||
|
||||
AuthorizationFreeItemSet(newRights);
|
||||
AuthorizationFreeItemSet(mySet);
|
||||
AuthorizationFree(aRef, kAuthorizationFlagDestroyRights);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int open_tap(char *ifname)
|
||||
{
|
||||
char str[STR_MAX] = {0};
|
||||
char ifstr[STR_MAX] = {0};
|
||||
char *interface;
|
||||
char *address = NULL;
|
||||
char *netmask = NULL;
|
||||
char *bridge = NULL;
|
||||
char *bridged_if = NULL;
|
||||
int sd;
|
||||
|
||||
snprintf(ifstr, STR_MAX, "%s", ifname);
|
||||
interface = strtok(ifstr, "/");
|
||||
bridge = strtok(NULL, "/");
|
||||
if (bridge != NULL) {
|
||||
bridged_if = strtok(NULL, "/");
|
||||
}
|
||||
interface = strtok(ifstr, ":");
|
||||
|
||||
address = strtok(NULL, ":");
|
||||
|
||||
if (address != NULL) {
|
||||
netmask = strtok(NULL, ":");
|
||||
}
|
||||
|
||||
snprintf(str, STR_MAX, "/dev/%s", interface);
|
||||
|
||||
sd = open(str, O_RDWR);
|
||||
if (sd < 0) {
|
||||
fprintf(stderr, "%s: Failed to open %s\n",
|
||||
exec_name, interface);
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (address == NULL) {
|
||||
snprintf(str, STR_MAX, "/sbin/ifconfig %s up", interface);
|
||||
} else if (netmask == NULL) {
|
||||
snprintf(str, STR_MAX, "/sbin/ifconfig %s %s",
|
||||
interface, address);
|
||||
} else {
|
||||
snprintf(str, STR_MAX, "/sbin/ifconfig %s %s netmask %s",
|
||||
interface, address, netmask);
|
||||
}
|
||||
|
||||
if (run_cmd(str) != 0) {
|
||||
fprintf(stderr, "%s: Failed to configure %s\n",
|
||||
exec_name, interface);
|
||||
close(sd);
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (bridge != NULL) {
|
||||
/* Check to see if bridge is alread up */
|
||||
snprintf(str, STR_MAX, "/sbin/ifconfig %s", bridge);
|
||||
if (run_cmd(str) == 0) {
|
||||
/* bridge is already up */
|
||||
if (bridged_if != NULL) {
|
||||
fprintf(stderr, "%s: Warning: %s already exists, so %s was not added.\n",
|
||||
exec_name, bridge, bridged_if);
|
||||
}
|
||||
} else {
|
||||
snprintf(str, STR_MAX, "/sbin/ifconfig %s create", bridge);
|
||||
if (run_cmd(str) != 0) {
|
||||
fprintf(stderr, "%s: Failed to create %s\n",
|
||||
exec_name, bridge);
|
||||
close(sd);
|
||||
return -1;
|
||||
}
|
||||
strlcpy(remove_bridge, bridge, STR_MAX);
|
||||
|
||||
snprintf(str, STR_MAX, "/sbin/ifconfig %s up", bridge);
|
||||
if (run_cmd(str) != 0) {
|
||||
fprintf(stderr, "%s: Failed to open %s\n",
|
||||
exec_name, bridge);
|
||||
close(sd);
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (bridged_if != NULL) {
|
||||
snprintf(str, STR_MAX, "/sbin/ifconfig %s addm %s",
|
||||
bridge, bridged_if);
|
||||
if (run_cmd(str) != 0) {
|
||||
fprintf(stderr, "%s: Failed to add %s to %s\n",
|
||||
exec_name, bridged_if, bridge);
|
||||
close(sd);
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
snprintf(str, STR_MAX, "/sbin/ifconfig %s addm %s",
|
||||
bridge, interface);
|
||||
if (run_cmd(str) != 0) {
|
||||
fprintf(stderr, "%s: Failed to add %s to %s\n",
|
||||
exec_name, interface, bridge);
|
||||
close(sd);
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
return sd;
|
||||
}
|
||||
|
||||
static int open_bpf(char *ifname)
|
||||
{
|
||||
u_int blen = 0;
|
||||
struct ifreq ifreq;
|
||||
u_int arg;
|
||||
|
||||
int sd = open("/dev/bpf2", O_RDWR);
|
||||
|
||||
if (sd < 0) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (ioctl(sd, BIOCGBLEN, &blen) < 0) {
|
||||
close(sd);
|
||||
return -2;
|
||||
}
|
||||
|
||||
bzero(&ifreq, sizeof(ifreq));
|
||||
strncpy(ifreq.ifr_name, ifname, IFNAMSIZ);
|
||||
|
||||
arg = 0;
|
||||
if (ioctl(sd, BIOCSETIF, &ifreq) < 0) {
|
||||
close(sd);
|
||||
return -3;
|
||||
}
|
||||
|
||||
arg = 0;
|
||||
if (ioctl(sd, BIOCSSEESENT, &arg) < 0) {
|
||||
close(sd);
|
||||
return -4;
|
||||
}
|
||||
|
||||
arg = 1;
|
||||
if (ioctl(sd, BIOCPROMISC, &arg) < 0) {
|
||||
close(sd);
|
||||
return -5;
|
||||
}
|
||||
|
||||
arg = 1;
|
||||
if (ioctl(sd, BIOCIMMEDIATE, &arg) < 0) {
|
||||
close(sd);
|
||||
return -6;
|
||||
}
|
||||
|
||||
return sd;
|
||||
}
|
||||
|
||||
static int run_cmd(const char *cmd) {
|
||||
char cmd_buffer[STR_MAX] = {0};
|
||||
char *argv[MAX_ARGV + 1] = {0};
|
||||
int i;
|
||||
pid_t pid, waitpid;
|
||||
int status = 0;
|
||||
|
||||
/* Collect arguments */
|
||||
strncpy(cmd_buffer, cmd, STR_MAX-1);
|
||||
|
||||
argv[0] = strtok(cmd_buffer, " ");
|
||||
for (i=1; i<MAX_ARGV; ++i) {
|
||||
argv[i] = strtok(NULL, " ");
|
||||
if (argv[i] == NULL) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/* Run sub process */
|
||||
pid = fork();
|
||||
if (pid == 0) {
|
||||
|
||||
/* Child process */
|
||||
fclose(stdout);
|
||||
fclose(stderr);
|
||||
|
||||
if (execve(argv[0], argv, NULL) < 0) {
|
||||
perror("execve");
|
||||
return -1;
|
||||
}
|
||||
} else {
|
||||
/* Wait for child to exit */
|
||||
waitpid = wait(&status);
|
||||
if (waitpid < 0) {
|
||||
perror("wait");
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (status != 0) {
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void handler(int signum) {
|
||||
do_exit();
|
||||
exit(1);
|
||||
}
|
||||
|
||||
static int install_signal_handlers() {
|
||||
struct sigaction act = {0};
|
||||
|
||||
act.sa_handler = handler;
|
||||
sigemptyset(&act.sa_mask);
|
||||
|
||||
if (sigaction(SIGINT, &act, NULL) != 0) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
||||
if (sigaction(SIGHUP, &act, NULL) != 0) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
||||
if (sigaction(SIGTERM, &act, NULL) != 0) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void do_exit() {
|
||||
if (*remove_bridge) {
|
||||
char str[STR_MAX];
|
||||
snprintf(str, STR_MAX, "/sbin/ifconfig %s destroy", remove_bridge);
|
||||
run_cmd(str);
|
||||
}
|
||||
}
|
@ -251,7 +251,9 @@ static int open_rsrc(const char *path, int flag)
|
||||
char rsrc_path[MAX_PATH_LENGTH];
|
||||
make_rsrc_path(path, rsrc_path);
|
||||
|
||||
return open(rsrc_path, flag);
|
||||
int fd = open(rsrc_path, flag);
|
||||
if (fd < 0 && (flag == O_WRONLY || flag == O_RDWR)) fd = open(rsrc_path, flag | O_CREAT); // for APFS
|
||||
return fd;
|
||||
}
|
||||
|
||||
|
||||
@ -418,9 +420,9 @@ void get_finfo(const char *path, uint32 finfo, uint32 fxinfo, bool is_dir)
|
||||
|
||||
// No native Finder info, translate file name extension to MacOS type/creator
|
||||
if (!is_dir) {
|
||||
int path_len = strlen(path);
|
||||
size_t path_len = strlen(path);
|
||||
for (int i=0; e2t_translation[i].ext; i++) {
|
||||
int ext_len = strlen(e2t_translation[i].ext);
|
||||
size_t ext_len = strlen(e2t_translation[i].ext);
|
||||
if (path_len < ext_len)
|
||||
continue;
|
||||
if (!strcmp(path + path_len - ext_len, e2t_translation[i].ext)) {
|
||||
@ -624,11 +626,11 @@ const char *convert_string(const char *str, CFStringEncoding from, CFStringEncod
|
||||
// Convert from the host OS filename encoding to MacRoman
|
||||
const char *host_encoding_to_macroman(const char *filename)
|
||||
{
|
||||
return convert_string(filename, kCFStringEncodingUTF8, kCFStringEncodingMacRoman);
|
||||
return convert_string(filename, kCFStringEncodingUTF8, PrefsFindInt32("name_encoding"));
|
||||
}
|
||||
|
||||
// Convert from MacRoman to host OS filename encoding
|
||||
const char *macroman_to_host_encoding(const char *filename)
|
||||
{
|
||||
return convert_string(filename, kCFStringEncodingMacRoman, kCFStringEncodingUTF8);
|
||||
return convert_string(filename, PrefsFindInt32("name_encoding"), kCFStringEncodingUTF8);
|
||||
}
|
||||
|
@ -1,37 +0,0 @@
|
||||
#!/bin/bash -e
|
||||
|
||||
#
|
||||
# run_build68k_for_xcode.sh
|
||||
#
|
||||
# Generates files for 68k emulation, via UAE's virtual cpu, for use on Mac OS X hosts
|
||||
#
|
||||
|
||||
if [ ! "$BUILT_PRODUCTS_DIR" ] || [ ! "$PROJECT_DIR" ]; then
|
||||
echo "ERROR: $(basename $0) must be run from an Xcode 'External Build System' target"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# Log some debugging information
|
||||
echo "1=$1"
|
||||
echo "BUILT_PRODUCTS_DIR=$BUILT_PRODUCTS_DIR"
|
||||
echo "PROJECT_DIR=$PROJECT_DIR"
|
||||
|
||||
# Perform actions, given the passed-in build step
|
||||
case "$1" in
|
||||
"clean")
|
||||
echo "Cleaning build68k output(s)"
|
||||
rm -rf "$BUILT_PRODUCTS_DIR/build68k_output"
|
||||
;;
|
||||
"")
|
||||
if [ ! -d "$BUILT_PRODUCTS_DIR" ]; then
|
||||
echo "No built products directory"
|
||||
exit 1
|
||||
fi
|
||||
echo "Running build68k"
|
||||
cd "$BUILT_PRODUCTS_DIR"
|
||||
mkdir -p build68k_output
|
||||
cd build68k_output
|
||||
cat "$PROJECT_DIR/../uae_cpu/table68k" | "$BUILT_PRODUCTS_DIR/build68k" > "./defs68k.c"
|
||||
ls -al
|
||||
;;
|
||||
esac
|
@ -1,37 +0,0 @@
|
||||
#!/bin/bash -e
|
||||
|
||||
#
|
||||
# run_gemcpu_for_xcode.sh
|
||||
#
|
||||
# Generates files for 68k emulation, via UAE's virtual cpu, for use on Mac OS X hosts
|
||||
#
|
||||
|
||||
if [ ! "$BUILT_PRODUCTS_DIR" ] || [ ! "$PROJECT_DIR" ]; then
|
||||
echo "ERROR: $(basename $0) must be run from an Xcode 'External Build System' target"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# Log some debugging information
|
||||
echo "1=$1"
|
||||
echo "BUILT_PRODUCTS_DIR=$BUILT_PRODUCTS_DIR"
|
||||
echo "PROJECT_DIR=$PROJECT_DIR"
|
||||
|
||||
# Perform actions, given the passed-in build step
|
||||
case "$1" in
|
||||
"clean")
|
||||
echo "Cleaning gencpu output(s)"
|
||||
rm -rf "$BUILT_PRODUCTS_DIR/gencpu_output"
|
||||
;;
|
||||
"")
|
||||
if [ ! -d "$BUILT_PRODUCTS_DIR" ]; then
|
||||
echo "No built products directory"
|
||||
exit 1
|
||||
fi
|
||||
echo "Running gencpu"
|
||||
cd "$BUILT_PRODUCTS_DIR"
|
||||
mkdir -p gencpu_output
|
||||
cd gencpu_output
|
||||
"$BUILT_PRODUCTS_DIR/gencpu"
|
||||
ls -al
|
||||
;;
|
||||
esac
|
135
BasiliskII/src/MacOSX/runtool.c
Normal file
135
BasiliskII/src/MacOSX/runtool.c
Normal file
@ -0,0 +1,135 @@
|
||||
/*
|
||||
* runtool.m - Run an external program as root for networking
|
||||
* Copyright (C) 2010, Daniel Sumorok
|
||||
*
|
||||
* Basilisk II (C) 1997-2008 Christian Bauer
|
||||
*
|
||||
* This program 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 Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program 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 this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
|
||||
#include <sys/types.h>
|
||||
#include <sys/socket.h>
|
||||
#include <net/if_dl.h>
|
||||
#include <ifaddrs.h>
|
||||
#include <errno.h>
|
||||
|
||||
#include <unistd.h>
|
||||
|
||||
#include <net/if.h>
|
||||
#include <sys/time.h>
|
||||
#include <sys/ioctl.h>
|
||||
#include <net/bpf.h>
|
||||
#include <fcntl.h>
|
||||
|
||||
#include <strings.h>
|
||||
|
||||
#include <Carbon/Carbon.h>
|
||||
|
||||
FILE * run_tool(const char *if_name, const char *tool_name);
|
||||
|
||||
FILE * run_tool(const char *if_name, const char *tool_name)
|
||||
{
|
||||
OSStatus auth_status;
|
||||
FILE *fp = NULL;
|
||||
char *args[] = {NULL, NULL, NULL};
|
||||
char path_buffer[256];
|
||||
AuthorizationFlags auth_flags;
|
||||
AuthorizationRef auth_ref;
|
||||
AuthorizationItem auth_items[1];
|
||||
AuthorizationRights auth_rights;
|
||||
CFBundleRef bundle_ref;
|
||||
CFURLRef url_ref;
|
||||
CFStringRef path_str;
|
||||
CFStringRef tool_name_str;
|
||||
char c;
|
||||
|
||||
bundle_ref = CFBundleGetMainBundle();
|
||||
if(bundle_ref == NULL) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
tool_name_str = CFStringCreateWithCString(NULL, tool_name,
|
||||
kCFStringEncodingUTF8);
|
||||
|
||||
url_ref = CFBundleCopyResourceURL(bundle_ref, tool_name_str,
|
||||
NULL, NULL);
|
||||
CFRelease(tool_name_str);
|
||||
|
||||
if(url_ref == NULL) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
path_str = CFURLCopyFileSystemPath(url_ref, kCFURLPOSIXPathStyle);
|
||||
CFRelease(url_ref);
|
||||
|
||||
if(path_str == NULL) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if(!CFStringGetCString(path_str, path_buffer, sizeof(path_buffer),
|
||||
kCFStringEncodingUTF8)) {
|
||||
CFRelease(path_str);
|
||||
return NULL;
|
||||
}
|
||||
CFRelease(path_str);
|
||||
|
||||
args[0] = (char *)tool_name;
|
||||
args[1] = (char *)if_name;
|
||||
|
||||
auth_flags = kAuthorizationFlagExtendRights |
|
||||
kAuthorizationFlagInteractionAllowed |
|
||||
kAuthorizationFlagPreAuthorize;
|
||||
|
||||
auth_items[0].name = "system.privilege.admin";
|
||||
auth_items[0].valueLength = 0;
|
||||
auth_items[0].value = NULL;
|
||||
auth_items[0].flags = 0;
|
||||
|
||||
auth_rights.count = sizeof (auth_items) / sizeof (auth_items[0]);
|
||||
auth_rights.items = auth_items;
|
||||
|
||||
auth_status = AuthorizationCreate(&auth_rights,
|
||||
kAuthorizationEmptyEnvironment,
|
||||
auth_flags,
|
||||
&auth_ref);
|
||||
|
||||
if (auth_status != errAuthorizationSuccess) {
|
||||
fprintf(stderr, "%s: AuthorizationCreate() failed.\n",
|
||||
__func__);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
auth_status = AuthorizationExecuteWithPrivileges(auth_ref,
|
||||
path_buffer,
|
||||
kAuthorizationFlagDefaults,
|
||||
args + 1,
|
||||
&fp);
|
||||
|
||||
if (auth_status != errAuthorizationSuccess) {
|
||||
fprintf(stderr, "%s: AuthorizationExecWithPrivileges() failed.\n",
|
||||
__func__);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if(fread(&c, 1, 1, fp) != 1) {
|
||||
fclose(fp);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
return fp;
|
||||
}
|
@ -350,8 +350,9 @@ void DarwinAddSerialPrefs(void)
|
||||
{
|
||||
D(bug("Modem BSD path: %s\n", bsdPath));
|
||||
|
||||
// Note that if there are multiple modems, we only get the last
|
||||
// Note that if there are multiple modems, we only get the first
|
||||
PrefsAddString("seriala", bsdPath);
|
||||
break;
|
||||
}
|
||||
else
|
||||
D(bug("Could not get BSD device path for modem\n"));
|
||||
|
489
BasiliskII/src/MacOSX/uae_cpu.xcodeproj/project.pbxproj
Normal file
489
BasiliskII/src/MacOSX/uae_cpu.xcodeproj/project.pbxproj
Normal file
@ -0,0 +1,489 @@
|
||||
// !$*UTF8*$!
|
||||
{
|
||||
archiveVersion = 1;
|
||||
classes = {
|
||||
};
|
||||
objectVersion = 46;
|
||||
objects = {
|
||||
|
||||
/* Begin PBXBuildFile section */
|
||||
E4C1B4A32642B05A00EB55A0 /* compemu.cpp in Sources */ = {isa = PBXBuildFile; fileRef = E4C1B49A2642B05A00EB55A0 /* compemu.cpp */; };
|
||||
E4C1B4A42642B05A00EB55A0 /* compstbl.cpp in Sources */ = {isa = PBXBuildFile; fileRef = E4C1B49B2642B05A00EB55A0 /* compstbl.cpp */; };
|
||||
E4C1B4A52642B05A00EB55A0 /* comptbl.h in Headers */ = {isa = PBXBuildFile; fileRef = E4C1B49C2642B05A00EB55A0 /* comptbl.h */; };
|
||||
E4C1B4A62642B05A00EB55A0 /* cpuemu_nf.cpp in Sources */ = {isa = PBXBuildFile; fileRef = E4C1B49D2642B05A00EB55A0 /* cpuemu_nf.cpp */; };
|
||||
E4C1B4A72642B05A00EB55A0 /* cpuemu.cpp in Sources */ = {isa = PBXBuildFile; fileRef = E4C1B49E2642B05A00EB55A0 /* cpuemu.cpp */; };
|
||||
E4C1B4A82642B05A00EB55A0 /* cpustbl_nf.cpp in Sources */ = {isa = PBXBuildFile; fileRef = E4C1B49F2642B05A00EB55A0 /* cpustbl_nf.cpp */; };
|
||||
E4C1B4A92642B05A00EB55A0 /* cpustbl.cpp in Sources */ = {isa = PBXBuildFile; fileRef = E4C1B4A02642B05A00EB55A0 /* cpustbl.cpp */; };
|
||||
E4C1B4AA2642B05A00EB55A0 /* cputbl.h in Headers */ = {isa = PBXBuildFile; fileRef = E4C1B4A12642B05A00EB55A0 /* cputbl.h */; };
|
||||
E4C1B4AB2642B05A00EB55A0 /* defs68k.c in Sources */ = {isa = PBXBuildFile; fileRef = E4C1B4A22642B05A00EB55A0 /* defs68k.c */; };
|
||||
E4F537C92642A8BA008B27DF /* basilisk_glue.cpp in Sources */ = {isa = PBXBuildFile; fileRef = E4F537C72642A8BA008B27DF /* basilisk_glue.cpp */; };
|
||||
E4F537CD2642A8C2008B27DF /* cpu_emulation.h in Headers */ = {isa = PBXBuildFile; fileRef = E4F537CB2642A8C2008B27DF /* cpu_emulation.h */; };
|
||||
E4F537DB2642A8CC008B27DF /* m68k.h in Headers */ = {isa = PBXBuildFile; fileRef = E4F537D02642A8CC008B27DF /* m68k.h */; };
|
||||
E4F537DC2642A8CC008B27DF /* memory.cpp in Sources */ = {isa = PBXBuildFile; fileRef = E4F537D12642A8CC008B27DF /* memory.cpp */; };
|
||||
E4F537DD2642A8CC008B27DF /* memory.h in Headers */ = {isa = PBXBuildFile; fileRef = E4F537D22642A8CC008B27DF /* memory.h */; };
|
||||
E4F537DE2642A8CC008B27DF /* newcpu.cpp in Sources */ = {isa = PBXBuildFile; fileRef = E4F537D32642A8CC008B27DF /* newcpu.cpp */; };
|
||||
E4F537DF2642A8CC008B27DF /* newcpu.h in Headers */ = {isa = PBXBuildFile; fileRef = E4F537D42642A8CC008B27DF /* newcpu.h */; };
|
||||
E4F537E02642A8CC008B27DF /* noflags.h in Headers */ = {isa = PBXBuildFile; fileRef = E4F537D52642A8CC008B27DF /* noflags.h */; };
|
||||
E4F537E12642A8CC008B27DF /* readcpu.cpp in Sources */ = {isa = PBXBuildFile; fileRef = E4F537D62642A8CC008B27DF /* readcpu.cpp */; };
|
||||
E4F537E22642A8CC008B27DF /* readcpu.h in Headers */ = {isa = PBXBuildFile; fileRef = E4F537D72642A8CC008B27DF /* readcpu.h */; };
|
||||
E4F537E32642A8CC008B27DF /* spcflags.h in Headers */ = {isa = PBXBuildFile; fileRef = E4F537D82642A8CC008B27DF /* spcflags.h */; };
|
||||
E4F537EE2642A8E8008B27DF /* codegen_x86.h in Headers */ = {isa = PBXBuildFile; fileRef = E4F537E62642A8E8008B27DF /* codegen_x86.h */; };
|
||||
E4F537EF2642A8E8008B27DF /* compemu_fpp.cpp in Sources */ = {isa = PBXBuildFile; fileRef = E4F537E72642A8E8008B27DF /* compemu_fpp.cpp */; };
|
||||
E4F537F02642A8E8008B27DF /* compemu_support.cpp in Sources */ = {isa = PBXBuildFile; fileRef = E4F537E82642A8E8008B27DF /* compemu_support.cpp */; };
|
||||
E4F537F12642A8E8008B27DF /* compemu.h in Headers */ = {isa = PBXBuildFile; fileRef = E4F537E92642A8E8008B27DF /* compemu.h */; };
|
||||
E4F537F22642A8E8008B27DF /* flags_x86.h in Headers */ = {isa = PBXBuildFile; fileRef = E4F537EA2642A8E8008B27DF /* flags_x86.h */; };
|
||||
E4F537F32642A8E8008B27DF /* gencomp.c in Sources */ = {isa = PBXBuildFile; fileRef = E4F537EB2642A8E8008B27DF /* gencomp.c */; };
|
||||
E4F538092642A904008B27DF /* core.h in Headers */ = {isa = PBXBuildFile; fileRef = E4F537F62642A904008B27DF /* core.h */; };
|
||||
E4F5380A2642A904008B27DF /* exceptions.cpp in Sources */ = {isa = PBXBuildFile; fileRef = E4F537F72642A904008B27DF /* exceptions.cpp */; };
|
||||
E4F5380B2642A904008B27DF /* exceptions.h in Headers */ = {isa = PBXBuildFile; fileRef = E4F537F82642A904008B27DF /* exceptions.h */; };
|
||||
E4F5380C2642A904008B27DF /* flags.cpp in Sources */ = {isa = PBXBuildFile; fileRef = E4F537F92642A904008B27DF /* flags.cpp */; };
|
||||
E4F5380D2642A904008B27DF /* flags.h in Headers */ = {isa = PBXBuildFile; fileRef = E4F537FA2642A904008B27DF /* flags.h */; };
|
||||
E4F5380E2642A904008B27DF /* fpu_ieee.cpp in Sources */ = {isa = PBXBuildFile; fileRef = E4F537FB2642A904008B27DF /* fpu_ieee.cpp */; };
|
||||
E4F5380F2642A904008B27DF /* fpu_ieee.h in Headers */ = {isa = PBXBuildFile; fileRef = E4F537FC2642A904008B27DF /* fpu_ieee.h */; };
|
||||
E4F538152642A904008B27DF /* fpu.h in Headers */ = {isa = PBXBuildFile; fileRef = E4F538022642A904008B27DF /* fpu.h */; };
|
||||
E4F538162642A904008B27DF /* impl.h in Headers */ = {isa = PBXBuildFile; fileRef = E4F538032642A904008B27DF /* impl.h */; };
|
||||
E4F538172642A904008B27DF /* mathlib.cpp in Sources */ = {isa = PBXBuildFile; fileRef = E4F538042642A904008B27DF /* mathlib.cpp */; };
|
||||
E4F538182642A904008B27DF /* mathlib.h in Headers */ = {isa = PBXBuildFile; fileRef = E4F538052642A904008B27DF /* mathlib.h */; };
|
||||
E4F538192642A904008B27DF /* rounding.cpp in Sources */ = {isa = PBXBuildFile; fileRef = E4F538062642A904008B27DF /* rounding.cpp */; };
|
||||
E4F5381A2642A904008B27DF /* rounding.h in Headers */ = {isa = PBXBuildFile; fileRef = E4F538072642A904008B27DF /* rounding.h */; };
|
||||
E4F5381B2642A904008B27DF /* types.h in Headers */ = {isa = PBXBuildFile; fileRef = E4F538082642A904008B27DF /* types.h */; };
|
||||
/* End PBXBuildFile section */
|
||||
|
||||
/* Begin PBXFileReference section */
|
||||
E4C1B49A2642B05A00EB55A0 /* compemu.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = compemu.cpp; path = gencpu_output/compemu.cpp; sourceTree = BUILT_PRODUCTS_DIR; };
|
||||
E4C1B49B2642B05A00EB55A0 /* compstbl.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = compstbl.cpp; path = gencpu_output/compstbl.cpp; sourceTree = BUILT_PRODUCTS_DIR; };
|
||||
E4C1B49C2642B05A00EB55A0 /* comptbl.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = comptbl.h; path = gencpu_output/comptbl.h; sourceTree = BUILT_PRODUCTS_DIR; };
|
||||
E4C1B49D2642B05A00EB55A0 /* cpuemu_nf.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = cpuemu_nf.cpp; path = gencpu_output/cpuemu_nf.cpp; sourceTree = BUILT_PRODUCTS_DIR; };
|
||||
E4C1B49E2642B05A00EB55A0 /* cpuemu.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = cpuemu.cpp; path = gencpu_output/cpuemu.cpp; sourceTree = BUILT_PRODUCTS_DIR; };
|
||||
E4C1B49F2642B05A00EB55A0 /* cpustbl_nf.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = cpustbl_nf.cpp; path = gencpu_output/cpustbl_nf.cpp; sourceTree = BUILT_PRODUCTS_DIR; };
|
||||
E4C1B4A02642B05A00EB55A0 /* cpustbl.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = cpustbl.cpp; path = gencpu_output/cpustbl.cpp; sourceTree = BUILT_PRODUCTS_DIR; };
|
||||
E4C1B4A12642B05A00EB55A0 /* cputbl.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = cputbl.h; path = gencpu_output/cputbl.h; sourceTree = BUILT_PRODUCTS_DIR; };
|
||||
E4C1B4A22642B05A00EB55A0 /* defs68k.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = defs68k.c; path = gencpu_output/defs68k.c; sourceTree = BUILT_PRODUCTS_DIR; };
|
||||
E4F537C02642A86D008B27DF /* libuae_cpu_x86_64.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = libuae_cpu_x86_64.a; sourceTree = BUILT_PRODUCTS_DIR; };
|
||||
E4F537C72642A8BA008B27DF /* basilisk_glue.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = basilisk_glue.cpp; path = ../uae_cpu/basilisk_glue.cpp; sourceTree = "<group>"; };
|
||||
E4F537CB2642A8C2008B27DF /* cpu_emulation.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = cpu_emulation.h; path = ../uae_cpu/cpu_emulation.h; sourceTree = "<group>"; };
|
||||
E4F537D02642A8CC008B27DF /* m68k.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = m68k.h; path = ../uae_cpu/m68k.h; sourceTree = "<group>"; };
|
||||
E4F537D12642A8CC008B27DF /* memory.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = memory.cpp; path = ../uae_cpu/memory.cpp; sourceTree = "<group>"; };
|
||||
E4F537D22642A8CC008B27DF /* memory.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = memory.h; path = ../uae_cpu/memory.h; sourceTree = "<group>"; };
|
||||
E4F537D32642A8CC008B27DF /* newcpu.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = newcpu.cpp; path = ../uae_cpu/newcpu.cpp; sourceTree = "<group>"; };
|
||||
E4F537D42642A8CC008B27DF /* newcpu.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = newcpu.h; path = ../uae_cpu/newcpu.h; sourceTree = "<group>"; };
|
||||
E4F537D52642A8CC008B27DF /* noflags.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = noflags.h; path = ../uae_cpu/noflags.h; sourceTree = "<group>"; };
|
||||
E4F537D62642A8CC008B27DF /* readcpu.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = readcpu.cpp; path = ../uae_cpu/readcpu.cpp; sourceTree = "<group>"; };
|
||||
E4F537D72642A8CC008B27DF /* readcpu.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = readcpu.h; path = ../uae_cpu/readcpu.h; sourceTree = "<group>"; };
|
||||
E4F537D82642A8CC008B27DF /* spcflags.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = spcflags.h; path = ../uae_cpu/spcflags.h; sourceTree = "<group>"; };
|
||||
E4F537D92642A8CC008B27DF /* table68k */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; name = table68k; path = ../uae_cpu/table68k; sourceTree = "<group>"; };
|
||||
E4F537E62642A8E8008B27DF /* codegen_x86.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = codegen_x86.h; path = ../uae_cpu/compiler/codegen_x86.h; sourceTree = "<group>"; };
|
||||
E4F537E72642A8E8008B27DF /* compemu_fpp.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = compemu_fpp.cpp; path = ../uae_cpu/compiler/compemu_fpp.cpp; sourceTree = "<group>"; };
|
||||
E4F537E82642A8E8008B27DF /* compemu_support.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = compemu_support.cpp; path = ../uae_cpu/compiler/compemu_support.cpp; sourceTree = "<group>"; };
|
||||
E4F537E92642A8E8008B27DF /* compemu.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = compemu.h; path = ../uae_cpu/compiler/compemu.h; sourceTree = "<group>"; };
|
||||
E4F537EA2642A8E8008B27DF /* flags_x86.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = flags_x86.h; path = ../uae_cpu/compiler/flags_x86.h; sourceTree = "<group>"; };
|
||||
E4F537EB2642A8E8008B27DF /* gencomp.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = gencomp.c; path = ../uae_cpu/compiler/gencomp.c; sourceTree = "<group>"; };
|
||||
E4F537F62642A904008B27DF /* core.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = core.h; path = ../uae_cpu/fpu/core.h; sourceTree = "<group>"; };
|
||||
E4F537F72642A904008B27DF /* exceptions.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = exceptions.cpp; path = ../uae_cpu/fpu/exceptions.cpp; sourceTree = "<group>"; };
|
||||
E4F537F82642A904008B27DF /* exceptions.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = exceptions.h; path = ../uae_cpu/fpu/exceptions.h; sourceTree = "<group>"; };
|
||||
E4F537F92642A904008B27DF /* flags.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = flags.cpp; path = ../uae_cpu/fpu/flags.cpp; sourceTree = "<group>"; };
|
||||
E4F537FA2642A904008B27DF /* flags.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = flags.h; path = ../uae_cpu/fpu/flags.h; sourceTree = "<group>"; };
|
||||
E4F537FB2642A904008B27DF /* fpu_ieee.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = fpu_ieee.cpp; path = ../uae_cpu/fpu/fpu_ieee.cpp; sourceTree = "<group>"; };
|
||||
E4F537FC2642A904008B27DF /* fpu_ieee.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = fpu_ieee.h; path = ../uae_cpu/fpu/fpu_ieee.h; sourceTree = "<group>"; };
|
||||
E4F538022642A904008B27DF /* fpu.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = fpu.h; path = ../uae_cpu/fpu/fpu.h; sourceTree = "<group>"; };
|
||||
E4F538032642A904008B27DF /* impl.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = impl.h; path = ../uae_cpu/fpu/impl.h; sourceTree = "<group>"; };
|
||||
E4F538042642A904008B27DF /* mathlib.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = mathlib.cpp; path = ../uae_cpu/fpu/mathlib.cpp; sourceTree = "<group>"; };
|
||||
E4F538052642A904008B27DF /* mathlib.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = mathlib.h; path = ../uae_cpu/fpu/mathlib.h; sourceTree = "<group>"; };
|
||||
E4F538062642A904008B27DF /* rounding.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = rounding.cpp; path = ../uae_cpu/fpu/rounding.cpp; sourceTree = "<group>"; };
|
||||
E4F538072642A904008B27DF /* rounding.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = rounding.h; path = ../uae_cpu/fpu/rounding.h; sourceTree = "<group>"; };
|
||||
E4F538082642A904008B27DF /* types.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = types.h; path = ../uae_cpu/fpu/types.h; sourceTree = "<group>"; };
|
||||
/* End PBXFileReference section */
|
||||
|
||||
/* Begin PBXFrameworksBuildPhase section */
|
||||
E4F537BD2642A86D008B27DF /* Frameworks */ = {
|
||||
isa = PBXFrameworksBuildPhase;
|
||||
buildActionMask = 2147483647;
|
||||
files = (
|
||||
);
|
||||
runOnlyForDeploymentPostprocessing = 0;
|
||||
};
|
||||
/* End PBXFrameworksBuildPhase section */
|
||||
|
||||
/* Begin PBXGroup section */
|
||||
E4C1B4982642AF3400EB55A0 /* generated */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
E4C1B49A2642B05A00EB55A0 /* compemu.cpp */,
|
||||
E4C1B49B2642B05A00EB55A0 /* compstbl.cpp */,
|
||||
E4C1B49C2642B05A00EB55A0 /* comptbl.h */,
|
||||
E4C1B49D2642B05A00EB55A0 /* cpuemu_nf.cpp */,
|
||||
E4C1B49E2642B05A00EB55A0 /* cpuemu.cpp */,
|
||||
E4C1B49F2642B05A00EB55A0 /* cpustbl_nf.cpp */,
|
||||
E4C1B4A02642B05A00EB55A0 /* cpustbl.cpp */,
|
||||
E4C1B4A12642B05A00EB55A0 /* cputbl.h */,
|
||||
E4C1B4A22642B05A00EB55A0 /* defs68k.c */,
|
||||
);
|
||||
name = generated;
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
E4F537B72642A86D008B27DF = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
E4F537C72642A8BA008B27DF /* basilisk_glue.cpp */,
|
||||
E4F537E42642A8D2008B27DF /* compiler */,
|
||||
E4F537CB2642A8C2008B27DF /* cpu_emulation.h */,
|
||||
E4F537F52642A8ED008B27DF /* fpu */,
|
||||
E4F537D02642A8CC008B27DF /* m68k.h */,
|
||||
E4F537D12642A8CC008B27DF /* memory.cpp */,
|
||||
E4F537D22642A8CC008B27DF /* memory.h */,
|
||||
E4F537D32642A8CC008B27DF /* newcpu.cpp */,
|
||||
E4F537D42642A8CC008B27DF /* newcpu.h */,
|
||||
E4F537D52642A8CC008B27DF /* noflags.h */,
|
||||
E4F537D62642A8CC008B27DF /* readcpu.cpp */,
|
||||
E4F537D72642A8CC008B27DF /* readcpu.h */,
|
||||
E4F537D82642A8CC008B27DF /* spcflags.h */,
|
||||
E4F537D92642A8CC008B27DF /* table68k */,
|
||||
E4C1B4982642AF3400EB55A0 /* generated */,
|
||||
E4F537C12642A86D008B27DF /* Products */,
|
||||
);
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
E4F537C12642A86D008B27DF /* Products */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
E4F537C02642A86D008B27DF /* libuae_cpu_x86_64.a */,
|
||||
);
|
||||
name = Products;
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
E4F537E42642A8D2008B27DF /* compiler */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
E4F537E62642A8E8008B27DF /* codegen_x86.h */,
|
||||
E4F537E72642A8E8008B27DF /* compemu_fpp.cpp */,
|
||||
E4F537E82642A8E8008B27DF /* compemu_support.cpp */,
|
||||
E4F537E92642A8E8008B27DF /* compemu.h */,
|
||||
E4F537EA2642A8E8008B27DF /* flags_x86.h */,
|
||||
E4F537EB2642A8E8008B27DF /* gencomp.c */,
|
||||
);
|
||||
name = compiler;
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
E4F537F52642A8ED008B27DF /* fpu */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
E4F537F62642A904008B27DF /* core.h */,
|
||||
E4F537F72642A904008B27DF /* exceptions.cpp */,
|
||||
E4F537F82642A904008B27DF /* exceptions.h */,
|
||||
E4F537F92642A904008B27DF /* flags.cpp */,
|
||||
E4F537FA2642A904008B27DF /* flags.h */,
|
||||
E4F537FB2642A904008B27DF /* fpu_ieee.cpp */,
|
||||
E4F537FC2642A904008B27DF /* fpu_ieee.h */,
|
||||
E4F538022642A904008B27DF /* fpu.h */,
|
||||
E4F538032642A904008B27DF /* impl.h */,
|
||||
E4F538042642A904008B27DF /* mathlib.cpp */,
|
||||
E4F538052642A904008B27DF /* mathlib.h */,
|
||||
E4F538062642A904008B27DF /* rounding.cpp */,
|
||||
E4F538072642A904008B27DF /* rounding.h */,
|
||||
E4F538082642A904008B27DF /* types.h */,
|
||||
);
|
||||
name = fpu;
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
/* End PBXGroup section */
|
||||
|
||||
/* Begin PBXHeadersBuildPhase section */
|
||||
E4F537BE2642A86D008B27DF /* Headers */ = {
|
||||
isa = PBXHeadersBuildPhase;
|
||||
buildActionMask = 2147483647;
|
||||
files = (
|
||||
E4F538182642A904008B27DF /* mathlib.h in Headers */,
|
||||
E4F538152642A904008B27DF /* fpu.h in Headers */,
|
||||
E4F5380F2642A904008B27DF /* fpu_ieee.h in Headers */,
|
||||
E4F537F12642A8E8008B27DF /* compemu.h in Headers */,
|
||||
E4F538092642A904008B27DF /* core.h in Headers */,
|
||||
E4C1B4AA2642B05A00EB55A0 /* cputbl.h in Headers */,
|
||||
E4F5381B2642A904008B27DF /* types.h in Headers */,
|
||||
E4F537DF2642A8CC008B27DF /* newcpu.h in Headers */,
|
||||
E4F5380D2642A904008B27DF /* flags.h in Headers */,
|
||||
E4F537E22642A8CC008B27DF /* readcpu.h in Headers */,
|
||||
E4F5381A2642A904008B27DF /* rounding.h in Headers */,
|
||||
E4C1B4A52642B05A00EB55A0 /* comptbl.h in Headers */,
|
||||
E4F5380B2642A904008B27DF /* exceptions.h in Headers */,
|
||||
E4F537E32642A8CC008B27DF /* spcflags.h in Headers */,
|
||||
E4F537DB2642A8CC008B27DF /* m68k.h in Headers */,
|
||||
E4F537F22642A8E8008B27DF /* flags_x86.h in Headers */,
|
||||
E4F538162642A904008B27DF /* impl.h in Headers */,
|
||||
E4F537CD2642A8C2008B27DF /* cpu_emulation.h in Headers */,
|
||||
E4F537EE2642A8E8008B27DF /* codegen_x86.h in Headers */,
|
||||
E4F537DD2642A8CC008B27DF /* memory.h in Headers */,
|
||||
E4F537E02642A8CC008B27DF /* noflags.h in Headers */,
|
||||
);
|
||||
runOnlyForDeploymentPostprocessing = 0;
|
||||
};
|
||||
/* End PBXHeadersBuildPhase section */
|
||||
|
||||
/* Begin PBXNativeTarget section */
|
||||
E4F537BF2642A86D008B27DF /* uae_cpu_x86_64 */ = {
|
||||
isa = PBXNativeTarget;
|
||||
buildConfigurationList = E4F537C42642A86D008B27DF /* Build configuration list for PBXNativeTarget "uae_cpu_x86_64" */;
|
||||
buildPhases = (
|
||||
E4C1B4992642AF5100EB55A0 /* ShellScript */,
|
||||
E4F537BC2642A86D008B27DF /* Sources */,
|
||||
E4F537BD2642A86D008B27DF /* Frameworks */,
|
||||
E4F537BE2642A86D008B27DF /* Headers */,
|
||||
);
|
||||
buildRules = (
|
||||
);
|
||||
dependencies = (
|
||||
);
|
||||
name = uae_cpu_x86_64;
|
||||
productName = uae_cpu;
|
||||
productReference = E4F537C02642A86D008B27DF /* libuae_cpu_x86_64.a */;
|
||||
productType = "com.apple.product-type.library.static";
|
||||
};
|
||||
/* End PBXNativeTarget section */
|
||||
|
||||
/* Begin PBXProject section */
|
||||
E4F537B82642A86D008B27DF /* Project object */ = {
|
||||
isa = PBXProject;
|
||||
attributes = {
|
||||
LastUpgradeCheck = 0820;
|
||||
TargetAttributes = {
|
||||
E4F537BF2642A86D008B27DF = {
|
||||
CreatedOnToolsVersion = 8.2.1;
|
||||
ProvisioningStyle = Automatic;
|
||||
};
|
||||
};
|
||||
};
|
||||
buildConfigurationList = E4F537BB2642A86D008B27DF /* Build configuration list for PBXProject "uae_cpu" */;
|
||||
compatibilityVersion = "Xcode 3.2";
|
||||
developmentRegion = English;
|
||||
hasScannedForEncodings = 0;
|
||||
knownRegions = (
|
||||
English,
|
||||
en,
|
||||
);
|
||||
mainGroup = E4F537B72642A86D008B27DF;
|
||||
productRefGroup = E4F537C12642A86D008B27DF /* Products */;
|
||||
projectDirPath = "";
|
||||
projectRoot = "";
|
||||
targets = (
|
||||
E4F537BF2642A86D008B27DF /* uae_cpu_x86_64 */,
|
||||
);
|
||||
};
|
||||
/* End PBXProject section */
|
||||
|
||||
/* Begin PBXShellScriptBuildPhase section */
|
||||
E4C1B4992642AF5100EB55A0 /* ShellScript */ = {
|
||||
isa = PBXShellScriptBuildPhase;
|
||||
buildActionMask = 2147483647;
|
||||
files = (
|
||||
);
|
||||
inputPaths = (
|
||||
);
|
||||
outputPaths = (
|
||||
$BUILT_PRODUCTS_DIR/gencpu_output/cpuemu.cpp,
|
||||
$BUILT_PRODUCTS_DIR/gencpu_output/cpuemu_nf.cpp,
|
||||
$BUILT_PRODUCTS_DIR/gencpu_output/cpustbl.cpp,
|
||||
$BUILT_PRODUCTS_DIR/gencpu_output/cpustbl_nf.cpp,
|
||||
$BUILT_PRODUCTS_DIR/gencpu_output/defs68k.c,
|
||||
$BUILT_PRODUCTS_DIR/gencpu_output/compemu.cpp,
|
||||
$BUILT_PRODUCTS_DIR/gencpu_output/compstbl.cpp,
|
||||
);
|
||||
runOnlyForDeploymentPostprocessing = 0;
|
||||
shellPath = /bin/sh;
|
||||
shellScript = "make -f Makefile.gencpu\n";
|
||||
};
|
||||
/* End PBXShellScriptBuildPhase section */
|
||||
|
||||
/* Begin PBXSourcesBuildPhase section */
|
||||
E4F537BC2642A86D008B27DF /* Sources */ = {
|
||||
isa = PBXSourcesBuildPhase;
|
||||
buildActionMask = 2147483647;
|
||||
files = (
|
||||
E4C1B4A62642B05A00EB55A0 /* cpuemu_nf.cpp in Sources */,
|
||||
E4C1B4A32642B05A00EB55A0 /* compemu.cpp in Sources */,
|
||||
E4F538192642A904008B27DF /* rounding.cpp in Sources */,
|
||||
E4F537E12642A8CC008B27DF /* readcpu.cpp in Sources */,
|
||||
E4F5380C2642A904008B27DF /* flags.cpp in Sources */,
|
||||
E4F537EF2642A8E8008B27DF /* compemu_fpp.cpp in Sources */,
|
||||
E4F538172642A904008B27DF /* mathlib.cpp in Sources */,
|
||||
E4F537F02642A8E8008B27DF /* compemu_support.cpp in Sources */,
|
||||
E4F537DC2642A8CC008B27DF /* memory.cpp in Sources */,
|
||||
E4C1B4A42642B05A00EB55A0 /* compstbl.cpp in Sources */,
|
||||
E4C1B4AB2642B05A00EB55A0 /* defs68k.c in Sources */,
|
||||
E4C1B4A92642B05A00EB55A0 /* cpustbl.cpp in Sources */,
|
||||
E4F537C92642A8BA008B27DF /* basilisk_glue.cpp in Sources */,
|
||||
E4F537F32642A8E8008B27DF /* gencomp.c in Sources */,
|
||||
E4F5380E2642A904008B27DF /* fpu_ieee.cpp in Sources */,
|
||||
E4C1B4A72642B05A00EB55A0 /* cpuemu.cpp in Sources */,
|
||||
E4C1B4A82642B05A00EB55A0 /* cpustbl_nf.cpp in Sources */,
|
||||
E4F537DE2642A8CC008B27DF /* newcpu.cpp in Sources */,
|
||||
E4F5380A2642A904008B27DF /* exceptions.cpp in Sources */,
|
||||
);
|
||||
runOnlyForDeploymentPostprocessing = 0;
|
||||
};
|
||||
/* End PBXSourcesBuildPhase section */
|
||||
|
||||
/* Begin XCBuildConfiguration section */
|
||||
E4F537C22642A86D008B27DF /* Debug */ = {
|
||||
isa = XCBuildConfiguration;
|
||||
buildSettings = {
|
||||
ALWAYS_SEARCH_USER_PATHS = NO;
|
||||
CLANG_ANALYZER_NONNULL = YES;
|
||||
CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x";
|
||||
CLANG_CXX_LIBRARY = "libc++";
|
||||
CLANG_ENABLE_MODULES = YES;
|
||||
CLANG_ENABLE_OBJC_ARC = YES;
|
||||
CLANG_WARN_BOOL_CONVERSION = YES;
|
||||
CLANG_WARN_CONSTANT_CONVERSION = YES;
|
||||
CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
|
||||
CLANG_WARN_DOCUMENTATION_COMMENTS = YES;
|
||||
CLANG_WARN_EMPTY_BODY = YES;
|
||||
CLANG_WARN_ENUM_CONVERSION = YES;
|
||||
CLANG_WARN_INFINITE_RECURSION = YES;
|
||||
CLANG_WARN_INT_CONVERSION = YES;
|
||||
CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
|
||||
CLANG_WARN_SUSPICIOUS_MOVE = YES;
|
||||
CLANG_WARN_UNREACHABLE_CODE = YES;
|
||||
CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
|
||||
CODE_SIGN_IDENTITY = "-";
|
||||
COPY_PHASE_STRIP = NO;
|
||||
DEBUG_INFORMATION_FORMAT = dwarf;
|
||||
ENABLE_STRICT_OBJC_MSGSEND = YES;
|
||||
ENABLE_TESTABILITY = YES;
|
||||
GCC_C_LANGUAGE_STANDARD = gnu99;
|
||||
GCC_DYNAMIC_NO_PIC = NO;
|
||||
GCC_NO_COMMON_BLOCKS = YES;
|
||||
GCC_OPTIMIZATION_LEVEL = 0;
|
||||
GCC_PREPROCESSOR_DEFINITIONS = (
|
||||
"DEBUG=1",
|
||||
"$(inherited)",
|
||||
);
|
||||
GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
|
||||
GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;
|
||||
GCC_WARN_UNDECLARED_SELECTOR = YES;
|
||||
GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
|
||||
GCC_WARN_UNUSED_FUNCTION = YES;
|
||||
GCC_WARN_UNUSED_VARIABLE = YES;
|
||||
MACOSX_DEPLOYMENT_TARGET = 10.7;
|
||||
MTL_ENABLE_DEBUG_INFO = YES;
|
||||
ONLY_ACTIVE_ARCH = YES;
|
||||
SDKROOT = macosx;
|
||||
};
|
||||
name = Debug;
|
||||
};
|
||||
E4F537C32642A86D008B27DF /* Release */ = {
|
||||
isa = XCBuildConfiguration;
|
||||
buildSettings = {
|
||||
ALWAYS_SEARCH_USER_PATHS = NO;
|
||||
CLANG_ANALYZER_NONNULL = YES;
|
||||
CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x";
|
||||
CLANG_CXX_LIBRARY = "libc++";
|
||||
CLANG_ENABLE_MODULES = YES;
|
||||
CLANG_ENABLE_OBJC_ARC = YES;
|
||||
CLANG_WARN_BOOL_CONVERSION = YES;
|
||||
CLANG_WARN_CONSTANT_CONVERSION = YES;
|
||||
CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
|
||||
CLANG_WARN_DOCUMENTATION_COMMENTS = YES;
|
||||
CLANG_WARN_EMPTY_BODY = YES;
|
||||
CLANG_WARN_ENUM_CONVERSION = YES;
|
||||
CLANG_WARN_INFINITE_RECURSION = YES;
|
||||
CLANG_WARN_INT_CONVERSION = YES;
|
||||
CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
|
||||
CLANG_WARN_SUSPICIOUS_MOVE = YES;
|
||||
CLANG_WARN_UNREACHABLE_CODE = YES;
|
||||
CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
|
||||
CODE_SIGN_IDENTITY = "-";
|
||||
COPY_PHASE_STRIP = NO;
|
||||
DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym";
|
||||
ENABLE_NS_ASSERTIONS = NO;
|
||||
ENABLE_STRICT_OBJC_MSGSEND = YES;
|
||||
GCC_C_LANGUAGE_STANDARD = gnu99;
|
||||
GCC_NO_COMMON_BLOCKS = YES;
|
||||
GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
|
||||
GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;
|
||||
GCC_WARN_UNDECLARED_SELECTOR = YES;
|
||||
GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
|
||||
GCC_WARN_UNUSED_FUNCTION = YES;
|
||||
GCC_WARN_UNUSED_VARIABLE = YES;
|
||||
MACOSX_DEPLOYMENT_TARGET = 10.7;
|
||||
MTL_ENABLE_DEBUG_INFO = NO;
|
||||
SDKROOT = macosx;
|
||||
};
|
||||
name = Release;
|
||||
};
|
||||
E4F537C52642A86D008B27DF /* Debug */ = {
|
||||
isa = XCBuildConfiguration;
|
||||
buildSettings = {
|
||||
ARCHS = x86_64;
|
||||
EXECUTABLE_PREFIX = lib;
|
||||
GCC_PREPROCESSOR_DEFINITIONS = (
|
||||
"$(inherited)",
|
||||
"USE_XCODE=1",
|
||||
CPU_x86_64,
|
||||
JIT,
|
||||
"USE_JIT=1",
|
||||
);
|
||||
GCC_WARN_64_TO_32_BIT_CONVERSION = NO;
|
||||
GCC_WARN_UNUSED_VARIABLE = NO;
|
||||
HEADER_SEARCH_PATHS = (
|
||||
../CrossPlatform,
|
||||
../include,
|
||||
../MacOSX,
|
||||
../uae_cpu,
|
||||
../Unix,
|
||||
);
|
||||
MACOSX_DEPLOYMENT_TARGET = 10.13;
|
||||
OTHER_CFLAGS = "-fwrapv";
|
||||
PRODUCT_NAME = "$(TARGET_NAME)";
|
||||
};
|
||||
name = Debug;
|
||||
};
|
||||
E4F537C62642A86D008B27DF /* Release */ = {
|
||||
isa = XCBuildConfiguration;
|
||||
buildSettings = {
|
||||
ARCHS = x86_64;
|
||||
EXECUTABLE_PREFIX = lib;
|
||||
GCC_PREPROCESSOR_DEFINITIONS = (
|
||||
"USE_XCODE=1",
|
||||
CPU_x86_64,
|
||||
JIT,
|
||||
"USE_JIT=1",
|
||||
);
|
||||
GCC_WARN_64_TO_32_BIT_CONVERSION = NO;
|
||||
GCC_WARN_UNUSED_VARIABLE = NO;
|
||||
HEADER_SEARCH_PATHS = (
|
||||
../CrossPlatform,
|
||||
../include,
|
||||
../MacOSX,
|
||||
../uae_cpu,
|
||||
../Unix,
|
||||
);
|
||||
MACOSX_DEPLOYMENT_TARGET = 10.13;
|
||||
OTHER_CFLAGS = "-fwrapv";
|
||||
PRODUCT_NAME = "$(TARGET_NAME)";
|
||||
};
|
||||
name = Release;
|
||||
};
|
||||
/* End XCBuildConfiguration section */
|
||||
|
||||
/* Begin XCConfigurationList section */
|
||||
E4F537BB2642A86D008B27DF /* Build configuration list for PBXProject "uae_cpu" */ = {
|
||||
isa = XCConfigurationList;
|
||||
buildConfigurations = (
|
||||
E4F537C22642A86D008B27DF /* Debug */,
|
||||
E4F537C32642A86D008B27DF /* Release */,
|
||||
);
|
||||
defaultConfigurationIsVisible = 0;
|
||||
defaultConfigurationName = Release;
|
||||
};
|
||||
E4F537C42642A86D008B27DF /* Build configuration list for PBXNativeTarget "uae_cpu_x86_64" */ = {
|
||||
isa = XCConfigurationList;
|
||||
buildConfigurations = (
|
||||
E4F537C52642A86D008B27DF /* Debug */,
|
||||
E4F537C62642A86D008B27DF /* Release */,
|
||||
);
|
||||
defaultConfigurationIsVisible = 0;
|
||||
defaultConfigurationName = Release;
|
||||
};
|
||||
/* End XCConfigurationList section */
|
||||
};
|
||||
rootObject = E4F537B82642A86D008B27DF /* Project object */;
|
||||
}
|
429
BasiliskII/src/MacOSX/uae_cpu_2021.xcodeproj/project.pbxproj
Normal file
429
BasiliskII/src/MacOSX/uae_cpu_2021.xcodeproj/project.pbxproj
Normal file
@ -0,0 +1,429 @@
|
||||
// !$*UTF8*$!
|
||||
{
|
||||
archiveVersion = 1;
|
||||
classes = {
|
||||
};
|
||||
objectVersion = 46;
|
||||
objects = {
|
||||
|
||||
/* Begin PBXBuildFile section */
|
||||
E41D7AAA2642C070005E8093 /* basilisk_glue.cpp in Sources */ = {isa = PBXBuildFile; fileRef = E41D7AA82642C070005E8093 /* basilisk_glue.cpp */; };
|
||||
E41D7AAE2642C07C005E8093 /* cpu_emulation.h in Headers */ = {isa = PBXBuildFile; fileRef = E41D7AAC2642C07C005E8093 /* cpu_emulation.h */; };
|
||||
E41D7AAF2642C07C005E8093 /* cpummu.h in Headers */ = {isa = PBXBuildFile; fileRef = E41D7AAD2642C07C005E8093 /* cpummu.h */; };
|
||||
E41D7ABB2642C087005E8093 /* m68k.h in Headers */ = {isa = PBXBuildFile; fileRef = E41D7AB12642C087005E8093 /* m68k.h */; };
|
||||
E41D7ABC2642C087005E8093 /* memory.h in Headers */ = {isa = PBXBuildFile; fileRef = E41D7AB22642C087005E8093 /* memory.h */; };
|
||||
E41D7ABD2642C087005E8093 /* newcpu.cpp in Sources */ = {isa = PBXBuildFile; fileRef = E41D7AB32642C087005E8093 /* newcpu.cpp */; };
|
||||
E41D7ABE2642C087005E8093 /* newcpu.h in Headers */ = {isa = PBXBuildFile; fileRef = E41D7AB42642C087005E8093 /* newcpu.h */; };
|
||||
E41D7ABF2642C087005E8093 /* readcpu.cpp in Sources */ = {isa = PBXBuildFile; fileRef = E41D7AB52642C087005E8093 /* readcpu.cpp */; };
|
||||
E41D7AC02642C087005E8093 /* readcpu.h in Headers */ = {isa = PBXBuildFile; fileRef = E41D7AB62642C087005E8093 /* readcpu.h */; };
|
||||
E41D7AC12642C087005E8093 /* registers.h in Headers */ = {isa = PBXBuildFile; fileRef = E41D7AB72642C087005E8093 /* registers.h */; };
|
||||
E41D7AC22642C087005E8093 /* spcflags.h in Headers */ = {isa = PBXBuildFile; fileRef = E41D7AB82642C087005E8093 /* spcflags.h */; };
|
||||
E41D7AD82642C0A4005E8093 /* core.h in Headers */ = {isa = PBXBuildFile; fileRef = E41D7AC42642C0A4005E8093 /* core.h */; };
|
||||
E41D7AD92642C0A4005E8093 /* exceptions.cpp in Sources */ = {isa = PBXBuildFile; fileRef = E41D7AC52642C0A4005E8093 /* exceptions.cpp */; };
|
||||
E41D7ADA2642C0A4005E8093 /* exceptions.h in Headers */ = {isa = PBXBuildFile; fileRef = E41D7AC62642C0A4005E8093 /* exceptions.h */; };
|
||||
E41D7ADB2642C0A4005E8093 /* flags.cpp in Sources */ = {isa = PBXBuildFile; fileRef = E41D7AC72642C0A4005E8093 /* flags.cpp */; };
|
||||
E41D7ADC2642C0A4005E8093 /* flags.h in Headers */ = {isa = PBXBuildFile; fileRef = E41D7AC82642C0A4005E8093 /* flags.h */; };
|
||||
E41D7ADF2642C0A4005E8093 /* fpu_mpfr.cpp in Sources */ = {isa = PBXBuildFile; fileRef = E41D7ACB2642C0A4005E8093 /* fpu_mpfr.cpp */; };
|
||||
E41D7AE52642C0A4005E8093 /* fpu.h in Headers */ = {isa = PBXBuildFile; fileRef = E41D7AD12642C0A4005E8093 /* fpu.h */; };
|
||||
E41D7AE62642C0A4005E8093 /* impl.h in Headers */ = {isa = PBXBuildFile; fileRef = E41D7AD22642C0A4005E8093 /* impl.h */; };
|
||||
E41D7AE72642C0A4005E8093 /* mathlib.cpp in Sources */ = {isa = PBXBuildFile; fileRef = E41D7AD32642C0A4005E8093 /* mathlib.cpp */; };
|
||||
E41D7AE82642C0A4005E8093 /* mathlib.h in Headers */ = {isa = PBXBuildFile; fileRef = E41D7AD42642C0A4005E8093 /* mathlib.h */; };
|
||||
E41D7AE92642C0A4005E8093 /* rounding.cpp in Sources */ = {isa = PBXBuildFile; fileRef = E41D7AD52642C0A4005E8093 /* rounding.cpp */; };
|
||||
E41D7AEA2642C0A4005E8093 /* rounding.h in Headers */ = {isa = PBXBuildFile; fileRef = E41D7AD62642C0A4005E8093 /* rounding.h */; };
|
||||
E41D7AEB2642C0A4005E8093 /* types.h in Headers */ = {isa = PBXBuildFile; fileRef = E41D7AD72642C0A4005E8093 /* types.h */; };
|
||||
E4FC27512642C45E00C64E21 /* cpufunctbl.cpp in Sources */ = {isa = PBXBuildFile; fileRef = E4FC274C2642C45E00C64E21 /* cpufunctbl.cpp */; };
|
||||
E4FC27522642C45E00C64E21 /* cpuemu.cpp in Sources */ = {isa = PBXBuildFile; fileRef = E4FC274D2642C45E00C64E21 /* cpuemu.cpp */; };
|
||||
E4FC27532642C45E00C64E21 /* cpustbl.cpp in Sources */ = {isa = PBXBuildFile; fileRef = E4FC274E2642C45E00C64E21 /* cpustbl.cpp */; };
|
||||
E4FC27542642C45E00C64E21 /* cputbl.h in Headers */ = {isa = PBXBuildFile; fileRef = E4FC274F2642C45E00C64E21 /* cputbl.h */; };
|
||||
E4FC27552642C45E00C64E21 /* defs68k.c in Sources */ = {isa = PBXBuildFile; fileRef = E4FC27502642C45E00C64E21 /* defs68k.c */; };
|
||||
/* End PBXBuildFile section */
|
||||
|
||||
/* Begin PBXFileReference section */
|
||||
E41D7AA12642C004005E8093 /* libuae_cpu_arm64.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = libuae_cpu_arm64.a; sourceTree = BUILT_PRODUCTS_DIR; };
|
||||
E41D7AA82642C070005E8093 /* basilisk_glue.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = basilisk_glue.cpp; path = ../uae_cpu_2021/basilisk_glue.cpp; sourceTree = "<group>"; };
|
||||
E41D7AAC2642C07C005E8093 /* cpu_emulation.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = cpu_emulation.h; path = ../uae_cpu_2021/cpu_emulation.h; sourceTree = "<group>"; };
|
||||
E41D7AAD2642C07C005E8093 /* cpummu.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = cpummu.h; path = ../uae_cpu_2021/cpummu.h; sourceTree = "<group>"; };
|
||||
E41D7AB12642C087005E8093 /* m68k.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = m68k.h; path = ../uae_cpu_2021/m68k.h; sourceTree = "<group>"; };
|
||||
E41D7AB22642C087005E8093 /* memory.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = memory.h; path = ../uae_cpu_2021/memory.h; sourceTree = "<group>"; };
|
||||
E41D7AB32642C087005E8093 /* newcpu.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = newcpu.cpp; path = ../uae_cpu_2021/newcpu.cpp; sourceTree = "<group>"; };
|
||||
E41D7AB42642C087005E8093 /* newcpu.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = newcpu.h; path = ../uae_cpu_2021/newcpu.h; sourceTree = "<group>"; };
|
||||
E41D7AB52642C087005E8093 /* readcpu.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = readcpu.cpp; path = ../uae_cpu_2021/readcpu.cpp; sourceTree = "<group>"; };
|
||||
E41D7AB62642C087005E8093 /* readcpu.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = readcpu.h; path = ../uae_cpu_2021/readcpu.h; sourceTree = "<group>"; };
|
||||
E41D7AB72642C087005E8093 /* registers.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = registers.h; path = ../uae_cpu_2021/registers.h; sourceTree = "<group>"; };
|
||||
E41D7AB82642C087005E8093 /* spcflags.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = spcflags.h; path = ../uae_cpu_2021/spcflags.h; sourceTree = "<group>"; };
|
||||
E41D7AB92642C087005E8093 /* table68k */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; name = table68k; path = ../uae_cpu_2021/table68k; sourceTree = "<group>"; };
|
||||
E41D7AC42642C0A4005E8093 /* core.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = core.h; path = ../uae_cpu_2021/fpu/core.h; sourceTree = "<group>"; };
|
||||
E41D7AC52642C0A4005E8093 /* exceptions.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = exceptions.cpp; path = ../uae_cpu_2021/fpu/exceptions.cpp; sourceTree = "<group>"; };
|
||||
E41D7AC62642C0A4005E8093 /* exceptions.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = exceptions.h; path = ../uae_cpu_2021/fpu/exceptions.h; sourceTree = "<group>"; };
|
||||
E41D7AC72642C0A4005E8093 /* flags.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = flags.cpp; path = ../uae_cpu_2021/fpu/flags.cpp; sourceTree = "<group>"; };
|
||||
E41D7AC82642C0A4005E8093 /* flags.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = flags.h; path = ../uae_cpu_2021/fpu/flags.h; sourceTree = "<group>"; };
|
||||
E41D7ACB2642C0A4005E8093 /* fpu_mpfr.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = fpu_mpfr.cpp; path = ../uae_cpu_2021/fpu/fpu_mpfr.cpp; sourceTree = "<group>"; };
|
||||
E41D7AD12642C0A4005E8093 /* fpu.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = fpu.h; path = ../uae_cpu_2021/fpu/fpu.h; sourceTree = "<group>"; };
|
||||
E41D7AD22642C0A4005E8093 /* impl.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = impl.h; path = ../uae_cpu_2021/fpu/impl.h; sourceTree = "<group>"; };
|
||||
E41D7AD32642C0A4005E8093 /* mathlib.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = mathlib.cpp; path = ../uae_cpu_2021/fpu/mathlib.cpp; sourceTree = "<group>"; };
|
||||
E41D7AD42642C0A4005E8093 /* mathlib.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = mathlib.h; path = ../uae_cpu_2021/fpu/mathlib.h; sourceTree = "<group>"; };
|
||||
E41D7AD52642C0A4005E8093 /* rounding.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = rounding.cpp; path = ../uae_cpu_2021/fpu/rounding.cpp; sourceTree = "<group>"; };
|
||||
E41D7AD62642C0A4005E8093 /* rounding.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = rounding.h; path = ../uae_cpu_2021/fpu/rounding.h; sourceTree = "<group>"; };
|
||||
E41D7AD72642C0A4005E8093 /* types.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = types.h; path = ../uae_cpu_2021/fpu/types.h; sourceTree = "<group>"; };
|
||||
E4FC274C2642C45E00C64E21 /* cpufunctbl.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = cpufunctbl.cpp; path = gencpu_output_2021/cpufunctbl.cpp; sourceTree = BUILT_PRODUCTS_DIR; };
|
||||
E4FC274D2642C45E00C64E21 /* cpuemu.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = cpuemu.cpp; path = gencpu_output_2021/cpuemu.cpp; sourceTree = BUILT_PRODUCTS_DIR; };
|
||||
E4FC274E2642C45E00C64E21 /* cpustbl.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = cpustbl.cpp; path = gencpu_output_2021/cpustbl.cpp; sourceTree = BUILT_PRODUCTS_DIR; };
|
||||
E4FC274F2642C45E00C64E21 /* cputbl.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = cputbl.h; path = gencpu_output_2021/cputbl.h; sourceTree = BUILT_PRODUCTS_DIR; };
|
||||
E4FC27502642C45E00C64E21 /* defs68k.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = defs68k.c; path = gencpu_output_2021/defs68k.c; sourceTree = BUILT_PRODUCTS_DIR; };
|
||||
/* End PBXFileReference section */
|
||||
|
||||
/* Begin PBXFrameworksBuildPhase section */
|
||||
E41D7A9E2642C004005E8093 /* Frameworks */ = {
|
||||
isa = PBXFrameworksBuildPhase;
|
||||
buildActionMask = 2147483647;
|
||||
files = (
|
||||
);
|
||||
runOnlyForDeploymentPostprocessing = 0;
|
||||
};
|
||||
/* End PBXFrameworksBuildPhase section */
|
||||
|
||||
/* Begin PBXGroup section */
|
||||
E41D7A982642C004005E8093 = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
E41D7AA82642C070005E8093 /* basilisk_glue.cpp */,
|
||||
E41D7AC32642C08E005E8093 /* fpu */,
|
||||
E41D7AAC2642C07C005E8093 /* cpu_emulation.h */,
|
||||
E41D7AAD2642C07C005E8093 /* cpummu.h */,
|
||||
E41D7AB12642C087005E8093 /* m68k.h */,
|
||||
E41D7AB22642C087005E8093 /* memory.h */,
|
||||
E41D7AB32642C087005E8093 /* newcpu.cpp */,
|
||||
E41D7AB42642C087005E8093 /* newcpu.h */,
|
||||
E41D7AB52642C087005E8093 /* readcpu.cpp */,
|
||||
E41D7AB62642C087005E8093 /* readcpu.h */,
|
||||
E41D7AB72642C087005E8093 /* registers.h */,
|
||||
E41D7AB82642C087005E8093 /* spcflags.h */,
|
||||
E41D7AB92642C087005E8093 /* table68k */,
|
||||
E4FC274B2642C44A00C64E21 /* generated */,
|
||||
E41D7AA22642C004005E8093 /* Products */,
|
||||
);
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
E41D7AA22642C004005E8093 /* Products */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
E41D7AA12642C004005E8093 /* libuae_cpu_arm64.a */,
|
||||
);
|
||||
name = Products;
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
E41D7AC32642C08E005E8093 /* fpu */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
E41D7AC42642C0A4005E8093 /* core.h */,
|
||||
E41D7AC52642C0A4005E8093 /* exceptions.cpp */,
|
||||
E41D7AC62642C0A4005E8093 /* exceptions.h */,
|
||||
E41D7AC72642C0A4005E8093 /* flags.cpp */,
|
||||
E41D7AC82642C0A4005E8093 /* flags.h */,
|
||||
E41D7ACB2642C0A4005E8093 /* fpu_mpfr.cpp */,
|
||||
E41D7AD12642C0A4005E8093 /* fpu.h */,
|
||||
E41D7AD22642C0A4005E8093 /* impl.h */,
|
||||
E41D7AD32642C0A4005E8093 /* mathlib.cpp */,
|
||||
E41D7AD42642C0A4005E8093 /* mathlib.h */,
|
||||
E41D7AD52642C0A4005E8093 /* rounding.cpp */,
|
||||
E41D7AD62642C0A4005E8093 /* rounding.h */,
|
||||
E41D7AD72642C0A4005E8093 /* types.h */,
|
||||
);
|
||||
name = fpu;
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
E4FC274B2642C44A00C64E21 /* generated */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
E4FC274D2642C45E00C64E21 /* cpuemu.cpp */,
|
||||
E4FC274C2642C45E00C64E21 /* cpufunctbl.cpp */,
|
||||
E4FC274E2642C45E00C64E21 /* cpustbl.cpp */,
|
||||
E4FC274F2642C45E00C64E21 /* cputbl.h */,
|
||||
E4FC27502642C45E00C64E21 /* defs68k.c */,
|
||||
);
|
||||
path = generated;
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
/* End PBXGroup section */
|
||||
|
||||
/* Begin PBXHeadersBuildPhase section */
|
||||
E41D7A9F2642C004005E8093 /* Headers */ = {
|
||||
isa = PBXHeadersBuildPhase;
|
||||
buildActionMask = 2147483647;
|
||||
files = (
|
||||
E41D7AE82642C0A4005E8093 /* mathlib.h in Headers */,
|
||||
E41D7ADA2642C0A4005E8093 /* exceptions.h in Headers */,
|
||||
E41D7ABB2642C087005E8093 /* m68k.h in Headers */,
|
||||
E41D7AC02642C087005E8093 /* readcpu.h in Headers */,
|
||||
E41D7AEA2642C0A4005E8093 /* rounding.h in Headers */,
|
||||
E41D7AAE2642C07C005E8093 /* cpu_emulation.h in Headers */,
|
||||
E41D7AC22642C087005E8093 /* spcflags.h in Headers */,
|
||||
E41D7AE52642C0A4005E8093 /* fpu.h in Headers */,
|
||||
E41D7AAF2642C07C005E8093 /* cpummu.h in Headers */,
|
||||
E41D7AC12642C087005E8093 /* registers.h in Headers */,
|
||||
E41D7AD82642C0A4005E8093 /* core.h in Headers */,
|
||||
E4FC27542642C45E00C64E21 /* cputbl.h in Headers */,
|
||||
E41D7ABE2642C087005E8093 /* newcpu.h in Headers */,
|
||||
E41D7AE62642C0A4005E8093 /* impl.h in Headers */,
|
||||
E41D7ABC2642C087005E8093 /* memory.h in Headers */,
|
||||
E41D7AEB2642C0A4005E8093 /* types.h in Headers */,
|
||||
E41D7ADC2642C0A4005E8093 /* flags.h in Headers */,
|
||||
);
|
||||
runOnlyForDeploymentPostprocessing = 0;
|
||||
};
|
||||
/* End PBXHeadersBuildPhase section */
|
||||
|
||||
/* Begin PBXNativeTarget section */
|
||||
E41D7AA02642C004005E8093 /* uae_cpu_arm64 */ = {
|
||||
isa = PBXNativeTarget;
|
||||
buildConfigurationList = E41D7AA52642C004005E8093 /* Build configuration list for PBXNativeTarget "uae_cpu_arm64" */;
|
||||
buildPhases = (
|
||||
E4FC27492642C2E600C64E21 /* ShellScript */,
|
||||
E41D7A9D2642C004005E8093 /* Sources */,
|
||||
E41D7A9E2642C004005E8093 /* Frameworks */,
|
||||
E41D7A9F2642C004005E8093 /* Headers */,
|
||||
);
|
||||
buildRules = (
|
||||
);
|
||||
dependencies = (
|
||||
);
|
||||
name = uae_cpu_arm64;
|
||||
productName = uae_cpu_2021;
|
||||
productReference = E41D7AA12642C004005E8093 /* libuae_cpu_arm64.a */;
|
||||
productType = "com.apple.product-type.library.static";
|
||||
};
|
||||
/* End PBXNativeTarget section */
|
||||
|
||||
/* Begin PBXProject section */
|
||||
E41D7A992642C004005E8093 /* Project object */ = {
|
||||
isa = PBXProject;
|
||||
attributes = {
|
||||
LastUpgradeCheck = 0820;
|
||||
TargetAttributes = {
|
||||
E41D7AA02642C004005E8093 = {
|
||||
CreatedOnToolsVersion = 8.2.1;
|
||||
ProvisioningStyle = Automatic;
|
||||
};
|
||||
};
|
||||
};
|
||||
buildConfigurationList = E41D7A9C2642C004005E8093 /* Build configuration list for PBXProject "uae_cpu_2021" */;
|
||||
compatibilityVersion = "Xcode 3.2";
|
||||
developmentRegion = English;
|
||||
hasScannedForEncodings = 0;
|
||||
knownRegions = (
|
||||
English,
|
||||
en,
|
||||
);
|
||||
mainGroup = E41D7A982642C004005E8093;
|
||||
productRefGroup = E41D7AA22642C004005E8093 /* Products */;
|
||||
projectDirPath = "";
|
||||
projectRoot = "";
|
||||
targets = (
|
||||
E41D7AA02642C004005E8093 /* uae_cpu_arm64 */,
|
||||
);
|
||||
};
|
||||
/* End PBXProject section */
|
||||
|
||||
/* Begin PBXShellScriptBuildPhase section */
|
||||
E4FC27492642C2E600C64E21 /* ShellScript */ = {
|
||||
isa = PBXShellScriptBuildPhase;
|
||||
buildActionMask = 2147483647;
|
||||
files = (
|
||||
);
|
||||
inputFileListPaths = (
|
||||
);
|
||||
inputPaths = (
|
||||
);
|
||||
outputFileListPaths = (
|
||||
);
|
||||
outputPaths = (
|
||||
$BUILT_PRODUCTS_DIR/gencpu_output_2021/cpuemu.cpp,
|
||||
$BUILT_PRODUCTS_DIR/gencpu_output_2021/cpufunctbl.cpp,
|
||||
$BUILT_PRODUCTS_DIR/gencpu_output_2021/cpustbl.cpp,
|
||||
$BUILT_PRODUCTS_DIR/gencpu_output_2021/cputbl.h,
|
||||
$BUILT_PRODUCTS_DIR/gencpu_output_2021/defs68k.c,
|
||||
);
|
||||
runOnlyForDeploymentPostprocessing = 0;
|
||||
shellPath = /bin/sh;
|
||||
shellScript = "make -f Makefile.gencpu_2021\n";
|
||||
};
|
||||
/* End PBXShellScriptBuildPhase section */
|
||||
|
||||
/* Begin PBXSourcesBuildPhase section */
|
||||
E41D7A9D2642C004005E8093 /* Sources */ = {
|
||||
isa = PBXSourcesBuildPhase;
|
||||
buildActionMask = 2147483647;
|
||||
files = (
|
||||
E4FC27512642C45E00C64E21 /* cpufunctbl.cpp in Sources */,
|
||||
E41D7ADB2642C0A4005E8093 /* flags.cpp in Sources */,
|
||||
E41D7ADF2642C0A4005E8093 /* fpu_mpfr.cpp in Sources */,
|
||||
E41D7ABD2642C087005E8093 /* newcpu.cpp in Sources */,
|
||||
E4FC27552642C45E00C64E21 /* defs68k.c in Sources */,
|
||||
E41D7AE72642C0A4005E8093 /* mathlib.cpp in Sources */,
|
||||
E4FC27522642C45E00C64E21 /* cpuemu.cpp in Sources */,
|
||||
E4FC27532642C45E00C64E21 /* cpustbl.cpp in Sources */,
|
||||
E41D7AD92642C0A4005E8093 /* exceptions.cpp in Sources */,
|
||||
E41D7AAA2642C070005E8093 /* basilisk_glue.cpp in Sources */,
|
||||
E41D7ABF2642C087005E8093 /* readcpu.cpp in Sources */,
|
||||
E41D7AE92642C0A4005E8093 /* rounding.cpp in Sources */,
|
||||
);
|
||||
runOnlyForDeploymentPostprocessing = 0;
|
||||
};
|
||||
/* End PBXSourcesBuildPhase section */
|
||||
|
||||
/* Begin XCBuildConfiguration section */
|
||||
E41D7AA32642C004005E8093 /* Debug */ = {
|
||||
isa = XCBuildConfiguration;
|
||||
buildSettings = {
|
||||
ALWAYS_SEARCH_USER_PATHS = NO;
|
||||
CLANG_ANALYZER_NONNULL = YES;
|
||||
CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x";
|
||||
CLANG_CXX_LIBRARY = "libc++";
|
||||
CLANG_ENABLE_MODULES = YES;
|
||||
CLANG_ENABLE_OBJC_ARC = YES;
|
||||
CLANG_WARN_BOOL_CONVERSION = YES;
|
||||
CLANG_WARN_CONSTANT_CONVERSION = YES;
|
||||
CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
|
||||
CLANG_WARN_DOCUMENTATION_COMMENTS = YES;
|
||||
CLANG_WARN_EMPTY_BODY = YES;
|
||||
CLANG_WARN_ENUM_CONVERSION = YES;
|
||||
CLANG_WARN_INFINITE_RECURSION = YES;
|
||||
CLANG_WARN_INT_CONVERSION = YES;
|
||||
CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
|
||||
CLANG_WARN_SUSPICIOUS_MOVE = YES;
|
||||
CLANG_WARN_UNREACHABLE_CODE = YES;
|
||||
CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
|
||||
CODE_SIGN_IDENTITY = "-";
|
||||
COPY_PHASE_STRIP = NO;
|
||||
DEBUG_INFORMATION_FORMAT = dwarf;
|
||||
ENABLE_STRICT_OBJC_MSGSEND = YES;
|
||||
ENABLE_TESTABILITY = YES;
|
||||
GCC_C_LANGUAGE_STANDARD = gnu99;
|
||||
GCC_DYNAMIC_NO_PIC = NO;
|
||||
GCC_NO_COMMON_BLOCKS = YES;
|
||||
GCC_OPTIMIZATION_LEVEL = 0;
|
||||
GCC_PREPROCESSOR_DEFINITIONS = (
|
||||
"DEBUG=1",
|
||||
"$(inherited)",
|
||||
);
|
||||
GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
|
||||
GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;
|
||||
GCC_WARN_UNDECLARED_SELECTOR = YES;
|
||||
GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
|
||||
GCC_WARN_UNUSED_FUNCTION = YES;
|
||||
GCC_WARN_UNUSED_VARIABLE = YES;
|
||||
MACOSX_DEPLOYMENT_TARGET = 10.13;
|
||||
MTL_ENABLE_DEBUG_INFO = YES;
|
||||
ONLY_ACTIVE_ARCH = YES;
|
||||
SDKROOT = macosx;
|
||||
};
|
||||
name = Debug;
|
||||
};
|
||||
E41D7AA42642C004005E8093 /* Release */ = {
|
||||
isa = XCBuildConfiguration;
|
||||
buildSettings = {
|
||||
ALWAYS_SEARCH_USER_PATHS = NO;
|
||||
CLANG_ANALYZER_NONNULL = YES;
|
||||
CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x";
|
||||
CLANG_CXX_LIBRARY = "libc++";
|
||||
CLANG_ENABLE_MODULES = YES;
|
||||
CLANG_ENABLE_OBJC_ARC = YES;
|
||||
CLANG_WARN_BOOL_CONVERSION = YES;
|
||||
CLANG_WARN_CONSTANT_CONVERSION = YES;
|
||||
CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
|
||||
CLANG_WARN_DOCUMENTATION_COMMENTS = YES;
|
||||
CLANG_WARN_EMPTY_BODY = YES;
|
||||
CLANG_WARN_ENUM_CONVERSION = YES;
|
||||
CLANG_WARN_INFINITE_RECURSION = YES;
|
||||
CLANG_WARN_INT_CONVERSION = YES;
|
||||
CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
|
||||
CLANG_WARN_SUSPICIOUS_MOVE = YES;
|
||||
CLANG_WARN_UNREACHABLE_CODE = YES;
|
||||
CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
|
||||
CODE_SIGN_IDENTITY = "-";
|
||||
COPY_PHASE_STRIP = NO;
|
||||
DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym";
|
||||
ENABLE_NS_ASSERTIONS = NO;
|
||||
ENABLE_STRICT_OBJC_MSGSEND = YES;
|
||||
GCC_C_LANGUAGE_STANDARD = gnu99;
|
||||
GCC_NO_COMMON_BLOCKS = YES;
|
||||
GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
|
||||
GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;
|
||||
GCC_WARN_UNDECLARED_SELECTOR = YES;
|
||||
GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
|
||||
GCC_WARN_UNUSED_FUNCTION = YES;
|
||||
GCC_WARN_UNUSED_VARIABLE = YES;
|
||||
MACOSX_DEPLOYMENT_TARGET = 10.13;
|
||||
MTL_ENABLE_DEBUG_INFO = NO;
|
||||
SDKROOT = macosx;
|
||||
};
|
||||
name = Release;
|
||||
};
|
||||
E41D7AA62642C004005E8093 /* Debug */ = {
|
||||
isa = XCBuildConfiguration;
|
||||
buildSettings = {
|
||||
ARCHS = "$(ARCHS_STANDARD)";
|
||||
EXECUTABLE_PREFIX = lib;
|
||||
GCC_PREPROCESSOR_DEFINITIONS = (
|
||||
"$(inherited)",
|
||||
"USE_XCODE=1",
|
||||
);
|
||||
HEADER_SEARCH_PATHS = (
|
||||
/usr/local/include,
|
||||
../CrossPlatform,
|
||||
../include,
|
||||
../MacOSX,
|
||||
../uae_cpu_2021,
|
||||
../Unix,
|
||||
);
|
||||
OTHER_CFLAGS = "-fwrapv";
|
||||
PRODUCT_NAME = "$(TARGET_NAME)";
|
||||
VALID_ARCHS = arm64;
|
||||
};
|
||||
name = Debug;
|
||||
};
|
||||
E41D7AA72642C004005E8093 /* Release */ = {
|
||||
isa = XCBuildConfiguration;
|
||||
buildSettings = {
|
||||
ARCHS = "$(ARCHS_STANDARD)";
|
||||
EXECUTABLE_PREFIX = lib;
|
||||
GCC_PREPROCESSOR_DEFINITIONS = "USE_XCODE=1";
|
||||
HEADER_SEARCH_PATHS = (
|
||||
/usr/local/include,
|
||||
../CrossPlatform,
|
||||
../include,
|
||||
../MacOSX,
|
||||
../uae_cpu_2021,
|
||||
../Unix,
|
||||
);
|
||||
OTHER_CFLAGS = "-fwrapv";
|
||||
PRODUCT_NAME = "$(TARGET_NAME)";
|
||||
VALID_ARCHS = arm64;
|
||||
};
|
||||
name = Release;
|
||||
};
|
||||
/* End XCBuildConfiguration section */
|
||||
|
||||
/* Begin XCConfigurationList section */
|
||||
E41D7A9C2642C004005E8093 /* Build configuration list for PBXProject "uae_cpu_2021" */ = {
|
||||
isa = XCConfigurationList;
|
||||
buildConfigurations = (
|
||||
E41D7AA32642C004005E8093 /* Debug */,
|
||||
E41D7AA42642C004005E8093 /* Release */,
|
||||
);
|
||||
defaultConfigurationIsVisible = 0;
|
||||
defaultConfigurationName = Release;
|
||||
};
|
||||
E41D7AA52642C004005E8093 /* Build configuration list for PBXNativeTarget "uae_cpu_arm64" */ = {
|
||||
isa = XCConfigurationList;
|
||||
buildConfigurations = (
|
||||
E41D7AA62642C004005E8093 /* Debug */,
|
||||
E41D7AA72642C004005E8093 /* Release */,
|
||||
);
|
||||
defaultConfigurationIsVisible = 0;
|
||||
defaultConfigurationName = Release;
|
||||
};
|
||||
/* End XCConfigurationList section */
|
||||
};
|
||||
rootObject = E41D7A992642C004005E8093 /* Project object */;
|
||||
}
|
@ -21,7 +21,20 @@
|
||||
#ifndef UTILS_MACOSX_H
|
||||
#define UTILS_MACOSX_H
|
||||
|
||||
// Invokes the specified function with an NSAutoReleasePool in place.
|
||||
void NSAutoReleasePool_wrap(void (*fn)(void));
|
||||
#ifdef USE_SDL
|
||||
#if SDL_VERSION_ATLEAST(2,0,0)
|
||||
void disable_SDL2_macosx_menu_bar_keyboard_shortcuts();
|
||||
bool is_fullscreen_osx(SDL_Window * window);
|
||||
#endif
|
||||
#endif
|
||||
|
||||
void set_menu_bar_visible_osx(bool visible);
|
||||
|
||||
void set_current_directory();
|
||||
|
||||
bool MetalIsAvailable();
|
||||
|
||||
void make_window_transparent(SDL_Window *window);
|
||||
void set_mouse_ignore(SDL_Window *window, int flag);
|
||||
|
||||
#endif
|
||||
|
@ -20,22 +20,17 @@
|
||||
|
||||
#include <Cocoa/Cocoa.h>
|
||||
#include "sysdeps.h"
|
||||
#include "utils_macosx.h"
|
||||
#include <SDL.h>
|
||||
#include "utils_macosx.h"
|
||||
|
||||
#if SDL_VERSION_ATLEAST(2,0,0)
|
||||
#if SDL_VERSION_ATLEAST(2, 0, 0) && !SDL_VERSION_ATLEAST(3, 0, 0)
|
||||
#include <SDL_syswm.h>
|
||||
#endif
|
||||
|
||||
// This is used from video_sdl.cpp.
|
||||
void NSAutoReleasePool_wrap(void (*fn)(void))
|
||||
{
|
||||
NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
|
||||
fn();
|
||||
[pool release];
|
||||
}
|
||||
#include <sys/sysctl.h>
|
||||
#include <Metal/Metal.h>
|
||||
|
||||
#if SDL_VERSION_ATLEAST(2,0,0)
|
||||
#if SDL_VERSION_ATLEAST(2, 0, 0)
|
||||
|
||||
void disable_SDL2_macosx_menu_bar_keyboard_shortcuts() {
|
||||
for (NSMenuItem * menu_item in [NSApp mainMenu].itemArray) {
|
||||
@ -52,22 +47,70 @@ void disable_SDL2_macosx_menu_bar_keyboard_shortcuts() {
|
||||
}
|
||||
}
|
||||
|
||||
static NSWindow *get_nswindow(SDL_Window *window) {
|
||||
#if SDL_VERSION_ATLEAST(3, 0, 0)
|
||||
SDL_PropertiesID props = SDL_GetWindowProperties(window);
|
||||
return (NSWindow *)SDL_GetPointerProperty(props, "SDL.window.cocoa.window", NULL);
|
||||
#else
|
||||
SDL_SysWMinfo wmInfo;
|
||||
SDL_VERSION(&wmInfo.version);
|
||||
return SDL_GetWindowWMInfo(window, &wmInfo) ? wmInfo.info.cocoa.window : nil;
|
||||
#endif
|
||||
}
|
||||
|
||||
bool is_fullscreen_osx(SDL_Window * window)
|
||||
{
|
||||
if (!window) {
|
||||
return false;
|
||||
}
|
||||
|
||||
SDL_SysWMinfo wmInfo;
|
||||
SDL_VERSION(&wmInfo.version);
|
||||
if (!SDL_GetWindowWMInfo(window, &wmInfo)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
const NSWindowStyleMask styleMask = [wmInfo.info.cocoa.window styleMask];
|
||||
const NSWindowStyleMask styleMask = [get_nswindow(window) styleMask];
|
||||
return (styleMask & NSWindowStyleMaskFullScreen) != 0;
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif // SDL_VERSION_ATLEAST(2, 0, 0)
|
||||
|
||||
#if SDL_VERSION_ATLEAST(3, 0, 0) && defined(VIDEO_CHROMAKEY)
|
||||
|
||||
// from https://github.com/zydeco/macemu/tree/rootless/
|
||||
|
||||
void make_window_transparent(SDL_Window *window)
|
||||
{
|
||||
if (!window) {
|
||||
return;
|
||||
}
|
||||
NSWindow *cocoaWindow = get_nswindow(window);
|
||||
NSView *sdlView = cocoaWindow.contentView;
|
||||
sdlView.wantsLayer = YES;
|
||||
sdlView.layer.backgroundColor = [NSColor clearColor].CGColor;
|
||||
static bool observing;
|
||||
if (!observing) {
|
||||
NSNotificationCenter *nc = [NSNotificationCenter defaultCenter];
|
||||
[nc addObserverForName:NSWindowDidBecomeKeyNotification object:cocoaWindow queue:[NSOperationQueue mainQueue] usingBlock:^(NSNotification * _Nonnull note) {
|
||||
NSWindow *window = (NSWindow *)note.object;
|
||||
window.level = NSMainMenuWindowLevel + 1;
|
||||
}];
|
||||
[nc addObserverForName:NSWindowDidResignKeyNotification object:cocoaWindow queue:[NSOperationQueue mainQueue] usingBlock:^(NSNotification * _Nonnull note) {
|
||||
NSWindow *window = (NSWindow *)note.object;
|
||||
// hack for window to be sent behind new key window
|
||||
[window setIsVisible:NO];
|
||||
[window setLevel:NSNormalWindowLevel];
|
||||
[window setIsVisible:YES];
|
||||
}];
|
||||
observing = true;
|
||||
}
|
||||
}
|
||||
|
||||
void set_mouse_ignore(SDL_Window *window, int flag) {
|
||||
if (!window) {
|
||||
return;
|
||||
}
|
||||
dispatch_async(dispatch_get_main_queue(), ^{
|
||||
get_nswindow(window).ignoresMouseEvents = flag;
|
||||
});
|
||||
}
|
||||
|
||||
#endif // SDL_VERSION_ATLEAST(3, 0, 0) && defined(VIDEO_CHROMAKEY)
|
||||
|
||||
void set_menu_bar_visible_osx(bool visible)
|
||||
{
|
||||
@ -81,3 +124,14 @@ void set_current_directory()
|
||||
[pool release];
|
||||
}
|
||||
|
||||
bool MetalIsAvailable() {
|
||||
const int EL_CAPITAN = 15; // Darwin major version of El Capitan
|
||||
char s[16];
|
||||
size_t size = sizeof(s);
|
||||
int v;
|
||||
if (sysctlbyname("kern.osrelease", s, &size, NULL, 0) || sscanf(s, "%d", &v) != 1 || v < EL_CAPITAN) return false;
|
||||
id<MTLDevice> dev = MTLCreateSystemDefaultDevice();
|
||||
bool r = dev != nil;
|
||||
[dev release];
|
||||
return r;
|
||||
}
|
||||
|
@ -6,7 +6,18 @@
|
||||
*/
|
||||
|
||||
#include "SDL.h"
|
||||
#if (SDL_COMPILEDVERSION < SDL_VERSIONNUM(2, 0, 0)) // SDLMain.m is not needed in SDL 2.x
|
||||
#if SDL_VERSION_ATLEAST(3, 0, 0)
|
||||
#define SDL_MAIN_NEEDED
|
||||
#include <SDL_main.h>
|
||||
#undef SDL_QUIT
|
||||
#define SDL_QUIT SDL_EVENT_QUIT
|
||||
#else
|
||||
#ifdef main
|
||||
#undef main
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#if SDL_COMPILEDVERSION >= SDL_VERSIONNUM(1, 0, 0) && SDL_COMPILEDVERSION < SDL_VERSIONNUM(2, 0, 0) // SDLMain.m is not needed in SDL 2.x
|
||||
|
||||
#include "SDLMain.h"
|
||||
#include <sys/param.h> /* for MAXPATHLEN */
|
||||
@ -348,9 +359,6 @@ static void CustomApplicationMain (int argc, char **argv)
|
||||
|
||||
|
||||
|
||||
#ifdef main
|
||||
# undef main
|
||||
#endif
|
||||
|
||||
|
||||
/* Main entry point to executable - should *not* be SDL_main! */
|
||||
|
@ -29,12 +29,15 @@
|
||||
#include <SDL_mutex.h>
|
||||
#include <SDL_audio.h>
|
||||
#include <SDL_version.h>
|
||||
#include <SDL_timer.h>
|
||||
|
||||
#if !SDL_VERSION_ATLEAST(3, 0, 0)
|
||||
|
||||
#define DEBUG 0
|
||||
#include "debug.h"
|
||||
|
||||
#if defined(BINCUE)
|
||||
#include "bincue_unix.h"
|
||||
#include "bincue.h"
|
||||
#endif
|
||||
|
||||
|
||||
@ -49,11 +52,14 @@ static int audio_channel_count_index = 0;
|
||||
static SDL_sem *audio_irq_done_sem = NULL; // Signal from interrupt to streaming thread: data block read
|
||||
static uint8 silence_byte; // Byte value to use to fill sound buffers with silence
|
||||
static uint8 *audio_mix_buf = NULL;
|
||||
static int audio_volume = SDL_MIX_MAXVOLUME;
|
||||
static bool audio_mute = false;
|
||||
static int main_volume = MAC_MAX_VOLUME;
|
||||
static int speaker_volume = MAC_MAX_VOLUME;
|
||||
static bool main_mute = false;
|
||||
static bool speaker_mute = false;
|
||||
|
||||
// Prototypes
|
||||
static void stream_func(void *arg, uint8 *stream, int stream_len);
|
||||
static int get_audio_volume();
|
||||
|
||||
|
||||
/*
|
||||
@ -92,7 +98,7 @@ static bool open_sdl_audio(void)
|
||||
audio_spec.freq = audio_sample_rates[audio_sample_rate_index] >> 16;
|
||||
audio_spec.format = (audio_sample_sizes[audio_sample_size_index] == 8) ? AUDIO_U8 : AUDIO_S16MSB;
|
||||
audio_spec.channels = audio_channel_counts[audio_channel_count_index];
|
||||
audio_spec.samples = 4096;
|
||||
audio_spec.samples = 4096 >> PrefsFindInt32("sound_buffer");
|
||||
audio_spec.callback = stream_func;
|
||||
audio_spec.userdata = NULL;
|
||||
|
||||
@ -112,7 +118,7 @@ static bool open_sdl_audio(void)
|
||||
|
||||
#if defined(BINCUE)
|
||||
OpenAudio_bincue(audio_spec.freq, audio_spec.format, audio_spec.channels,
|
||||
audio_spec.silence);
|
||||
audio_spec.silence, get_audio_volume());
|
||||
#endif
|
||||
|
||||
#if SDL_VERSION_ATLEAST(2,0,0)
|
||||
@ -163,7 +169,9 @@ void AudioInit(void)
|
||||
|
||||
// Init semaphore
|
||||
audio_irq_done_sem = SDL_CreateSemaphore(0);
|
||||
|
||||
#ifdef BINCUE
|
||||
InitBinCue();
|
||||
#endif
|
||||
// Open and initialize audio device
|
||||
open_audio();
|
||||
}
|
||||
@ -176,6 +184,9 @@ void AudioInit(void)
|
||||
static void close_audio(void)
|
||||
{
|
||||
// Close audio device
|
||||
#if defined(BINCUE)
|
||||
CloseAudio_bincue();
|
||||
#endif
|
||||
SDL_CloseAudio();
|
||||
free(audio_mix_buf);
|
||||
audio_mix_buf = NULL;
|
||||
@ -186,7 +197,9 @@ void AudioExit(void)
|
||||
{
|
||||
// Close audio device
|
||||
close_audio();
|
||||
|
||||
#ifdef BINCUE
|
||||
ExitBinCue();
|
||||
#endif
|
||||
// Delete semaphore
|
||||
if (audio_irq_done_sem)
|
||||
SDL_DestroySemaphore(audio_irq_done_sem);
|
||||
@ -228,7 +241,7 @@ static void stream_func(void *arg, uint8 *stream, int stream_len)
|
||||
|
||||
// Get size of audio data
|
||||
uint32 apple_stream_info = ReadMacInt32(audio_data + adatStreamInfo);
|
||||
if (apple_stream_info && !audio_mute) {
|
||||
if (apple_stream_info && !main_mute && !speaker_mute) {
|
||||
int work_size = ReadMacInt32(apple_stream_info + scd_sampleCount) * (AudioStatus.sample_size >> 3) * AudioStatus.channels;
|
||||
D(bug("stream: work_size %d\n", work_size));
|
||||
if (work_size > stream_len)
|
||||
@ -237,9 +250,16 @@ static void stream_func(void *arg, uint8 *stream, int stream_len)
|
||||
goto silence;
|
||||
|
||||
// Send data to audio device
|
||||
Mac2Host_memcpy(audio_mix_buf, ReadMacInt32(apple_stream_info + scd_buffer), work_size);
|
||||
bool dbl = AudioStatus.channels == 2 &&
|
||||
ReadMacInt16(apple_stream_info + scd_numChannels) == 1 &&
|
||||
ReadMacInt16(apple_stream_info + scd_sampleSize) == 8;
|
||||
uint8 *src = Mac2HostAddr(ReadMacInt32(apple_stream_info + scd_buffer));
|
||||
if (dbl)
|
||||
for (int i = 0; i < work_size; i += 2)
|
||||
audio_mix_buf[i] = audio_mix_buf[i + 1] = src[i >> 1];
|
||||
else memcpy(audio_mix_buf, src, work_size);
|
||||
memset((uint8 *)stream, silence_byte, stream_len);
|
||||
SDL_MixAudio(stream, audio_mix_buf, work_size, audio_volume);
|
||||
SDL_MixAudio(stream, audio_mix_buf, work_size, get_audio_volume());
|
||||
|
||||
D(bug("stream: data written\n"));
|
||||
|
||||
@ -249,11 +269,13 @@ static void stream_func(void *arg, uint8 *stream, int stream_len)
|
||||
} else {
|
||||
|
||||
// Audio not active, play silence
|
||||
silence: memset(stream, silence_byte, stream_len);
|
||||
silence: memset(stream, silence_byte, stream_len);
|
||||
}
|
||||
|
||||
#if defined(BINCUE)
|
||||
MixAudio_bincue(stream, stream_len);
|
||||
#endif
|
||||
|
||||
}
|
||||
|
||||
|
||||
@ -317,43 +339,84 @@ bool audio_set_channels(int index)
|
||||
|
||||
bool audio_get_main_mute(void)
|
||||
{
|
||||
return audio_mute;
|
||||
return main_mute;
|
||||
}
|
||||
|
||||
uint32 audio_get_main_volume(void)
|
||||
{
|
||||
uint32 chan = (audio_volume * MAC_MAX_VOLUME / SDL_MIX_MAXVOLUME);
|
||||
uint32 chan = main_volume;
|
||||
return (chan << 16) + chan;
|
||||
}
|
||||
|
||||
bool audio_get_speaker_mute(void)
|
||||
{
|
||||
return audio_mute;
|
||||
return speaker_mute;
|
||||
}
|
||||
|
||||
uint32 audio_get_speaker_volume(void)
|
||||
{
|
||||
return audio_get_main_volume();
|
||||
uint32 chan = speaker_volume;
|
||||
return (chan << 16) + chan;
|
||||
}
|
||||
|
||||
void audio_set_main_mute(bool mute)
|
||||
{
|
||||
audio_mute = mute;
|
||||
main_mute = mute;
|
||||
}
|
||||
|
||||
void audio_set_main_volume(uint32 vol)
|
||||
{
|
||||
// We only have one-channel volume right now.
|
||||
uint32 avg = ((vol >> 16) + (vol & 0xffff)) / 2;
|
||||
if (avg > MAC_MAX_VOLUME)
|
||||
avg = MAC_MAX_VOLUME;
|
||||
audio_volume = avg * SDL_MIX_MAXVOLUME / MAC_MAX_VOLUME;
|
||||
main_volume = ((vol >> 16) + (vol & 0xffff)) / 2;
|
||||
if (main_volume > MAC_MAX_VOLUME)
|
||||
main_volume = MAC_MAX_VOLUME;
|
||||
}
|
||||
|
||||
void audio_set_speaker_mute(bool mute)
|
||||
{
|
||||
speaker_mute = mute;
|
||||
}
|
||||
|
||||
void audio_set_speaker_volume(uint32 vol)
|
||||
{
|
||||
// We only have one-channel volume right now.
|
||||
speaker_volume = ((vol >> 16) + (vol & 0xffff)) / 2;
|
||||
if (speaker_volume > MAC_MAX_VOLUME)
|
||||
speaker_volume = MAC_MAX_VOLUME;
|
||||
}
|
||||
|
||||
static int get_audio_volume() {
|
||||
return main_volume * speaker_volume * SDL_MIX_MAXVOLUME / (MAC_MAX_VOLUME * MAC_MAX_VOLUME);
|
||||
}
|
||||
|
||||
#if SDL_VERSION_ATLEAST(2,0,0)
|
||||
static int play_startup(void *arg) {
|
||||
SDL_AudioSpec wav_spec;
|
||||
Uint8 *wav_buffer;
|
||||
Uint32 wav_length;
|
||||
if (SDL_LoadWAV("startup.wav", &wav_spec, &wav_buffer, &wav_length)) {
|
||||
SDL_AudioSpec obtained;
|
||||
SDL_AudioDeviceID deviceId = SDL_OpenAudioDevice(NULL, 0, &wav_spec, &obtained, 0);
|
||||
if (deviceId) {
|
||||
SDL_QueueAudio(deviceId, wav_buffer, wav_length);
|
||||
SDL_PauseAudioDevice(deviceId, 0);
|
||||
while (SDL_GetQueuedAudioSize(deviceId)) SDL_Delay(10);
|
||||
SDL_Delay(500);
|
||||
SDL_CloseAudioDevice(deviceId);
|
||||
}
|
||||
else printf("play_startup: Audio driver failed to initialize\n");
|
||||
SDL_FreeWAV(wav_buffer);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
void PlayStartupSound() {
|
||||
SDL_CreateThread(play_startup, "", NULL);
|
||||
}
|
||||
#else
|
||||
void PlayStartupSound() {
|
||||
// Not implemented
|
||||
}
|
||||
#endif
|
||||
#endif // SDL_VERSION_ATLEAST
|
||||
|
||||
|
555
BasiliskII/src/SDL/audio_sdl3.cpp
Normal file
555
BasiliskII/src/SDL/audio_sdl3.cpp
Normal file
@ -0,0 +1,555 @@
|
||||
/*
|
||||
* audio_sdl3.cpp - Audio support, SDL implementation
|
||||
*
|
||||
* Basilisk II (C) 1997-2008 Christian Bauer
|
||||
*
|
||||
* This program 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 Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program 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 this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*/
|
||||
|
||||
#include "sysdeps.h"
|
||||
|
||||
#include <SDL.h>
|
||||
#if SDL_VERSION_ATLEAST(3, 0, 0)
|
||||
|
||||
#include "cpu_emulation.h"
|
||||
#include "main.h"
|
||||
#include "prefs.h"
|
||||
#include "user_strings.h"
|
||||
#include "audio.h"
|
||||
#include "audio_defs.h"
|
||||
|
||||
#include <queue>
|
||||
|
||||
#define DEBUG 0
|
||||
#include "debug.h"
|
||||
|
||||
#define MONITOR_MAIN_STREAM 0
|
||||
#define MONITOR_INTERRUPT_STREAM 0
|
||||
#define DISPLAY_EVERY 4
|
||||
|
||||
#if defined(BINCUE)
|
||||
#include "bincue.h"
|
||||
#endif
|
||||
|
||||
|
||||
#define MAC_MAX_VOLUME 0x0100
|
||||
|
||||
#define MAIN_STREAM_EXTRA_DATA_MARGIN_MS 3
|
||||
#define INTERRUPT_STREAM_QUEUE_TARGET_MS 5
|
||||
#define INTERRUPT_RETRY_MS 5
|
||||
|
||||
// The currently selected audio parameters (indices in audio_sample_rates[] etc. vectors)
|
||||
static int audio_sample_rate_index = 0;
|
||||
static int audio_sample_size_index = 0;
|
||||
static int audio_channel_count_index = 0;
|
||||
|
||||
// Global variables
|
||||
static SDL_Semaphore *audio_irq_done_sem = NULL; // Signal from interrupt to streaming thread: data block read
|
||||
static uint8 silence_byte; // Byte value to use to fill sound buffers with silence
|
||||
static int main_volume = MAC_MAX_VOLUME;
|
||||
static int speaker_volume = MAC_MAX_VOLUME;
|
||||
static bool main_mute = false;
|
||||
static bool speaker_mute = false;
|
||||
|
||||
static SDL_Thread *startup_thread;
|
||||
volatile static bool playing_startup, exit_startup;
|
||||
SDL_AudioSpec audio_spec;
|
||||
|
||||
// Prototypes
|
||||
static void SDLCALL stream_func(void *arg, SDL_AudioStream *stream, int additional_amount, int total_amount);
|
||||
static float get_audio_volume();
|
||||
static void start_threads();
|
||||
static void stop_threads();
|
||||
|
||||
static SDL_Thread * interrupt_thread = NULL;
|
||||
static int interrupt_thread_func(void *data);
|
||||
static bool interrupt_thread_quit;
|
||||
static SDL_AudioStream * interrupt_stream = NULL;
|
||||
|
||||
/*
|
||||
* Initialization
|
||||
*/
|
||||
|
||||
// Set AudioStatus to reflect current audio stream format
|
||||
static void set_audio_status_format(void)
|
||||
{
|
||||
AudioStatus.sample_rate = audio_sample_rates[audio_sample_rate_index];
|
||||
AudioStatus.sample_size = audio_sample_sizes[audio_sample_size_index];
|
||||
AudioStatus.channels = audio_channel_counts[audio_channel_count_index];
|
||||
}
|
||||
|
||||
static SDL_AudioStream * main_open_sdl_stream = NULL;
|
||||
|
||||
// Init SDL audio system
|
||||
static bool open_sdl_audio(void)
|
||||
{
|
||||
// SDL supports a variety of twisted little audio formats, all different
|
||||
if (audio_sample_sizes.empty()) {
|
||||
audio_sample_rates.push_back(11025 << 16);
|
||||
audio_sample_rates.push_back(22050 << 16);
|
||||
audio_sample_rates.push_back(44100 << 16);
|
||||
audio_sample_sizes.push_back(8);
|
||||
audio_sample_sizes.push_back(16);
|
||||
audio_channel_counts.push_back(1);
|
||||
audio_channel_counts.push_back(2);
|
||||
|
||||
// Default to highest supported values
|
||||
audio_sample_rate_index = (int)audio_sample_rates.size() - 1;
|
||||
audio_sample_size_index = (int)audio_sample_sizes.size() - 1;
|
||||
audio_channel_count_index = (int)audio_channel_counts.size() - 1;
|
||||
}
|
||||
|
||||
//memset(&audio_spec, 0, sizeof(audio_spec));
|
||||
audio_spec.format = (audio_sample_sizes[audio_sample_size_index] == 8) ? SDL_AUDIO_U8 : SDL_AUDIO_S16BE;
|
||||
audio_spec.channels = audio_channel_counts[audio_channel_count_index];
|
||||
audio_spec.freq = audio_sample_rates[audio_sample_rate_index] >> 16;
|
||||
|
||||
D(bug("Opening SDL audio device stream, freq %d chan %d format %s\n", audio_spec.freq, audio_spec.channels,
|
||||
SDL_GetAudioFormatName(audio_spec.format)));
|
||||
|
||||
assert(!main_open_sdl_stream);
|
||||
|
||||
// Open the audio device, forcing the desired format
|
||||
SDL_AudioStream *stream = SDL_OpenAudioDeviceStream(SDL_AUDIO_DEVICE_DEFAULT_PLAYBACK, &audio_spec, stream_func, NULL);
|
||||
if (stream == NULL) {
|
||||
fprintf(stderr, "WARNING: Cannot open audio: %s\n", SDL_GetError());
|
||||
return false;
|
||||
}
|
||||
main_open_sdl_stream = stream;
|
||||
silence_byte = SDL_GetSilenceValueForFormat(audio_spec.format);
|
||||
#if defined(BINCUE)
|
||||
OpenAudio_bincue(audio_spec.freq, audio_spec.format, audio_spec.channels, silence_byte, (int)(get_audio_volume()*128));
|
||||
#endif
|
||||
|
||||
printf("Using SDL/%s audio output\n", SDL_GetCurrentAudioDriver());
|
||||
audio_frames_per_block = 4096 >> PrefsFindInt32("sound_buffer");
|
||||
start_threads();
|
||||
SDL_ResumeAudioDevice(SDL_GetAudioStreamDevice(stream));
|
||||
return true;
|
||||
}
|
||||
|
||||
static void start_threads() {
|
||||
interrupt_stream = SDL_CreateAudioStream(&audio_spec, &audio_spec);
|
||||
assert(interrupt_thread == NULL);
|
||||
interrupt_thread_quit = false;
|
||||
interrupt_thread = SDL_CreateThread(interrupt_thread_func, "audio_sdl3_interrupt_thread", NULL);
|
||||
}
|
||||
|
||||
static void stop_threads() {
|
||||
exit_startup = true;
|
||||
if (startup_thread != NULL)
|
||||
SDL_WaitThread(startup_thread, NULL);
|
||||
startup_thread = NULL;
|
||||
//
|
||||
interrupt_thread_quit = true;
|
||||
if (interrupt_thread != NULL)
|
||||
SDL_WaitThread(interrupt_thread, NULL);
|
||||
interrupt_thread = NULL;
|
||||
SDL_DestroyAudioStream(interrupt_stream);
|
||||
}
|
||||
|
||||
static bool close_sdl_audio() {
|
||||
stop_threads();
|
||||
if (main_open_sdl_stream) {
|
||||
SDL_DestroyAudioStream(main_open_sdl_stream);
|
||||
main_open_sdl_stream = NULL;
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
static bool open_audio(void)
|
||||
{
|
||||
// Try to open SDL audio
|
||||
if (!open_sdl_audio()) {
|
||||
WarningAlert(GetString(STR_NO_AUDIO_WARN));
|
||||
return false;
|
||||
}
|
||||
|
||||
// Device opened, set AudioStatus
|
||||
set_audio_status_format();
|
||||
|
||||
// Everything went fine
|
||||
audio_open = true;
|
||||
return true;
|
||||
}
|
||||
|
||||
void AudioInit(void)
|
||||
{
|
||||
// Init audio status and feature flags
|
||||
AudioStatus.sample_rate = 44100 << 16;
|
||||
AudioStatus.sample_size = 16;
|
||||
AudioStatus.channels = 2;
|
||||
AudioStatus.mixer = 0;
|
||||
AudioStatus.num_sources = 0;
|
||||
audio_component_flags = cmpWantsRegisterMessage | kStereoOut | k16BitOut;
|
||||
|
||||
// Sound disabled in prefs? Then do nothing
|
||||
if (PrefsFindBool("nosound"))
|
||||
return;
|
||||
|
||||
// Init semaphore
|
||||
audio_irq_done_sem = SDL_CreateSemaphore(0);
|
||||
#ifdef BINCUE
|
||||
InitBinCue();
|
||||
#endif
|
||||
// Open and initialize audio device
|
||||
open_audio();
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Deinitialization
|
||||
*/
|
||||
|
||||
static void close_audio(void)
|
||||
{
|
||||
exit_startup = true;
|
||||
while (playing_startup)
|
||||
SDL_Delay(10);
|
||||
exit_startup = false;
|
||||
// Close audio device
|
||||
close_sdl_audio();
|
||||
audio_open = false;
|
||||
}
|
||||
|
||||
void AudioExit(void)
|
||||
{
|
||||
// Close audio device
|
||||
close_audio();
|
||||
#ifdef BINCUE
|
||||
ExitBinCue();
|
||||
#endif
|
||||
// Delete semaphore
|
||||
if (audio_irq_done_sem)
|
||||
SDL_DestroySemaphore(audio_irq_done_sem);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* First source added, start audio stream
|
||||
*/
|
||||
|
||||
void audio_enter_stream()
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Last source removed, stop audio stream
|
||||
*/
|
||||
|
||||
void audio_exit_stream()
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Streaming function
|
||||
*/
|
||||
|
||||
static int time_to_stream_bytes(int time_ms) {
|
||||
// fraction in seconds
|
||||
int time_numerator = time_ms;
|
||||
int time_denominator = 100;
|
||||
|
||||
// sample size across all channels
|
||||
int sample_size = AudioStatus.channels * (AudioStatus.sample_size >> 3); // bytes
|
||||
// Take care with data types
|
||||
// - AudioStatus.sample_rate Hz is in 16.16 fixed point and will overflow if we multiply its uint32 by even 2
|
||||
int time_samples = ((int)(((uint64)AudioStatus.sample_rate * time_numerator) >> 16) / time_denominator);
|
||||
// - We want a number of bytes that is an integer multiple of a sample for each channel
|
||||
return time_samples * sample_size;
|
||||
}
|
||||
|
||||
static int interrupt_thread_func(void *data)
|
||||
{
|
||||
while (!interrupt_thread_quit) {
|
||||
|
||||
int target_queue_size = time_to_stream_bytes(INTERRUPT_STREAM_QUEUE_TARGET_MS);
|
||||
|
||||
#if MONITOR_INTERRUPT_STREAM
|
||||
static int monitor_stream_count = 0;
|
||||
if (monitor_stream_count++ % DISPLAY_EVERY == 0)
|
||||
bug("audio mac interrupt thread: target_queue_size %5d q %6d\n",
|
||||
target_queue_size, SDL_GetAudioStreamQueued(interrupt_stream));
|
||||
#endif
|
||||
|
||||
if (AudioStatus.num_sources) {
|
||||
while (SDL_GetAudioStreamQueued(interrupt_stream) < target_queue_size) {
|
||||
// Trigger audio interrupt to get new buffer
|
||||
D(bug("stream: triggering irq\n"));
|
||||
SetInterruptFlag(INTFLAG_AUDIO);
|
||||
TriggerInterrupt();
|
||||
D(bug("stream: waiting for ack\n"));
|
||||
SDL_WaitSemaphore(audio_irq_done_sem);
|
||||
D(bug("stream: ack received\n"));
|
||||
|
||||
// Get size of audio data
|
||||
uint32 apple_stream_info = ReadMacInt32(audio_data + adatStreamInfo);
|
||||
if (apple_stream_info) {
|
||||
|
||||
bool known_audio_format;
|
||||
int source_sample_size;
|
||||
SDL_AudioFormat source_format;
|
||||
uint32 fourcc = ReadMacInt32(apple_stream_info + scd_format);
|
||||
switch (fourcc) {
|
||||
case FOURCC('t','w','o','s'):
|
||||
known_audio_format = true;
|
||||
source_sample_size = 16;
|
||||
source_format = SDL_AUDIO_S16BE;
|
||||
break;
|
||||
case FOURCC('r','a','w',' '):
|
||||
known_audio_format = true;
|
||||
source_sample_size = 8;
|
||||
source_format = SDL_AUDIO_U8;
|
||||
break;
|
||||
default:
|
||||
// bug("SoundComponentData in unsupported format fourcc '%c%c%c%c'\n",
|
||||
// (fourcc >> 24)&0xff, (fourcc >> 16)&0xff, (fourcc >> 8)&0xff, fourcc&0xff);
|
||||
known_audio_format = false;
|
||||
// We can't do anything with the source data but we know the duration,
|
||||
// so we generate an appropriate silence
|
||||
// Set a placeholder source format to use for it:
|
||||
source_sample_size = 8;
|
||||
source_format = SDL_AUDIO_U8;
|
||||
}
|
||||
|
||||
uint16 source_channels = ReadMacInt16(apple_stream_info + scd_numChannels);
|
||||
|
||||
int work_size = ReadMacInt32(apple_stream_info + scd_sampleCount) * (source_sample_size >> 3) * source_channels;
|
||||
if (work_size == 0)
|
||||
break; // no more audio available right now
|
||||
|
||||
uint8 buf[work_size];
|
||||
|
||||
uint32 source_sample_rate = ReadMacInt32(apple_stream_info + scd_sampleRate);
|
||||
|
||||
SDL_AudioSpec current_scd_spec = {source_format, source_channels, (uint16)(source_sample_rate >> 16)};
|
||||
//bug("scd channels %d sr %d 0x%x >>16%d\n", source_channels, source_sample_rate, source_sample_rate, source_sample_rate>>16);
|
||||
|
||||
SDL_SetAudioStreamFormat(interrupt_stream, ¤t_scd_spec, NULL);
|
||||
|
||||
if (known_audio_format && !main_mute && !speaker_mute) {
|
||||
Mac2Host_memcpy(buf, ReadMacInt32(apple_stream_info + scd_buffer), work_size);
|
||||
} else {
|
||||
memset(buf, SDL_GetSilenceValueForFormat(source_format), work_size);
|
||||
}
|
||||
|
||||
SDL_PutAudioStreamData(interrupt_stream, buf, work_size);
|
||||
}
|
||||
else {
|
||||
SDL_ClearAudioStream(interrupt_stream);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Audio isn't active or the mac doesn't have any right now.
|
||||
// Wait a little while.
|
||||
SDL_Delay(INTERRUPT_RETRY_MS);
|
||||
|
||||
} // while
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void SDLCALL stream_func(void *, SDL_AudioStream *stream, int stream_len, int total_amount)
|
||||
{
|
||||
int target_queue_size;
|
||||
int margin;
|
||||
if (stream_len == 0) {
|
||||
// This indicates that SDL3 really has all the data it wants right now.
|
||||
// This is our backpressure state, where we avoid pushing even more
|
||||
// which prevents non-real-time audio situations (like playing media with audio)
|
||||
// from getting unnecessarily ahead
|
||||
return;
|
||||
} else {
|
||||
// We want to supply a little more data than was requested to prevent underruns
|
||||
// Figure out a fraction of a second of data to use
|
||||
margin = time_to_stream_bytes(MAIN_STREAM_EXTRA_DATA_MARGIN_MS);
|
||||
target_queue_size = stream_len + margin;
|
||||
}
|
||||
|
||||
int bytes_available = SDL_GetAudioStreamAvailable(interrupt_stream);
|
||||
if (bytes_available > stream_len) {
|
||||
// push any extra bytes, up to the target number, right away
|
||||
stream_len = std::min(bytes_available, target_queue_size);
|
||||
} else if (bytes_available == 0) {
|
||||
#if defined(BINCUE)
|
||||
if (HaveAudioToMix_bincue()) {
|
||||
// we are driving the rate entirely on behalf of the CD audio
|
||||
stream_len = target_queue_size;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
#if MONITOR_MAIN_STREAM
|
||||
static int monitor_stream_count = 0;
|
||||
if (monitor_stream_count++ % DISPLAY_EVERY == 0)
|
||||
bug("audio main sdl3 stream callback: stream_len %5d already sent %5d margin %5d target_q %5d q %6ld\n",
|
||||
stream_len, total_amount, margin, target_queue_size, bytes_available);
|
||||
#endif
|
||||
|
||||
uint8 src[stream_len], dst[stream_len];
|
||||
int i = SDL_GetAudioStreamData(interrupt_stream, src, stream_len);
|
||||
if (i < stream_len)
|
||||
memset(src + i, silence_byte, stream_len - i);
|
||||
memset(dst, silence_byte, stream_len);
|
||||
//SDL_AudioSpec audio_spec;
|
||||
//int r = SDL_GetAudioStreamFormat(stream, NULL, &audio_spec);// little endianが帰ってくる
|
||||
SDL_MixAudio(dst, src, audio_spec.format, stream_len, get_audio_volume());
|
||||
#if defined(BINCUE)
|
||||
MixAudio_bincue(dst, stream_len);
|
||||
#endif
|
||||
SDL_PutAudioStreamData(stream, dst, stream_len);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* MacOS audio interrupt, read next data block
|
||||
*/
|
||||
|
||||
void AudioInterrupt(void)
|
||||
{
|
||||
D(bug("AudioInterrupt\n"));
|
||||
|
||||
// Get data from apple mixer
|
||||
if (AudioStatus.mixer) {
|
||||
M68kRegisters r;
|
||||
r.a[0] = audio_data + adatStreamInfo;
|
||||
r.a[1] = AudioStatus.mixer;
|
||||
Execute68k(audio_data + adatGetSourceData, &r);
|
||||
D(bug(" GetSourceData() returns %08lx\n", r.d[0]));
|
||||
} else
|
||||
WriteMacInt32(audio_data + adatStreamInfo, 0);
|
||||
|
||||
// Signal stream function
|
||||
SDL_SignalSemaphore(audio_irq_done_sem);
|
||||
D(bug("AudioInterrupt done\n"));
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Set sampling parameters
|
||||
* "index" is an index into the audio_sample_rates[] etc. vectors
|
||||
* It is guaranteed that AudioStatus.num_sources == 0
|
||||
*/
|
||||
|
||||
bool audio_set_sample_rate(int index)
|
||||
{
|
||||
close_audio();
|
||||
audio_sample_rate_index = index;
|
||||
return open_audio();
|
||||
}
|
||||
|
||||
bool audio_set_sample_size(int index)
|
||||
{
|
||||
close_audio();
|
||||
audio_sample_size_index = index;
|
||||
return open_audio();
|
||||
}
|
||||
|
||||
bool audio_set_channels(int index)
|
||||
{
|
||||
close_audio();
|
||||
audio_channel_count_index = index;
|
||||
return open_audio();
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Get/set volume controls (volume values received/returned have the left channel
|
||||
* volume in the upper 16 bits and the right channel volume in the lower 16 bits;
|
||||
* both volumes are 8.8 fixed point values with 0x0100 meaning "maximum volume"))
|
||||
*/
|
||||
|
||||
bool audio_get_main_mute(void)
|
||||
{
|
||||
return main_mute;
|
||||
}
|
||||
|
||||
uint32 audio_get_main_volume(void)
|
||||
{
|
||||
uint32 chan = main_volume;
|
||||
return (chan << 16) + chan;
|
||||
}
|
||||
|
||||
bool audio_get_speaker_mute(void)
|
||||
{
|
||||
return speaker_mute;
|
||||
}
|
||||
|
||||
uint32 audio_get_speaker_volume(void)
|
||||
{
|
||||
uint32 chan = speaker_volume;
|
||||
return (chan << 16) + chan;
|
||||
}
|
||||
|
||||
void audio_set_main_mute(bool mute)
|
||||
{
|
||||
main_mute = mute;
|
||||
}
|
||||
|
||||
void audio_set_main_volume(uint32 vol)
|
||||
{
|
||||
// We only have one-channel volume right now.
|
||||
main_volume = ((vol >> 16) + (vol & 0xffff)) / 2;
|
||||
if (main_volume > MAC_MAX_VOLUME)
|
||||
main_volume = MAC_MAX_VOLUME;
|
||||
}
|
||||
|
||||
void audio_set_speaker_mute(bool mute)
|
||||
{
|
||||
speaker_mute = mute;
|
||||
}
|
||||
|
||||
void audio_set_speaker_volume(uint32 vol)
|
||||
{
|
||||
// We only have one-channel volume right now.
|
||||
speaker_volume = ((vol >> 16) + (vol & 0xffff)) / 2;
|
||||
if (speaker_volume > MAC_MAX_VOLUME)
|
||||
speaker_volume = MAC_MAX_VOLUME;
|
||||
}
|
||||
|
||||
static float get_audio_volume() {
|
||||
return (float) main_volume * speaker_volume / (MAC_MAX_VOLUME * MAC_MAX_VOLUME);
|
||||
}
|
||||
|
||||
static int play_startup(void *arg) {
|
||||
SDL_AudioSpec wav_spec;
|
||||
Uint8 *wav_buffer;
|
||||
Uint32 wav_length;
|
||||
if (!playing_startup && SDL_LoadWAV("startup.wav", &wav_spec, &wav_buffer, &wav_length)) {
|
||||
SDL_AudioStream *stream = SDL_OpenAudioDeviceStream(SDL_AUDIO_DEVICE_DEFAULT_PLAYBACK, &wav_spec, NULL, NULL);
|
||||
if (stream) {
|
||||
SDL_ResumeAudioDevice(SDL_GetAudioStreamDevice(stream));
|
||||
SDL_PutAudioStreamData(stream, wav_buffer, wav_length);
|
||||
playing_startup = true;
|
||||
while (!exit_startup && SDL_GetAudioStreamAvailable(stream)) SDL_Delay(10);
|
||||
if (!exit_startup) SDL_Delay(500);
|
||||
SDL_DestroyAudioStream(stream);
|
||||
}
|
||||
else printf("play_startup: Audio driver failed to initialize\n");
|
||||
SDL_free(wav_buffer);
|
||||
playing_startup = false;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
void PlayStartupSound() {
|
||||
startup_thread = SDL_CreateThread(play_startup, "play_startup", NULL);
|
||||
}
|
||||
|
||||
#endif // SDL_VERSION_ATLEAST
|
@ -67,7 +67,9 @@ void LoadPrefs(const char * vmdir) // TODO: load prefs from 'vmdir'
|
||||
fclose(f);
|
||||
|
||||
} else {
|
||||
|
||||
#ifdef __linux__
|
||||
PrefsAddString("cdrom", "/dev/cdrom");
|
||||
#endif
|
||||
// No prefs file, save defaults
|
||||
SavePrefs();
|
||||
}
|
||||
|
@ -43,12 +43,13 @@
|
||||
#include "sysdeps.h"
|
||||
|
||||
#include <SDL.h>
|
||||
#if (SDL_COMPILEDVERSION < SDL_VERSIONNUM(2, 0, 0))
|
||||
#if SDL_COMPILEDVERSION >= SDL_VERSIONNUM(1, 0, 0) && SDL_COMPILEDVERSION < SDL_VERSIONNUM(2, 0, 0)
|
||||
|
||||
#include <SDL_mutex.h>
|
||||
#include <SDL_thread.h>
|
||||
#include <errno.h>
|
||||
#include <vector>
|
||||
#include <string>
|
||||
|
||||
#ifdef WIN32
|
||||
#include <malloc.h> /* alloca() */
|
||||
@ -118,7 +119,9 @@ static bool use_vosf = false; // Flag: VOSF enabled
|
||||
static const bool use_vosf = false; // VOSF not possible
|
||||
#endif
|
||||
|
||||
static bool ctrl_down = false; // Flag: Ctrl key pressed
|
||||
static bool ctrl_down = false; // Flag: Ctrl key pressed (for use with hotkeys)
|
||||
static bool opt_down = false; // Flag: Opt/Alt key pressed (for use with hotkeys)
|
||||
static bool cmd_down = false; // Flag: Cmd/Super/Win key pressed (for use with hotkeys)
|
||||
static bool caps_on = false; // Flag: Caps Lock on
|
||||
static bool quit_full_screen = false; // Flag: DGA close requested from redraw thread
|
||||
static bool emerg_quit = false; // Flag: Ctrl-Esc pressed, emergency quit requested from MacOS thread
|
||||
@ -155,6 +158,11 @@ static SDL_mutex *frame_buffer_lock = NULL;
|
||||
#define LOCK_FRAME_BUFFER SDL_LockMutex(frame_buffer_lock)
|
||||
#define UNLOCK_FRAME_BUFFER SDL_UnlockMutex(frame_buffer_lock)
|
||||
|
||||
// Previously set gamma tables
|
||||
static uint16 last_gamma_red[256];
|
||||
static uint16 last_gamma_green[256];
|
||||
static uint16 last_gamma_blue[256];
|
||||
|
||||
// Video refresh function
|
||||
static void VideoRefreshInit(void);
|
||||
static void (*video_refresh)(void);
|
||||
@ -360,6 +368,7 @@ public:
|
||||
|
||||
virtual void switch_to_current_mode(void);
|
||||
virtual void set_palette(uint8 *pal, int num);
|
||||
virtual void set_gamma(uint8 *gamma, int num);
|
||||
|
||||
bool video_open(void);
|
||||
void video_close(void);
|
||||
@ -515,12 +524,26 @@ static void set_mac_frame_buffer(SDL_monitor_desc &monitor, int depth)
|
||||
}
|
||||
|
||||
// Set window name and class
|
||||
static void set_window_name(int name)
|
||||
static void set_window_name(bool mouse_grabbed)
|
||||
{
|
||||
const char *title = PrefsFindString("title");
|
||||
std::string s = title ? title : GetString(STR_WINDOW_TITLE);
|
||||
int grabbed = 0;
|
||||
if (mouse_grabbed)
|
||||
{
|
||||
s += GetString(STR_WINDOW_TITLE_GRABBED_PRE);
|
||||
int hotkey = PrefsFindInt32("hotkey");
|
||||
hotkey = hotkey ? hotkey : 1;
|
||||
if (hotkey & 1) s += GetString(STR_WINDOW_TITLE_GRABBED1);
|
||||
if (hotkey & 2) s += GetString(STR_WINDOW_TITLE_GRABBED2);
|
||||
if (hotkey & 4) s += GetString(STR_WINDOW_TITLE_GRABBED4);
|
||||
s += GetString(STR_WINDOW_TITLE_GRABBED_POST);
|
||||
}
|
||||
const SDL_VideoInfo *vi = SDL_GetVideoInfo();
|
||||
if (vi && vi->wm_available) {
|
||||
const char *str = GetString(name);
|
||||
SDL_WM_SetCaption(str, str);
|
||||
if (vi && vi->wm_available)
|
||||
{
|
||||
//The icon name should stay the same
|
||||
SDL_WM_SetCaption(s.c_str(), GetString(STR_WINDOW_TITLE));
|
||||
}
|
||||
}
|
||||
|
||||
@ -700,6 +723,7 @@ void driver_base::adapt_to_video_mode() {
|
||||
ADBSetRelMouseMode(false);
|
||||
|
||||
// Init blitting routines
|
||||
if (!s) return;
|
||||
SDL_PixelFormat *f = s->format;
|
||||
VisualFormat visualFormat;
|
||||
visualFormat.depth = sdl_depth_of_video_depth(VIDEO_MODE_DEPTH);
|
||||
@ -731,7 +755,7 @@ void driver_base::adapt_to_video_mode() {
|
||||
SDL_ShowCursor(hardware_cursor);
|
||||
|
||||
// Set window name/class
|
||||
set_window_name(STR_WINDOW_TITLE);
|
||||
set_window_name(false);
|
||||
|
||||
// Everything went well
|
||||
init_ok = true;
|
||||
@ -1299,8 +1323,8 @@ void VideoVBL(void)
|
||||
// Setting the window name must happen on the main thread, else it doesn't work on
|
||||
// some platforms - e.g. macOS Sierra.
|
||||
if (mouse_grabbed_window_name_status != mouse_grabbed) {
|
||||
set_window_name(mouse_grabbed ? STR_WINDOW_TITLE_GRABBED : STR_WINDOW_TITLE);
|
||||
mouse_grabbed_window_name_status = mouse_grabbed;
|
||||
set_window_name(mouse_grabbed);
|
||||
mouse_grabbed_window_name_status = mouse_grabbed;
|
||||
}
|
||||
|
||||
// Temporarily give up frame buffer lock (this is the point where
|
||||
@ -1328,7 +1352,7 @@ void VideoInterrupt(void)
|
||||
// Setting the window name must happen on the main thread, else it doesn't work on
|
||||
// some platforms - e.g. macOS Sierra.
|
||||
if (mouse_grabbed_window_name_status != mouse_grabbed) {
|
||||
set_window_name(mouse_grabbed ? STR_WINDOW_TITLE_GRABBED : STR_WINDOW_TITLE);
|
||||
set_window_name(mouse_grabbed);
|
||||
mouse_grabbed_window_name_status = mouse_grabbed;
|
||||
}
|
||||
|
||||
@ -1363,9 +1387,51 @@ void SDL_monitor_desc::set_palette(uint8 *pal, int num_in)
|
||||
{
|
||||
const VIDEO_MODE &mode = get_current_mode();
|
||||
|
||||
// FIXME: how can we handle the gamma ramp?
|
||||
if ((int)VIDEO_MODE_DEPTH > VIDEO_DEPTH_8BIT)
|
||||
if ((int)VIDEO_MODE_DEPTH > VIDEO_DEPTH_8BIT) {
|
||||
// handle the gamma ramp
|
||||
|
||||
if (pal[0] == 127 && pal[num_in*3-1] == 127) // solid grey
|
||||
return; // ignore
|
||||
|
||||
uint16 red[256];
|
||||
uint16 green[256];
|
||||
uint16 blue[256];
|
||||
|
||||
int repeats = 256 / num_in;
|
||||
|
||||
for (int i = 0; i < num_in; i++) {
|
||||
for (int j = 0; j < repeats; j++) {
|
||||
red[i*repeats + j] = pal[i*3 + 0] << 8;
|
||||
green[i*repeats + j] = pal[i*3 + 1] << 8;
|
||||
blue[i*repeats + j] = pal[i*3 + 2] << 8;
|
||||
}
|
||||
}
|
||||
|
||||
// fill remaining entries (if any) with last value
|
||||
for (int i = num_in * repeats; i < 256; i++) {
|
||||
red[i] = pal[(num_in - 1) * 3] << 8;
|
||||
green[i] = pal[(num_in - 1) * 3 + 1] << 8;
|
||||
blue[i] = pal[(num_in - 1) * 3 + 2] << 8;
|
||||
}
|
||||
|
||||
bool changed = (memcmp(red, last_gamma_red, 512) != 0 ||
|
||||
memcmp(green, last_gamma_green, 512) != 0 ||
|
||||
memcmp(blue, last_gamma_blue, 512) != 0);
|
||||
|
||||
if (changed) {
|
||||
int result = SDL_SetGammaRamp(red, green, blue);
|
||||
|
||||
if (result < 0) {
|
||||
fprintf(stderr, "SDL_SetGammaRamp returned %d, SDL error: %s\n", result, SDL_GetError());
|
||||
}
|
||||
|
||||
memcpy(last_gamma_red, red, 512);
|
||||
memcpy(last_gamma_green, green, 512);
|
||||
memcpy(last_gamma_blue, blue, 512);
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
LOCK_PALETTE;
|
||||
|
||||
@ -1405,6 +1471,10 @@ void SDL_monitor_desc::set_palette(uint8 *pal, int num_in)
|
||||
UNLOCK_PALETTE;
|
||||
}
|
||||
|
||||
void SDL_monitor_desc::set_gamma(uint8 *gamma, int num_in)
|
||||
{
|
||||
// Not implemented
|
||||
}
|
||||
|
||||
/*
|
||||
* Switch video mode
|
||||
@ -1564,11 +1634,29 @@ static bool is_modifier_key(SDL_KeyboardEvent const & e)
|
||||
return false;
|
||||
}
|
||||
|
||||
static bool is_ctrl_down(SDL_keysym const & ks)
|
||||
static bool is_hotkey_down(SDL_keysym const & ks)
|
||||
{
|
||||
return ctrl_down || (ks.mod & KMOD_CTRL);
|
||||
int hotkey = PrefsFindInt32("hotkey");
|
||||
if (!hotkey) hotkey = 1;
|
||||
return (ctrl_down || (ks.mod & KMOD_CTRL) || !(hotkey & 1)) &&
|
||||
(opt_down || (ks.mod & KMOD_ALT) || !(hotkey & 2)) &&
|
||||
(cmd_down || (ks.mod & KMOD_META) || !(hotkey & 4));
|
||||
}
|
||||
|
||||
static int modify_opt_cmd(int code) {
|
||||
static bool f, c;
|
||||
if (!f) {
|
||||
f = true;
|
||||
c = PrefsFindBool("swap_opt_cmd");
|
||||
}
|
||||
if (c) {
|
||||
switch (code) {
|
||||
case 0x37: return 0x3a;
|
||||
case 0x3a: return 0x37;
|
||||
}
|
||||
}
|
||||
return code;
|
||||
}
|
||||
|
||||
/*
|
||||
* Translate key event to Mac keycode, returns -1 if no keycode was found
|
||||
@ -1628,8 +1716,8 @@ static int kc_decode(SDL_keysym const & ks, bool key_down)
|
||||
case SDLK_PERIOD: case SDLK_GREATER: return 0x2f;
|
||||
case SDLK_SLASH: case SDLK_QUESTION: return 0x2c;
|
||||
|
||||
case SDLK_TAB: if (is_ctrl_down(ks)) {if (!key_down) drv->suspend(); return -2;} else return 0x30;
|
||||
case SDLK_RETURN: if (is_ctrl_down(ks)) {if (!key_down) toggle_fullscreen = true; return -2;} else return 0x24;
|
||||
case SDLK_TAB: if (is_hotkey_down(ks)) {if (!key_down) drv->suspend(); return -2;} else return 0x30;
|
||||
case SDLK_RETURN: if (is_hotkey_down(ks)) {if (!key_down) toggle_fullscreen = true; return -2;} else return 0x24;
|
||||
case SDLK_SPACE: return 0x31;
|
||||
case SDLK_BACKSPACE: return 0x33;
|
||||
|
||||
@ -1644,19 +1732,9 @@ static int kc_decode(SDL_keysym const & ks, bool key_down)
|
||||
case SDLK_RCTRL: return 0x36;
|
||||
case SDLK_LSHIFT: return 0x38;
|
||||
case SDLK_RSHIFT: return 0x38;
|
||||
#if (defined(__APPLE__) && defined(__MACH__))
|
||||
case SDLK_LALT: return 0x3a;
|
||||
case SDLK_RALT: return 0x3a;
|
||||
case SDLK_LMETA: return 0x37;
|
||||
case SDLK_RMETA: return 0x37;
|
||||
#else
|
||||
case SDLK_LALT: return 0x37;
|
||||
case SDLK_RALT: return 0x37;
|
||||
case SDLK_LMETA: return 0x3a;
|
||||
case SDLK_RMETA: return 0x3a;
|
||||
#endif
|
||||
case SDLK_LSUPER: return 0x3a; // "Windows" key
|
||||
case SDLK_RSUPER: return 0x3a;
|
||||
case SDLK_LALT: case SDLK_RALT: return 0x3a;
|
||||
case SDLK_LMETA: case SDLK_RMETA: return 0x37;
|
||||
case SDLK_LSUPER: case SDLK_RSUPER: return 0x37; // "Windows" key
|
||||
case SDLK_MENU: return 0x32;
|
||||
case SDLK_CAPSLOCK: return 0x39;
|
||||
case SDLK_NUMLOCK: return 0x47;
|
||||
@ -1666,13 +1744,13 @@ static int kc_decode(SDL_keysym const & ks, bool key_down)
|
||||
case SDLK_LEFT: return 0x3b;
|
||||
case SDLK_RIGHT: return 0x3c;
|
||||
|
||||
case SDLK_ESCAPE: if (is_ctrl_down(ks)) {if (!key_down) { quit_full_screen = true; emerg_quit = true; } return -2;} else return 0x35;
|
||||
case SDLK_ESCAPE: if (is_hotkey_down(ks)) {if (!key_down) { quit_full_screen = true; emerg_quit = true; } return -2;} else return 0x35;
|
||||
|
||||
case SDLK_F1: if (is_ctrl_down(ks)) {if (!key_down) SysMountFirstFloppy(); return -2;} else return 0x7a;
|
||||
case SDLK_F1: if (is_hotkey_down(ks)) {if (!key_down) SysMountFirstFloppy(); return -2;} else return 0x7a;
|
||||
case SDLK_F2: return 0x78;
|
||||
case SDLK_F3: return 0x63;
|
||||
case SDLK_F4: return 0x76;
|
||||
case SDLK_F5: if (is_ctrl_down(ks)) {if (!key_down) drv->toggle_mouse_grab(); return -2;} else return 0x60;
|
||||
case SDLK_F5: if (is_hotkey_down(ks)) {if (!key_down) drv->toggle_mouse_grab(); return -2;} else return 0x60;
|
||||
case SDLK_F6: return 0x61;
|
||||
case SDLK_F7: return 0x62;
|
||||
case SDLK_F8: return 0x64;
|
||||
@ -1795,6 +1873,15 @@ static void handle_events(void)
|
||||
code = event2keycode(event.key, true);
|
||||
if (code >= 0) {
|
||||
if (!emul_suspended) {
|
||||
if (code == 0x36) {
|
||||
ctrl_down = true;
|
||||
} else if (code == 0x3a) {
|
||||
opt_down = true;
|
||||
code = modify_opt_cmd(code);
|
||||
} else if (code == 0x37) {
|
||||
cmd_down = true;
|
||||
code = modify_opt_cmd(code);
|
||||
}
|
||||
if (code == 0x39) { // Caps Lock pressed
|
||||
if (caps_on) {
|
||||
ADBKeyUp(code);
|
||||
@ -1805,8 +1892,6 @@ static void handle_events(void)
|
||||
}
|
||||
} else
|
||||
ADBKeyDown(code);
|
||||
if (code == 0x36)
|
||||
ctrl_down = true;
|
||||
} else {
|
||||
if (code == 0x31)
|
||||
drv->resume(); // Space wakes us up
|
||||
@ -1822,6 +1907,15 @@ static void handle_events(void)
|
||||
} else
|
||||
code = event2keycode(event.key, false);
|
||||
if (code >= 0) {
|
||||
if (code == 0x36) {
|
||||
ctrl_down = false;
|
||||
} else if (code == 0x3a) {
|
||||
opt_down = false;
|
||||
code = modify_opt_cmd(code);
|
||||
} else if (code == 0x37) {
|
||||
cmd_down = false;
|
||||
code = modify_opt_cmd(code);
|
||||
}
|
||||
if (code == 0x39) { // Caps Lock released
|
||||
if (caps_on) {
|
||||
ADBKeyUp(code);
|
||||
@ -1832,8 +1926,6 @@ static void handle_events(void)
|
||||
}
|
||||
} else
|
||||
ADBKeyUp(code);
|
||||
if (code == 0x36)
|
||||
ctrl_down = false;
|
||||
}
|
||||
break;
|
||||
}
|
||||
@ -2290,4 +2382,11 @@ void video_set_dirty_area(int x, int y, int w, int h)
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef SHEEPSHAVER
|
||||
void video_set_gamma(int n_colors)
|
||||
{
|
||||
// Not supported in SDL 1.2
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif // ends: SDL version check
|
||||
|
File diff suppressed because it is too large
Load Diff
2866
BasiliskII/src/SDL/video_sdl3.cpp
Normal file
2866
BasiliskII/src/SDL/video_sdl3.cpp
Normal file
File diff suppressed because it is too large
Load Diff
@ -71,7 +71,7 @@ void SaveXPRAM(void)
|
||||
SDL_snprintf(full_path, sizeof(full_path), "%s/%s", dir, XPRAM_FILE_NAME);
|
||||
|
||||
// Save the XPRAM file
|
||||
FILE *f = fopen(XPRAM_FILE_NAME, "wb");
|
||||
FILE *f = fopen(full_path, "wb");
|
||||
if (f != NULL) {
|
||||
fwrite(XPRAM, 256, 1, f);
|
||||
fclose(f);
|
||||
|
7
BasiliskII/src/Unix/.gitignore
vendored
7
BasiliskII/src/Unix/.gitignore
vendored
@ -19,6 +19,13 @@ cpustbl.cpp
|
||||
cputbl.h
|
||||
cpuemu_nf.cpp
|
||||
cpustbl_nf.cpp
|
||||
cpufunctbl.cpp
|
||||
compemu.cpp
|
||||
compstbl.cpp
|
||||
comptbl.h
|
||||
|
||||
# Generated GLib resource files
|
||||
g_resource.cpp
|
||||
|
||||
patches/*
|
||||
.pc*
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -1,166 +0,0 @@
|
||||
/* GIMP RGBA C-Source image dump (BasiliskII_32x32x32_icon.c) */
|
||||
|
||||
static const struct {
|
||||
unsigned int width;
|
||||
unsigned int height;
|
||||
unsigned int bytes_per_pixel; /* 2:RGB16, 3:RGB, 4:RGBA */
|
||||
unsigned char pixel_data[32 * 32 * 4 + 1];
|
||||
} icon_32x32x32 = {
|
||||
32, 32, 4,
|
||||
"\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"
|
||||
"\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"
|
||||
"\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"
|
||||
"\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"
|
||||
"\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"
|
||||
"\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"
|
||||
"\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"
|
||||
"\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"
|
||||
"\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0q'\17s\377s\0\377q\37\6s\0\0\0\0\0\0\0\0"
|
||||
"\0\0\0\0\0\0\0\0JJJ\377\7\7\7!\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"
|
||||
"\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"
|
||||
"\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0h(\16k\377\214\0\377"
|
||||
"\356b\16\357\36\27\27!\12\12\12\30%%%)\356b\16\357\315Y\40\316\263I\40\326"
|
||||
"\245B)\377\203\27\0\204z\16\0{z\16\0{\203\27\0\204z\16\0{\203\27\0\204z\16"
|
||||
"\0{z\16\0{\203\27\0\204\264I\27\265,\26\15""9\0\0\0\10\0\0\0\0\0\0\0\0\0"
|
||||
"\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\10\377{\0\377\377\204"
|
||||
"\0\377%\22\22)\27\27\27!AAARbbb\224jjj\224\377\224\0\377\377\214\0\377\377"
|
||||
"\224\0\377\377\224\0\377\377\214\0\377\377\224\0\377\377\224\0\377\377\224"
|
||||
"\0\377\377\224\0\377\377\224\0\377\377\224\0\377\377\224\0\377\377\224\0"
|
||||
"\377\377s\0\377,((9\37\37\37)\0\0\0\0\0\0\0\0,,,9jjj\204jjj\204aaa{jjj\204"
|
||||
"\2138\40\224\377\224\0\377\377k\0\377bbb\204jjj\234zzz\306zzz\326\203\203"
|
||||
"\203\316zzz\245\377\224\0\377\377\204\0\377\377s\0\377\377s\0\377\377{\0"
|
||||
"\377\377s\0\377\377s\0\377\377s\0\377\377{\0\377\377s\0\377\377s\0\377\377"
|
||||
"s\0\377\377s\0\377\377c\0\377zzz\306rrr\265\0\0\0\0\0\0\0\0jjj\204\234\234"
|
||||
"\234\377\234\234\234\377\245\245\245\377\357c\30\377\377\224\0\377\367c\0"
|
||||
"\377\224\224\224\377{{{\377ccc\377sss\377\214\214\214\377\234\234\234\377"
|
||||
"\234\234\234\377\377\224\0\377\377{\0\377\377s\0\377\377k\0\377\377k\0\377"
|
||||
"\377s\0\377\377k\0\377\377s\0\377\377k\0\377\377s\0\377\377s\0\377\377s\0"
|
||||
"\377\377s\0\377\306Z9\377{{{\377rrr\275\0\0\0\0\0\0\0\0bbb\204\234\234\234"
|
||||
"\377\245\245\245\377\367s\20\377\377\204\0\377\377k\0\377\214\214\214\377"
|
||||
"kkk\377ZZZ\377{{{\377\224\224\224\377\234\234\234\377\245\245\245\377\224"
|
||||
"\224\224\377\2559!\377\306\224\204\377\214kk\377kkk\377sss\377sss\377sss"
|
||||
"\377sss\377sss\377sss\377sss\377\367R\10\377\377k\0\377{{{\377\203\203\203"
|
||||
"\367XXX\204\0\0\0\0\0\0\0\0jjj\204\245\245\245\377\357c\30\377\377\204\0"
|
||||
"\377\377s\0\377\224\204\204\377ccc\377ZZZ\377{{{\377\234\234\234\377\245"
|
||||
"\245\245\377\245\245\245\377\234\234\234\377RRR\377sss\377\306\306\306\377"
|
||||
"\214\214\214\377\214\214\214\377\214\214\214\377\214\214\214\377\214\214"
|
||||
"\214\377\224\224\224\377\214\214\214\377\214\214\214\377\224\224\224\377"
|
||||
"\377c\0\377\357R\30\377\204\204\204\377zzz\326666B\0\0\0\0\0\0\0\0aaa{\306"
|
||||
"sR\377\377\224\0\377\377{\0\377\316R1\377ccc\377RRR\377JJJ\377{{{\377\234"
|
||||
"\234\234\377\245\245\245\377\234\234\234\377\224\224\224\377RRR\377\336\336"
|
||||
"\336\377\336\336\336\377\316\316\316\377\316\316\316\377\224\224\224\377"
|
||||
"RRR\377\326\326\326\377\326\326\326\377\326\326\326\377\326\326\326\377\326"
|
||||
"\306\306\377\377k\0\377\306\275\265\377\203\203\203\357jjj\234\25\25\25\30"
|
||||
"\0\0\0\0\0\0\0\0jbb\204\377\224\0\377\377{\0\377\377k\0\377ccc\377RRR\377"
|
||||
"kkk\377ccc\377\204\204\204\377\245\245\245\377\245\245\245\377\234\234\234"
|
||||
"\377ZZZ\377ccc\377\347\347\347\377\347\347\347\377\347\347\347\377\347\347"
|
||||
"\347\377\224\224\224\377RRR\377\347\347\347\377\336\336\336\377\347\347\347"
|
||||
"\377\347\347\347\377\367k9\377\377c\0\377\275\275\275\377\203\203\203\347"
|
||||
"IIIZ\0\0\0\0\0\0\0\0\0\0\0\0\356j\16\357\377\204\0\377\377s\0\377\234R9\377"
|
||||
"RRR\377ZZZ\377\214\214\214\377ccc\377\204\204\204\377\234\234\234\377\234"
|
||||
"\234\234\377\245\245\245\377RRR\377\326\326\326\377\347\347\347\377\336\336"
|
||||
"\336\377\347\347\347\377\336\336\336\377\234\234\234\377JJJ\377\347\347\347"
|
||||
"\377\347\347\347\377\347\347\347\377\336\336\336\377\377k\0\377\347\224\204"
|
||||
"\377\234\234\234\377\203\203\203\326\36\36\36!\0\0\0\0\0\0\0\0\0\0\0\10\377"
|
||||
"\224\0\377\377{\0\377\377k\0\377RRR\377RRR\377sss\377\224\224\224\377\234"
|
||||
"\234\234\377\245\245\245\377\245\245\245\377\234\234\234\377\214\214\214"
|
||||
"\377JJJ\377\347\347\347\377\347\347\347\377\347\347\347\377\336\336\336\377"
|
||||
"\347\347\347\377\347\347\347\377\347\347\347\377\347\347\347\377\347\347"
|
||||
"\347\377\336\336\336\377\347\275\265\377\377s\0\377\316\316\316\377\214\214"
|
||||
"\214\377\203\203\203\265\0\0\0\10\0\0\0\0\0\0\0\0\335Y\26\336\377\214\0\377"
|
||||
"\377s\0\377\316B\30\377JJJ\377ZZZ\377\204\204\204\377\234\234\234\377\245"
|
||||
"\245\245\377\245\245\245\377\234\234\234\377\245\245\245\377ccc\377kkk\377"
|
||||
"\347\347\347\377\336\336\336\377\347\347\347\377\347\347\347\377\347\347"
|
||||
"\347\377\336\336\336\377\336\336\336\377\347\347\347\377\336\336\336\377"
|
||||
"\347\347\347\377\377c!\377\367c)\377\265\265\265\377\214\214\214\377zzz\224"
|
||||
"\0\0\0\0\0\0\0\0\0\0\0\0\377\224\0\377\377{\0\377\377k\0\377ZRR\377RRR\377"
|
||||
"{kk\377\377Z\10\377\377s\0\377\377s\0\377\377s\0\377\357R\30\377\245\245"
|
||||
"\245\377RRR\377\255\255\255\377\347\347\347\377\336\336\336\377\347\347\347"
|
||||
"\377\336\336\336\377\347\347\347\377\347\347\347\377\347\347\347\377\347"
|
||||
"\347\347\377\347\347\347\377\347\347\347\377\377k\0\377\336\316\316\377\234"
|
||||
"\234\234\377\245\245\245\377yyy\204\0\0\0\0\0\0\0\0\36\27\27!\377\224\0\377"
|
||||
"\377s\0\377\377k\0\377RRR\377ZRR\377\377k\0\377\316cJ\377\316cJ\377\377\214"
|
||||
"\0\377\377s\0\377\377s\0\377\377c\0\377RRR\377\326\326\326\377\336\336\336"
|
||||
"\377\347\347\347\377\347\347\347\377\347\347\347\377\336\336\336\377\347"
|
||||
"\347\347\377\336\336\336\377\347\347\347\377\336\336\336\377\357\245\224"
|
||||
"\377\377c\0\377\306\306\306\377\214\214\214\377\275\275\275\377yyy\204\0"
|
||||
"\0\0\0\0\0\0\0\212(\16\214\377\224\0\377\377k\0\377\377R\0\377RRR\377ccc"
|
||||
"\377\224\224\224\377\234\234\234\377{{{\377ccc\377\377\214\0\377\377s\0\377"
|
||||
"\377s\0\377\347B\10\377\316\316\316\377\347\347\347\377\347\347\347\377\347"
|
||||
"\347\347\377\336\336\336\377\347\347\347\377\347\347\347\377\347\347\347"
|
||||
"\377\347\347\347\377\347\347\347\377\377R\0\377\357\204c\377\255\255\255"
|
||||
"\377\224\224\224\377\326\326\326\377zzz{\0\0\0\0\0\0\0\0\335b\26\336\377"
|
||||
"\214\0\377\377s\0\377\336J\20\377RRR\377kkk\377\224\224\224\377\204\204\204"
|
||||
"\377kkk\377{{{\377\265ZJ\377\377\214\0\377\377s\0\377\377s\0\377111\377J"
|
||||
"JJ\377RRR\377JJJ\377RRR\377\347\347\347\377\347\347\347\377\347\347\347\377"
|
||||
"\336\336\336\377\347\347\347\377\377k\0\377\326\326\326\377\234\234\234\377"
|
||||
"\255\255\255\377\336\336\336\377yyy\204\0\0\0\0\0\0\0\0\377Z\0\377\377\204"
|
||||
"\0\377\377k\0\377\275B\30\377JJJ\377{{{\377\234\234\234\377\234\234\234\377"
|
||||
"\234\234\234\377\234\234\234\377\234\234\234\377\377\224\0\377\377{\0\377"
|
||||
"\377s\0\377\265B)\377sss\377\224\224\224\377kkk\377ZZZ\377\336\336\336\377"
|
||||
"\336\336\336\377\347\347\347\377\347\347\347\377\367\224{\377\377Z\10\377"
|
||||
"\306\306\306\377\214\214\214\377\306\306\306\377\336\336\336\377\203\203"
|
||||
"\203\204\0\0\0\0\0\0\0\0\377c\0\377\377\204\0\377\377s\0\377\275B!\377RR"
|
||||
"R\377{{{\377\234\234\234\377\245\245\245\377\234\234\234\377\245\245\245"
|
||||
"\377\234\234\234\377\377c\0\377\377\214\0\377\377k\0\377\357J\10\377ccc\377"
|
||||
"\224\224\224\377RRR\377\214\214\214\377\347\347\347\377\347\347\347\377\347"
|
||||
"\347\347\377\336\336\336\377\377Z\0\377\347\245\234\377\255\255\255\377\234"
|
||||
"\234\234\377\326\326\326\377\347\347\347\377zzz{\0\0\0\0\0\0\0\0\377c\0\377"
|
||||
"\377\204\0\377\377s\0\377\316J\30\377RRR\377\204\204\204\377\224\224\224"
|
||||
"\377kkk\377{{{\377\234\234\234\377\245\245\245\377\347c)\377\377\224\0\377"
|
||||
"\377s\0\377\377R\0\377RRR\377\204\204\204\377JJJ\377\265\265\265\377\347"
|
||||
"\347\347\377\336\336\336\377\347\347\347\377\336\336\336\377\377k\0\377J"
|
||||
"JJ\377\214\214\214\377\265\265\265\377\336\336\336\377\347\347\347\377zz"
|
||||
"z{\0\0\0\0\0\0\0\0\346b\17\347\377\214\0\377\377k\0\377\347J\10\377ZZZ\377"
|
||||
"\204\204\204\377\245\245\245\377\214\214\214\377kkk\377kkk\377kkk\377\275"
|
||||
"J1\377\377\224\0\377\377s\0\377\377Z\0\377JJJ\377sss\377RRR\377\214\214\214"
|
||||
"\377sss\377ZZZ\377JJJ\377\275B!\377\336J\20\377\255\255\255\377\224\224\224"
|
||||
"\377\316\316\316\377\336\336\336\377\347\347\347\377zzz{\0\0\0\0\0\0\0\0"
|
||||
"\2437\27\245\377\214\0\377\377s\0\377\377Z\0\377RRR\377\204\204\204\377\234"
|
||||
"\234\234\377\245\245\245\377\234\234\234\377\245\245\245\377\234\234\234"
|
||||
"\377\306ZB\377\377\224\0\377\377s\0\377\367J\0\377111\377RRR\377RRR\377Z"
|
||||
"ZZ\377sss\377\224\224\224\377\326\326\326\377\377c\0\377\336\326\316\377"
|
||||
"\245\245\245\377\245\245\245\377\336\336\336\377\347\347\347\377\347\347"
|
||||
"\347\377zzz{\0\0\0\0\0\0\0\0%\22\22)\377\214\0\377\377s\0\377\377k\0\377"
|
||||
"RRR\377{{{\377\234\234\234\377\245\245\245\377\234\234\234\377\245\245\245"
|
||||
"\377\234\234\234\377\326kJ\377\377\214\0\377\377s\0\377\306J!\377RRR\377"
|
||||
"sss\377JJJ\377\265\265\265\377\336\336\336\377\347\347\347\377\347\326\326"
|
||||
"\377\377c\0\377\316\316\316\377\224\224\224\377\275\275\275\377\336\336\336"
|
||||
"\377\347\347\347\377\336\336\336\377zzz{\0\0\0\0\0\0\0\0\0\0\0\0\377\224"
|
||||
"\0\377\377\204\0\377\377s\0\377kJJ\377kkk\377\234\234\234\377\245\245\245"
|
||||
"\377\234\234\234\377\245\245\245\377\245\245\245\377\347c)\377\377\214\0"
|
||||
"\377\377s\0\377cJB\377ZZZ\377{{{\377RRR\377\224\224\224\377\347\347\347\377"
|
||||
"\347\347\347\377\367c)\377\367\204c\377\275\275\275\377\224\224\224\377\316"
|
||||
"\316\316\377\347\347\347\377\347\347\347\377\347\347\347\377yyy\204\0\0\0"
|
||||
"\0\0\0\0\0\0\0\0\0\264@\27\265\377\214\0\377\377s\0\377\357J\10\377kkk\377"
|
||||
"\224\224\224\377\245\245\245\377\234\234\234\377\245\245\245\377\234\234"
|
||||
"\234\377\377c\0\377\377\204\0\377\377c\0\377RRR\377ZZZ\377\204\204\204\377"
|
||||
"ccc\377ccc\377\336\336\336\377\347\347\347\377\377s\0\377\326\326\326\377"
|
||||
"\245\245\245\377\245\245\245\377\336\336\336\377\336\336\336\377\336\336"
|
||||
"\336\377\347\347\347\377zzz{\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\10\377\224\0\377"
|
||||
"\377\204\0\377\377k\0\377kkc\377\245\245\245\377\265\265\265\377\275\275"
|
||||
"\275\377\265\265\265\377\265\265\265\377\377\224\0\377\377s\0\377\234ZR\377"
|
||||
"ccc\377kkk\377\245\245\245\377\245\245\245\377RRR\377\357\357\357\377\357"
|
||||
"\255\234\377\377R\0\377\326\326\326\377\234\234\234\377\326\326\326\377\357"
|
||||
"\357\357\377\357\357\357\377\367\367\367\377\357\357\357\377zzz{\0\0\0\0"
|
||||
"\0\0\0\0\0\0\0\0\0\0\0\0H%\37J\377\214\0\377\377{\0\377\367Z\0\377XXX\204"
|
||||
"\17\17\17\20\0\0\0\0\0\0\0\0\2128\27\214\377{\0\377\335Q\16\336zzz\326zz"
|
||||
"z\367bbb\224\17\17\17\20\0\0\0\0RRR\377\0\0\0\0\377Z\0\377W\37\26ZQQQkjj"
|
||||
"j\234\27\27\27!\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"
|
||||
"\0\0\0\0\0\0\0\0\0\0\0yA0\204\377\224\0\377\377{\0\377\367Z\10\3776..B\0"
|
||||
"\0\0\0P\37\17R\377{\0\377\346Y\16\357QQQk\203\203\203\357zzz\316666B\0\0"
|
||||
"\0\10\0\0\0\0III\336777\234\377s\0\377\27\27\27!rrr\245QQQk\0\0\0\10\0\0"
|
||||
"\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"
|
||||
"\0\0\17\17\17\20YYY{\356Y\7\367\377k\0\377\377k\0\377\377s\0\377\377c\0\377"
|
||||
"a&\27c%%%)rrr\265zzz\326QQQk\0\0\0\10\0\0\0\0\0\0\0\0\0\0\0\20RRR\377\0\0"
|
||||
"\0\0""777Jrrr\265$$$1\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"
|
||||
"\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\25\25\25\30YYY{zzz\336\203\203"
|
||||
"\203\357rrr\255IIIZIIIZjjj\245zzz\316QQQk\17\17\17\20\0\0\0\0\0\0\0\0\0\0"
|
||||
"\0\0\0\0\0\0\0\0\0\0\0\0\0\10IIIZXXXs\17\17\17\20\0\0\0\0\0\0\0\0\0\0\0\0"
|
||||
"\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"
|
||||
"\0\0\0\10\17\17\17\20AAAJbbb\224rrr\275zzz\275jjj\255bbb\214666B\17\17\17"
|
||||
"\20\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\10\0\0\0\20\17"
|
||||
"\17\17\20\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"
|
||||
"\0\0\0\0",
|
||||
};
|
||||
|
@ -20,6 +20,8 @@
|
||||
# along with this program; if not, write to the Free Software
|
||||
# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
|
||||
sw_vers > /dev/null && exit 0
|
||||
|
||||
PAGEZERO_SIZE=0x2000
|
||||
[[ -n "$1" ]] && PAGEZERO_SIZE=$1
|
||||
# You want all the output to go to stderr so that configure is quiet but
|
||||
|
506
BasiliskII/src/Unix/Linux/etherhelpertool.c
Normal file
506
BasiliskII/src/Unix/Linux/etherhelpertool.c
Normal file
@ -0,0 +1,506 @@
|
||||
/*
|
||||
* etherhelpertool.c - Reads and writes raw ethernet packets usng bpf
|
||||
* interface.
|
||||
*
|
||||
* Copyright (C) 2010, Daniel Sumorok
|
||||
*
|
||||
* Basilisk II (C) 1997-2008 Christian Bauer
|
||||
*
|
||||
* This program 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 Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program 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 this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
|
||||
#include <sys/types.h>
|
||||
#include <sys/socket.h>
|
||||
#include <ifaddrs.h>
|
||||
#include <errno.h>
|
||||
#include <sys/select.h>
|
||||
|
||||
#include <unistd.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
#include <net/if.h>
|
||||
#include <sys/time.h>
|
||||
#include <sys/ioctl.h>
|
||||
#include <sys/socket.h>
|
||||
#include <netpacket/packet.h>
|
||||
#include <net/ethernet.h>
|
||||
#include <fcntl.h>
|
||||
#include <signal.h>
|
||||
|
||||
#include <linux/if_tun.h>
|
||||
|
||||
#include <strings.h>
|
||||
|
||||
#define STR_MAX 256
|
||||
#define MAX_ARGV 10
|
||||
|
||||
static int remove_bridge = 0;
|
||||
static char bridge_name[STR_MAX];
|
||||
static const char *exec_name = "etherhelpertool";
|
||||
|
||||
static int main_loop(int sd, int use_bpf);
|
||||
static int open_tap(char *ifname);
|
||||
static int run_cmd(const char *cmd);
|
||||
static void handler(int signum);
|
||||
static int install_signal_handlers(void);
|
||||
static void do_exit(void);
|
||||
static int open_bpf(char *ifname);
|
||||
|
||||
int main(int argc, char **argv)
|
||||
{
|
||||
char *if_name;
|
||||
int ret = 255;
|
||||
int sd = -1;
|
||||
int tapNum;
|
||||
int use_bpf;
|
||||
|
||||
if (argc != 2) {
|
||||
return 255;
|
||||
}
|
||||
|
||||
if_name = argv[1];
|
||||
|
||||
do {
|
||||
if (strncmp(if_name, "tap", 3) == 0) {
|
||||
sd = open_tap(if_name);
|
||||
use_bpf = 0;
|
||||
} else {
|
||||
sd = open_bpf(if_name);
|
||||
use_bpf = 1;
|
||||
}
|
||||
|
||||
if (sd < 0) {
|
||||
fprintf(stderr, "%s: open device failed.\n",
|
||||
exec_name);
|
||||
ret = 253;
|
||||
break;
|
||||
}
|
||||
|
||||
if (install_signal_handlers() != 0) {
|
||||
fprintf(stderr,
|
||||
"%s: failed to install signal handers.\n",
|
||||
exec_name);
|
||||
ret = 252;
|
||||
break;
|
||||
}
|
||||
|
||||
ret = main_loop(sd, use_bpf);
|
||||
close(sd);
|
||||
} while (0);
|
||||
|
||||
do_exit();
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int main_loop(int sd, int use_bpf)
|
||||
{
|
||||
fd_set readSet;
|
||||
char *outgoing, *incoming;
|
||||
unsigned short *out_len;
|
||||
unsigned short *in_len;
|
||||
int in_index, out_index;
|
||||
u_int blen = 0;
|
||||
int ret;
|
||||
int fret = 0;
|
||||
int pkt_len;
|
||||
int frame_len;
|
||||
int pad;
|
||||
char c = 0;
|
||||
|
||||
blen = 4096;
|
||||
|
||||
incoming = malloc(blen);
|
||||
if (incoming == NULL) {
|
||||
fprintf(stderr,
|
||||
"%s: malloc() failed.\n",
|
||||
exec_name);
|
||||
return -2;
|
||||
}
|
||||
|
||||
outgoing = malloc(blen);
|
||||
if (outgoing == NULL) {
|
||||
free(incoming);
|
||||
fprintf(stderr,
|
||||
"%s: malloc() failed.\n",
|
||||
exec_name);
|
||||
return -3;
|
||||
}
|
||||
|
||||
in_index = 0;
|
||||
out_index = 0;
|
||||
|
||||
out_len = (unsigned short *)outgoing;
|
||||
|
||||
/* Let our parent know we are ready for business. */
|
||||
if(write(0, &c, 1) != 1) {
|
||||
fprintf(stderr, "%s: Failed to notify main application: %s\n",
|
||||
__func__, strerror(errno));
|
||||
}
|
||||
|
||||
while (1) {
|
||||
int i;
|
||||
FD_ZERO(&readSet);
|
||||
FD_SET(0, &readSet);
|
||||
FD_SET(sd, &readSet);
|
||||
|
||||
ret = select(sd + 1, &readSet, NULL, NULL, NULL);
|
||||
if (ret < 0) {
|
||||
fprintf(stderr,
|
||||
"%s: select() failed.\n",
|
||||
exec_name);
|
||||
fret = -4;
|
||||
break;
|
||||
}
|
||||
|
||||
if (FD_ISSET(0, &readSet)) {
|
||||
if (out_index < 2) {
|
||||
ret = read(0, outgoing + out_index, 2-out_index);
|
||||
} else {
|
||||
ret = read(0, outgoing + out_index, *out_len - out_index + 2);
|
||||
}
|
||||
|
||||
if (ret < 1) {
|
||||
if(ret < 0) {
|
||||
fprintf(stderr,
|
||||
"%s: read() failed.\n",
|
||||
exec_name);
|
||||
}
|
||||
fret = -5;
|
||||
break;
|
||||
}
|
||||
|
||||
out_index += ret;
|
||||
|
||||
if (out_index > 1) {
|
||||
if ((*out_len + 2) > blen) {
|
||||
fret = -6;
|
||||
break;
|
||||
}
|
||||
|
||||
if (out_index == (*out_len + 2)) {
|
||||
if(use_bpf) {
|
||||
ret = write(sd, out_len + 1, *out_len);
|
||||
if (ret != *out_len) {
|
||||
fprintf(stderr,
|
||||
"%s: write() failed.\n",
|
||||
exec_name);
|
||||
fret = -7;
|
||||
break;
|
||||
}
|
||||
} else {
|
||||
ret = write(sd, out_len + 1, *out_len);
|
||||
if (ret != *out_len) {
|
||||
fprintf(stderr,
|
||||
"%s: write() failed.\n",
|
||||
exec_name);
|
||||
fret = -7;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
out_index = 0;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
if (FD_ISSET(sd, &readSet)) {
|
||||
in_len = (unsigned short *)incoming;
|
||||
|
||||
pkt_len = read(sd, in_len + 1, blen-2);
|
||||
if (pkt_len < 14) {
|
||||
fprintf(stderr,
|
||||
"%s: read() returned %d.\n",
|
||||
exec_name, pkt_len);
|
||||
fret = -8;
|
||||
break;
|
||||
}
|
||||
*in_len = pkt_len;
|
||||
|
||||
if (write(0, in_len, pkt_len + 2) < (pkt_len + 2)) {
|
||||
fprintf(stderr,
|
||||
"%s: write() failed\n",
|
||||
exec_name);
|
||||
fret = -10;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
free(incoming);
|
||||
free(outgoing);
|
||||
|
||||
return fret;
|
||||
}
|
||||
|
||||
|
||||
static int open_tap(char *ifname)
|
||||
{
|
||||
char str[STR_MAX] = {0};
|
||||
char ifstr[STR_MAX] = {0};
|
||||
char *interface;
|
||||
char *address = NULL;
|
||||
char *netmask = NULL;
|
||||
char *bridge = NULL;
|
||||
char *bridged_if = NULL;
|
||||
int sd;
|
||||
struct ifreq ifr = {0};
|
||||
|
||||
snprintf(ifstr, STR_MAX, "%s", ifname);
|
||||
interface = strtok(ifstr, "/");
|
||||
bridge = strtok(NULL, "/");
|
||||
if (bridge != NULL) {
|
||||
bridged_if = strtok(NULL, "/");
|
||||
}
|
||||
interface = strtok(ifstr, ":");
|
||||
|
||||
address = strtok(NULL, ":");
|
||||
|
||||
if (address != NULL) {
|
||||
netmask = strtok(NULL, ":");
|
||||
}
|
||||
|
||||
sd = open("/dev/net/tun", O_RDWR);
|
||||
if (sd < 0) {
|
||||
fprintf(stderr, "%s: Failed to open %s\n",
|
||||
exec_name, interface);
|
||||
return -1;
|
||||
}
|
||||
|
||||
snprintf(str, STR_MAX, "/dev/%s", interface);
|
||||
ifr.ifr_flags = IFF_TAP | IFF_NO_PI;
|
||||
strncpy(ifr.ifr_name, interface, IFNAMSIZ);
|
||||
|
||||
if(ioctl(sd, TUNSETIFF, (void *)&ifr) != 0) {
|
||||
fprintf(stderr, "%s: ioctl(TUNSETIFF): %s\n",
|
||||
__func__, strerror(errno));
|
||||
close(sd);
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (address == NULL) {
|
||||
snprintf(str, STR_MAX, "/sbin/ifconfig %s up", interface);
|
||||
} else if (netmask == NULL) {
|
||||
snprintf(str, STR_MAX, "/sbin/ifconfig %s %s",
|
||||
interface, address);
|
||||
} else {
|
||||
snprintf(str, STR_MAX, "/sbin/ifconfig %s %s netmask %s",
|
||||
interface, address, netmask);
|
||||
}
|
||||
|
||||
if (run_cmd(str) != 0) {
|
||||
fprintf(stderr, "%s: Failed to configure %s\n",
|
||||
exec_name, interface);
|
||||
close(sd);
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (bridge != NULL) {
|
||||
/* Check to see if bridge is alread up */
|
||||
snprintf(str, STR_MAX, "/sbin/ifconfig %s", bridge);
|
||||
if (run_cmd(str) == 0) {
|
||||
/* bridge is already up */
|
||||
if (bridged_if != NULL) {
|
||||
fprintf(stderr, "%s: Warning: %s already exists, so %s was not added.\n",
|
||||
exec_name, bridge, bridged_if);
|
||||
}
|
||||
} else {
|
||||
snprintf(str, STR_MAX, "/sbin/brctl addbr %s", bridge);
|
||||
if (run_cmd(str) != 0) {
|
||||
fprintf(stderr, "%s: Failed to create %s\n",
|
||||
exec_name, bridge);
|
||||
close(sd);
|
||||
return -1;
|
||||
}
|
||||
remove_bridge = 1;
|
||||
|
||||
strncpy(bridge_name, bridge, STR_MAX);
|
||||
|
||||
snprintf(str, STR_MAX, "/sbin/ifconfig %s up", bridge);
|
||||
if (run_cmd(str) != 0) {
|
||||
fprintf(stderr, "%s: Failed to open %s\n",
|
||||
exec_name, bridge);
|
||||
close(sd);
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (bridged_if != NULL) {
|
||||
snprintf(str, STR_MAX, "/sbin/brctl addif %s %s",
|
||||
bridge, bridged_if);
|
||||
if (run_cmd(str) != 0) {
|
||||
fprintf(stderr, "%s: Failed to add %s to %s\n",
|
||||
exec_name, bridged_if, bridge);
|
||||
close(sd);
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
snprintf(str, STR_MAX, "/sbin/brctl addif %s %s",
|
||||
bridge, interface);
|
||||
if (run_cmd(str) != 0) {
|
||||
fprintf(stderr, "%s: Failed to add %s to %s\n",
|
||||
exec_name, interface, bridge);
|
||||
close(sd);
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return sd;
|
||||
}
|
||||
|
||||
static int run_cmd(const char *cmd) {
|
||||
char cmd_buffer[STR_MAX] = {0};
|
||||
char *argv[MAX_ARGV + 1] = {0};
|
||||
int i;
|
||||
pid_t pid, waitpid;
|
||||
int status = 0;
|
||||
|
||||
/* Collect arguments */
|
||||
strncpy(cmd_buffer, cmd, STR_MAX-1);
|
||||
|
||||
argv[0] = strtok(cmd_buffer, " ");
|
||||
for (i=1; i<MAX_ARGV; ++i) {
|
||||
argv[i] = strtok(NULL, " ");
|
||||
if (argv[i] == NULL) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/* Run sub process */
|
||||
pid = fork();
|
||||
if (pid == 0) {
|
||||
|
||||
/* Child process */
|
||||
fclose(stdout);
|
||||
fclose(stderr);
|
||||
|
||||
if (execve(argv[0], argv, NULL) < 0) {
|
||||
perror("execve");
|
||||
return -1;
|
||||
}
|
||||
} else {
|
||||
/* Wait for child to exit */
|
||||
waitpid = wait(&status);
|
||||
if (waitpid < 0) {
|
||||
perror("wait");
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (status != 0) {
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void handler(int signum) {
|
||||
do_exit();
|
||||
exit(1);
|
||||
}
|
||||
|
||||
static int install_signal_handlers() {
|
||||
struct sigaction act = {0};
|
||||
|
||||
act.sa_handler = handler;
|
||||
sigemptyset(&act.sa_mask);
|
||||
|
||||
if (sigaction(SIGINT, &act, NULL) != 0) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
||||
if (sigaction(SIGHUP, &act, NULL) != 0) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
||||
if (sigaction(SIGTERM, &act, NULL) != 0) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void do_exit() {
|
||||
char cmd[STR_MAX];
|
||||
|
||||
if (remove_bridge) {
|
||||
snprintf(cmd, STR_MAX, "/sbin/ifconfig %s down",
|
||||
bridge_name);
|
||||
|
||||
if(run_cmd(cmd) != 0) {
|
||||
fprintf(stderr, "Failed to bring bridge down\n");
|
||||
}
|
||||
|
||||
snprintf(cmd, STR_MAX, "/sbin/brctl delbr %s",
|
||||
bridge_name);
|
||||
|
||||
if(run_cmd(cmd) != 0) {
|
||||
fprintf(stderr, "Failed to destroy bridge\n");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static int open_bpf(char *ifname)
|
||||
{
|
||||
int sd;
|
||||
struct sockaddr_ll sockaddr = {0};
|
||||
struct ifreq ifreq = {0};
|
||||
struct packet_mreq pmreq = {0};
|
||||
socklen_t socklen = sizeof(struct packet_mreq);
|
||||
|
||||
sd = socket(AF_PACKET, SOCK_RAW, htons(ETH_P_ALL));
|
||||
if(sd < 0) {
|
||||
perror("socket");
|
||||
return -1;
|
||||
}
|
||||
|
||||
strncpy(ifreq.ifr_name, ifname, IFNAMSIZ);
|
||||
if(ioctl(sd, SIOCGIFINDEX, &ifreq) != 0) {
|
||||
fprintf(stderr, "%s: ioctl(SIOCGIFINDEX): %s\n",
|
||||
__func__, strerror(errno));
|
||||
close(sd);
|
||||
return -1;
|
||||
}
|
||||
|
||||
pmreq.mr_ifindex = ifreq.ifr_ifindex;
|
||||
pmreq.mr_type = PACKET_MR_PROMISC;
|
||||
if(setsockopt(sd, SOL_PACKET, PACKET_ADD_MEMBERSHIP,
|
||||
&pmreq, socklen) != 0) {
|
||||
fprintf(stderr, "%s: setsockopt() failed: %s\n",
|
||||
__func__, strerror(errno));
|
||||
close(sd);
|
||||
return -1;
|
||||
}
|
||||
|
||||
sockaddr.sll_family = AF_PACKET;
|
||||
sockaddr.sll_ifindex = ifreq.ifr_ifindex;
|
||||
sockaddr.sll_protocol = htons(ETH_P_ALL);
|
||||
if(bind(sd, (struct sockaddr *)&sockaddr,
|
||||
sizeof(struct sockaddr_ll)) != 0) {
|
||||
fprintf(stderr, "%s: bind failed: %s\n",
|
||||
__func__, strerror(errno));
|
||||
close(sd);
|
||||
return -1;
|
||||
}
|
||||
|
||||
return sd;
|
||||
}
|
58
BasiliskII/src/Unix/Linux/runtool.c
Normal file
58
BasiliskII/src/Unix/Linux/runtool.c
Normal file
@ -0,0 +1,58 @@
|
||||
#include <string.h>
|
||||
#include <unistd.h>
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
#include <errno.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/wait.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/socket.h>
|
||||
#include <errno.h>
|
||||
|
||||
#define STR_MAX 1024
|
||||
#define MAX_ARGV 10
|
||||
|
||||
FILE * run_tool(const char *if_name, const char *tool_name) {
|
||||
char cmd_buffer[STR_MAX] = {0};
|
||||
char * const argv[3] = {NULL, NULL, NULL};
|
||||
int i;
|
||||
pid_t pid, waitpid;
|
||||
int status = 0;
|
||||
int fds[2];
|
||||
char c;
|
||||
|
||||
if(socketpair(PF_LOCAL, SOCK_STREAM, 0, fds) != 0) {
|
||||
fprintf(stderr, "%s: socketpair() failed: %s\n",
|
||||
__func__, strerror(errno));
|
||||
return NULL;
|
||||
}
|
||||
|
||||
((const char**)argv)[0] = tool_name;
|
||||
((const char**)argv)[1] = if_name;
|
||||
|
||||
/* Run sub process */
|
||||
pid = fork();
|
||||
if (pid == 0) {
|
||||
/* Child process */
|
||||
fclose(stdout);
|
||||
fclose(stdin);
|
||||
dup2(fds[0], 0);
|
||||
close(fds[1]);
|
||||
close(fds[0]);
|
||||
|
||||
if (execve(tool_name, argv, NULL) < 0) {
|
||||
perror("execve");
|
||||
exit(1);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
close(fds[0]);
|
||||
|
||||
if(read(fds[1], &c, 1) < 1) {
|
||||
close(fds[1]);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
return fdopen(fds[1], "rw");
|
||||
}
|
@ -17,6 +17,7 @@ DESTDIR =
|
||||
|
||||
CC = @CC@
|
||||
CXX = @CXX@
|
||||
GCR = @GCR@
|
||||
CFLAGS = @CFLAGS@
|
||||
CXXFLAGS = @CXXFLAGS@
|
||||
CPUINCLUDES_FLAGS=@CPUINCLUDES@
|
||||
@ -45,6 +46,9 @@ GUI_LIBS = @GUI_LIBS@
|
||||
GUI_SRCS = ../prefs.cpp prefs_unix.cpp prefs_editor_gtk.cpp ../prefs_items.cpp \
|
||||
../user_strings.cpp user_strings_unix.cpp xpram_unix.cpp sys_unix.cpp rpc_unix.cpp
|
||||
|
||||
GRESOURCE_SRCS = ui/help-overlay.ui ui/menu.ui ui/prefs-editor.ui
|
||||
GRESOURCE_XML = ui/basiliskii.gresource.xml
|
||||
|
||||
XPLAT_SRCS = ../CrossPlatform/vm_alloc.cpp ../CrossPlatform/sigsegv.cpp ../CrossPlatform/video_blit.cpp
|
||||
|
||||
## Files
|
||||
@ -100,7 +104,7 @@ define GUI_SRCS_LIST_TO_OBJS
|
||||
endef
|
||||
GUI_OBJS = $(GUI_SRCS_LIST_TO_OBJS)
|
||||
ifeq ($(USE_BINCUE),yes)
|
||||
GUI_OBJS += bincue_unix.o
|
||||
GUI_OBJS += bincue.o
|
||||
endif
|
||||
GUI_SRCS := $(GUI_SRCS:%=@top_srcdir@/%)
|
||||
|
||||
@ -161,7 +165,9 @@ installdirs:
|
||||
|
||||
uninstall:
|
||||
rm -f $(DESTDIR)$(bindir)/$(APP)$(EXEEXT)
|
||||
rm -f $(DESTDIR)$(bindir)/$(GUI_APP)$(EXEEXT)
|
||||
if test -f "$(GUI_APP_EXE)"; then \
|
||||
rm -f $(DESTDIR)$(bindir)/$(GUI_APP_EXE); \
|
||||
fi
|
||||
rm -f $(DESTDIR)$(man1dir)/$(APP).1
|
||||
rm -f $(DESTDIR)$(datadir)/$(APP)/keycodes
|
||||
rm -f $(DESTDIR)$(datadir)/$(APP)/fbdevices
|
||||
@ -169,10 +175,10 @@ uninstall:
|
||||
rmdir $(DESTDIR)$(datadir)/$(APP)
|
||||
|
||||
mostlyclean:
|
||||
rm -f $(PROGS) $(OBJ_DIR)/* core* *.core *~ *.bak
|
||||
rm -f $(PROGS) $(OBJ_DIR)/* core* *.core *~ *.bak ui/*~ ui/*.bak
|
||||
|
||||
clean: mostlyclean
|
||||
rm -f cpuemu.cpp cpudefs.cpp cputmp*.s cpufast*.s cpustbl.cpp cputbl.h compemu.cpp compstbl.cpp comptbl.h
|
||||
rm -f cpuemu.cpp cpudefs.cpp cputmp*.s cpufast*.s cpustbl.cpp cputbl.h compemu.cpp compstbl.cpp comptbl.h g_resource.cpp
|
||||
|
||||
distclean: clean
|
||||
rm -rf $(OBJ_DIR)
|
||||
@ -182,7 +188,9 @@ distclean: clean
|
||||
rm -f Darwin/lowmem Darwin/pagezero
|
||||
|
||||
depend dep:
|
||||
makedepend $(CPPFLAGS) -Y. $(SRCS) 2>/dev/null
|
||||
makedepend $(CPPFLAGS) # Truncate out previous rules
|
||||
# Manually process emitted obj targets to take out extra directory layers
|
||||
makedepend $(CPPFLAGS) -pobj/ -Y. $(SRCS) -f- 2>/dev/null | sed 's#^obj/.*/\(.*\.o\):#obj/\1:#' >> Makefile
|
||||
|
||||
$(OBJ_DIR)/SDLMain.o : SDLMain.m
|
||||
$(CC) $(CPPFLAGS) $(DEFS) $(CFLAGS) -c $< -o $@
|
||||
@ -212,13 +220,16 @@ $(OBJ_DIR)/gencpu$(EXEEXT): $(OBJ_DIR)/gencpu.o $(OBJ_DIR)/readcpu.o $(OBJ_DIR)/
|
||||
$(OBJ_DIR)/gencomp$(EXEEXT): $(OBJ_DIR)/gencomp.o $(OBJ_DIR)/readcpu.o $(OBJ_DIR)/cpudefs.o
|
||||
$(CXX) $(LDFLAGS) -o $(OBJ_DIR)/gencomp$(EXEEXT) $(OBJ_DIR)/gencomp.o $(OBJ_DIR)/readcpu.o $(OBJ_DIR)/cpudefs.o
|
||||
|
||||
cpudefs.cpp: $(OBJ_DIR)/build68k$(EXEEXT) @top_srcdir@/../uae_cpu/table68k
|
||||
$(OBJ_DIR)/build68k$(EXEEXT) <@top_srcdir@/../uae_cpu/table68k >cpudefs.cpp
|
||||
UAE_PATH = @UAE_PATH@
|
||||
|
||||
cpudefs.cpp: $(OBJ_DIR)/build68k$(EXEEXT) @top_srcdir@/$(UAE_PATH)/table68k
|
||||
$(OBJ_DIR)/build68k$(EXEEXT) <@top_srcdir@/$(UAE_PATH)/table68k >cpudefs.cpp
|
||||
cpustbl.cpp: cpuemu.cpp
|
||||
cpustbl_nf.cpp: cpustbl.cpp
|
||||
compstbl.cpp: compemu.cpp
|
||||
cputbl.h: cpuemu.cpp
|
||||
comptbl.h: compemu.cpp
|
||||
cpufunctbl.cpp: cputbl.h
|
||||
|
||||
cpuemu.cpp: $(OBJ_DIR)/gencpu$(EXEEXT)
|
||||
$(OBJ_DIR)/gencpu$(EXEEXT)
|
||||
@ -283,5 +294,8 @@ $(OBJ_DIR)/compemu7.o: compemu.cpp
|
||||
$(OBJ_DIR)/compemu8.o: compemu.cpp
|
||||
$(CXX) $(CPPFLAGS) $(DEFS) -DPART_8 $(CXXFLAGS) -c $< -o $@
|
||||
|
||||
g_resource.cpp: $(GRESOURCE_SRCS) $(GRESOURCE_XML)
|
||||
$(GCR) --generate-source $(GRESOURCE_XML) --target $@
|
||||
|
||||
#-------------------------------------------------------------------------
|
||||
# DO NOT DELETE THIS LINE -- make depend depends on it.
|
||||
|
@ -1,28 +0,0 @@
|
||||
# serial 1
|
||||
dnl Additional macros for Basilisk II
|
||||
|
||||
dnl Check for libgnomeui
|
||||
dnl B2_PATH_GNOMEUI([ACTION-IF-FOUND [, ACTION-IF-NOT-FOUND]])
|
||||
dnl Test to see if libgnomeui is installed, and define GNOMEUI_CFLAGS, LIBS
|
||||
AC_DEFUN([B2_PATH_GNOMEUI],
|
||||
[dnl
|
||||
dnl Get the cflags and libraries from the gnome-config script
|
||||
dnl
|
||||
AC_ARG_WITH(gnome-config,
|
||||
[ --with-gnome-config=GNOME_CONFIG Location of gnome-config],
|
||||
GNOME_CONFIG="$withval")
|
||||
|
||||
AC_PATH_PROG(GNOME_CONFIG, gnome-config, no)
|
||||
AC_MSG_CHECKING(for libgnomeui)
|
||||
if test "$GNOME_CONFIG" = "no"; then
|
||||
AC_MSG_RESULT(no)
|
||||
ifelse([$2], , :, [$2])
|
||||
else
|
||||
AC_MSG_RESULT(yes)
|
||||
GNOMEUI_CFLAGS=`$GNOME_CONFIG --cflags gnomeui`
|
||||
GNOMEUI_LIBS=`$GNOME_CONFIG --libs gnomeui`
|
||||
ifelse([$1], , :, [$1])
|
||||
fi
|
||||
AC_SUBST(GNOMEUI_CFLAGS)
|
||||
AC_SUBST(GNOMEUI_LIBS)
|
||||
])
|
@ -1,836 +0,0 @@
|
||||
/*
|
||||
* Copyright (C) 2002-2010 The DOSBox Team
|
||||
*
|
||||
* This program 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 Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program 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 this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
*/
|
||||
|
||||
/* Geoffrey Brown 2010
|
||||
* Includes ideas from dosbox src/dos/cdrom_image.cpp
|
||||
*
|
||||
* Limitations: 1) cue files must reference single bin file
|
||||
* 2) only supports raw mode1 data and audio
|
||||
* 3) no support for audio flags
|
||||
* 4) requires SDL audio or OS X core audio
|
||||
* 5) limited cue file keyword support
|
||||
*
|
||||
* Creating cue/bin files:
|
||||
* cdrdao read-cd --read-raw --paranoia 3 foo.toc
|
||||
* toc2cue foo.toc
|
||||
*/
|
||||
|
||||
#include "sysdeps.h"
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <ctype.h>
|
||||
#include <libgen.h>
|
||||
#include <string.h>
|
||||
#include <fcntl.h>
|
||||
#include <unistd.h>
|
||||
#include <sys/stat.h>
|
||||
#include <errno.h>
|
||||
|
||||
#ifdef OSX_CORE_AUDIO
|
||||
#include "../MacOSX/MacOSX_sound_if.h"
|
||||
static int bincue_core_audio_callback(void);
|
||||
#endif
|
||||
|
||||
#ifdef USE_SDL_AUDIO
|
||||
#include <SDL.h>
|
||||
#include <SDL_audio.h>
|
||||
#endif
|
||||
|
||||
#include "bincue_unix.h"
|
||||
#define DEBUG 0
|
||||
#include "debug.h"
|
||||
|
||||
#define MAXTRACK 100
|
||||
#define MAXLINE 512
|
||||
#define CD_FRAMES 75
|
||||
#define RAW_SECTOR_SIZE 2352
|
||||
#define COOKED_SECTOR_SIZE 2048
|
||||
|
||||
// Bits of Track Control Field -- These are standard for scsi cd players
|
||||
|
||||
#define PREMPHASIS 0x1
|
||||
#define COPY 0x2
|
||||
#define DATA 0x4
|
||||
#define AUDIO 0
|
||||
#define FOURTRACK 0x8
|
||||
|
||||
// Audio status -- These are standard for scsi cd players
|
||||
|
||||
#define CDROM_AUDIO_INVALID 0x00
|
||||
#define CDROM_AUDIO_PLAY 0x11
|
||||
#define CDROM_AUDIO_PAUSED 0x12
|
||||
#define CDROM_AUDIO_COMPLETED 0x13
|
||||
#define CDROM_AUDIO_ERROR 0x14
|
||||
#define CDROM_AUDIO_NO_STATUS 0x15
|
||||
|
||||
typedef unsigned char uint8;
|
||||
|
||||
// cuefiles can be challenging as some information is
|
||||
// implied. For example, there may a pregap (also postgap)
|
||||
// of silence that must be generated. Here we implement
|
||||
// only the pregap.
|
||||
|
||||
typedef struct {
|
||||
int number;
|
||||
unsigned int start; // Track start in frames
|
||||
unsigned int length; // Track length in frames
|
||||
loff_t fileoffset; // Track frame start within file
|
||||
unsigned int pregap; // Silence in frames to generate
|
||||
unsigned char tcf; // Track control field
|
||||
} Track;
|
||||
|
||||
typedef struct {
|
||||
char *binfile; // Binary file name
|
||||
unsigned int length; // file length in frames
|
||||
int binfh; // binary file handle
|
||||
int tcnt; // number of tracks
|
||||
Track tracks[MAXTRACK];
|
||||
} CueSheet;
|
||||
|
||||
typedef struct {
|
||||
CueSheet *cs; // cue sheet to play from
|
||||
int audiofh; // file handle for audio data
|
||||
unsigned int audioposition; // current position from audiostart (bytes)
|
||||
unsigned int audiostart; // start position if playing (frame)
|
||||
unsigned int audioend; // end position if playing (frames)
|
||||
unsigned int silence; // pregap (silence) bytes
|
||||
unsigned char audiostatus; // See defines above for status
|
||||
loff_t fileoffset; // offset from file beginning to audiostart
|
||||
#ifdef OSX_CORE_AUDIO
|
||||
OSXsoundOutput soundoutput;
|
||||
#endif
|
||||
} CDPlayer;
|
||||
|
||||
// Minute,Second,Frame data type
|
||||
|
||||
typedef struct {
|
||||
int m, s, f; // note size matters since we scan for %d !
|
||||
} MSF;
|
||||
|
||||
// Parser State
|
||||
|
||||
static unsigned int totalPregap;
|
||||
static unsigned int prestart;
|
||||
|
||||
// Audio System State
|
||||
|
||||
static bool audio_enabled = false;
|
||||
static uint8 silence_byte;
|
||||
|
||||
|
||||
// CD Player state. Note only one player is supported !
|
||||
|
||||
static CDPlayer player;
|
||||
|
||||
static void FramesToMSF(unsigned int frames, MSF *msf)
|
||||
{
|
||||
msf->m = frames/(60 * CD_FRAMES);
|
||||
frames = frames%(60 * CD_FRAMES);
|
||||
msf->s = frames/CD_FRAMES;
|
||||
msf->f = frames%CD_FRAMES;
|
||||
}
|
||||
|
||||
static int MSFToFrames(MSF msf)
|
||||
{
|
||||
return (msf.m * 60 * CD_FRAMES) + (msf.s * CD_FRAMES) + msf.f;
|
||||
}
|
||||
|
||||
|
||||
static int PositionToTrack(CueSheet *cs, unsigned int position)
|
||||
{
|
||||
int i;
|
||||
MSF msf;
|
||||
|
||||
FramesToMSF(position, &msf);
|
||||
|
||||
for (i = 0; i < cs->tcnt; i++) {
|
||||
if ((position >= cs->tracks[i].start) &&
|
||||
(position <= (cs->tracks[i].start + cs->tracks[i].length)))
|
||||
break;
|
||||
}
|
||||
return i;
|
||||
}
|
||||
|
||||
static bool AddTrack(CueSheet *cs)
|
||||
{
|
||||
int skip = prestart;
|
||||
Track *prev;
|
||||
Track *curr = &(cs->tracks[cs->tcnt]);
|
||||
|
||||
prestart = 0;
|
||||
|
||||
if (skip > 0) {
|
||||
if (skip > curr->start) {
|
||||
D(bug("AddTrack: prestart > start\n"));
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
curr->fileoffset = curr->start * RAW_SECTOR_SIZE;
|
||||
|
||||
// now we patch up the indicated time
|
||||
|
||||
curr->start += totalPregap;
|
||||
|
||||
// curr->pregap is supposed to be part of this track, but it
|
||||
// must be generated as silence
|
||||
|
||||
totalPregap += curr->pregap;
|
||||
|
||||
if (cs->tcnt == 0) {
|
||||
if (curr->number != 1) {
|
||||
D(bug("AddTrack: number != 1\n"));
|
||||
return false;
|
||||
}
|
||||
cs->tcnt++;
|
||||
return true;
|
||||
}
|
||||
|
||||
prev = &(cs->tracks[cs->tcnt - 1]);
|
||||
|
||||
if (prev->start < skip)
|
||||
prev->length = skip - prev->start - curr->pregap;
|
||||
else
|
||||
prev->length = curr->start - prev->start - curr->pregap;
|
||||
|
||||
// error checks
|
||||
|
||||
if (curr->number <= 1) {
|
||||
D(bug("Bad track number %d\n", curr->number));
|
||||
return false;
|
||||
}
|
||||
if ((prev->number + 1 != curr->number) && (curr->number != 0xAA)) {
|
||||
D(bug("Bad track number %d\n", curr->number));
|
||||
return false;
|
||||
}
|
||||
if (curr->start < prev->start + prev->length) {
|
||||
D(bug("unexpected start %d\n", curr->start));
|
||||
return false;
|
||||
}
|
||||
|
||||
cs->tcnt++;
|
||||
return true;
|
||||
}
|
||||
|
||||
static bool ParseCueSheet(FILE *fh, CueSheet *cs, const char *cuefile)
|
||||
{
|
||||
bool seen1st = false;
|
||||
char line[MAXLINE];
|
||||
unsigned int i_line=0;
|
||||
char *keyword;
|
||||
|
||||
totalPregap = 0;
|
||||
prestart = 0;
|
||||
|
||||
while (fgets(line, MAXLINE, fh) != NULL) {
|
||||
Track *curr = &cs->tracks[cs->tcnt];
|
||||
|
||||
// check for CUE file
|
||||
|
||||
if (!i_line && (strncmp("FILE", line, 4) != 0)) {
|
||||
return false;
|
||||
}
|
||||
i_line++;
|
||||
|
||||
// extract keyword
|
||||
|
||||
if (NULL != (keyword = strtok(line, " \t\n\t"))) {
|
||||
if (!strcmp("FILE", keyword)) {
|
||||
char *filename;
|
||||
char *filetype;
|
||||
|
||||
if (i_line > 1) {
|
||||
D(bug("More than one FILE token\n"));
|
||||
goto fail;
|
||||
}
|
||||
filename = strtok(NULL, "\"\t\n\r");
|
||||
filetype = strtok(NULL, " \"\t\n\r");
|
||||
if (strcmp("BINARY", filetype)) {
|
||||
D(bug("Not binary file %s", filetype));
|
||||
goto fail;
|
||||
}
|
||||
else {
|
||||
char *tmp = strdup(cuefile);
|
||||
char *b = dirname(tmp);
|
||||
cs->binfile = (char *) malloc(strlen(b) + strlen(filename) + 2);
|
||||
sprintf(cs->binfile, "%s/%s", b, filename);
|
||||
free(tmp);
|
||||
}
|
||||
} else if (!strcmp("TRACK", keyword)) {
|
||||
char *field;
|
||||
int i_track;
|
||||
|
||||
if (seen1st) {
|
||||
if (!AddTrack(cs)){
|
||||
D(bug("AddTrack failed \n"));
|
||||
goto fail;
|
||||
}
|
||||
curr = &cs->tracks[cs->tcnt];
|
||||
}
|
||||
|
||||
seen1st = true;
|
||||
|
||||
// parse track number
|
||||
|
||||
field = strtok(NULL, " \t\n\r");
|
||||
if (1 != sscanf(field, "%d", &i_track)) {
|
||||
D(bug("Expected track number\n"));
|
||||
goto fail;
|
||||
}
|
||||
curr->number = i_track;
|
||||
|
||||
// parse track type
|
||||
|
||||
field = strtok(NULL, " \t\n\r");
|
||||
if (!strcmp("MODE1/2352", field)) {
|
||||
curr->tcf = DATA;
|
||||
} else if (!strcmp("AUDIO", field)) {
|
||||
curr->tcf = AUDIO;
|
||||
} else {
|
||||
D(bug("Unexpected track type %s", field));
|
||||
goto fail;
|
||||
}
|
||||
|
||||
} else if (!strcmp("INDEX", keyword)) {
|
||||
char *field;
|
||||
int i_index;
|
||||
MSF msf;
|
||||
|
||||
// parse INDEX number
|
||||
|
||||
field = strtok(NULL, " \t\n\r");
|
||||
if (1 != sscanf(field, "%d", &i_index)) {
|
||||
D(bug("Expected index number"));
|
||||
goto fail;
|
||||
}
|
||||
|
||||
// parse INDEX start
|
||||
|
||||
field = strtok(NULL, " \t\n\r");
|
||||
if (3 != sscanf(field, "%d:%d:%d",
|
||||
&msf.m, &msf.s, &msf.f)) {
|
||||
D(bug("Expected index start frame\n"));
|
||||
goto fail;
|
||||
}
|
||||
|
||||
if (i_index == 1)
|
||||
curr->start = MSFToFrames(msf);
|
||||
else if (i_index == 0)
|
||||
prestart = MSFToFrames(msf);
|
||||
} else if (!strcmp("PREGAP", keyword)) {
|
||||
MSF msf;
|
||||
char *field = strtok(NULL, " \t\n\r");
|
||||
if (3 != sscanf(field, "%d:%d:%d",
|
||||
&msf.m, &msf.s, &msf.f)) {
|
||||
D(bug("Expected pregap frame\n"));
|
||||
goto fail;
|
||||
}
|
||||
curr->pregap = MSFToFrames(msf);
|
||||
|
||||
// Ignored directives
|
||||
|
||||
} else if (!strcmp("TITLE", keyword)) {
|
||||
} else if (!strcmp("PERFORMER", keyword)) {
|
||||
} else if (!strcmp("REM", keyword)) {
|
||||
} else if (!strcmp("ISRC", keyword)) {
|
||||
} else if (!strcmp("SONGWRITER", keyword)) {
|
||||
} else {
|
||||
D(bug("Unexpected keyword %s\n", keyword));
|
||||
goto fail;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
AddTrack(cs); // add final track
|
||||
return true;
|
||||
fail:
|
||||
return false;
|
||||
}
|
||||
|
||||
static bool LoadCueSheet(const char *cuefile, CueSheet *cs)
|
||||
{
|
||||
FILE *fh = NULL;
|
||||
int binfh = -1;
|
||||
struct stat buf;
|
||||
Track *tlast = NULL;
|
||||
|
||||
if (cs) {
|
||||
bzero(cs, sizeof(*cs));
|
||||
if (!(fh = fopen(cuefile, "r")))
|
||||
return false;
|
||||
|
||||
if (!ParseCueSheet(fh, cs, cuefile)) goto fail;
|
||||
|
||||
// Open bin file and find length
|
||||
|
||||
if ((binfh = open(cs->binfile,O_RDONLY)) < 0) {
|
||||
D(bug("Can't read bin file %s\n", cs->binfile));
|
||||
goto fail;
|
||||
}
|
||||
|
||||
if (fstat(binfh, &buf)) {
|
||||
D(bug("fstat returned error\n"));
|
||||
goto fail;
|
||||
}
|
||||
|
||||
// compute length of final track
|
||||
|
||||
|
||||
tlast = &cs->tracks[cs->tcnt - 1];
|
||||
tlast->length = buf.st_size/RAW_SECTOR_SIZE
|
||||
- tlast->start + totalPregap;
|
||||
|
||||
if (tlast->length < 0) {
|
||||
D(bug("Binary file too short \n"));
|
||||
goto fail;
|
||||
}
|
||||
|
||||
// save bin file length and pointer
|
||||
|
||||
cs->length = buf.st_size/RAW_SECTOR_SIZE;
|
||||
cs->binfh = binfh;
|
||||
|
||||
fclose(fh);
|
||||
return true;
|
||||
|
||||
fail:
|
||||
if (binfh >= 0)
|
||||
close(binfh);
|
||||
fclose(fh);
|
||||
free(cs->binfile);
|
||||
return false;
|
||||
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
|
||||
void *open_bincue(const char *name)
|
||||
{
|
||||
CueSheet *cs;
|
||||
|
||||
if (player.cs == NULL) {
|
||||
cs = (CueSheet *) malloc(sizeof(CueSheet));
|
||||
if (!cs) {
|
||||
D(bug("malloc failed\n"));
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (LoadCueSheet(name, cs)) {
|
||||
player.cs = cs;
|
||||
#ifdef OSX_CORE_AUDIO
|
||||
audio_enabled = true;
|
||||
#endif
|
||||
if (audio_enabled)
|
||||
player.audiostatus = CDROM_AUDIO_NO_STATUS;
|
||||
else
|
||||
player.audiostatus = CDROM_AUDIO_INVALID;
|
||||
player.audiofh = dup(cs->binfh);
|
||||
return cs;
|
||||
}
|
||||
else
|
||||
free(cs);
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
void close_bincue(void *fh)
|
||||
{
|
||||
|
||||
|
||||
}
|
||||
|
||||
/*
|
||||
* File read (cooked)
|
||||
* Data are stored in raw sectors of which only COOKED_SECTOR_SIZE
|
||||
* bytes are valid -- the remaining include 16 bytes at the beginning
|
||||
* of each raw sector and RAW_SECTOR_SIZE - COOKED_SECTOR_SIZE - bytes
|
||||
* at the end
|
||||
*
|
||||
* We assume that a read request can land in the middle of
|
||||
* sector. We compute the byte address of that sector (sec)
|
||||
* and the offset of the first byte we want within that sector (secoff)
|
||||
*
|
||||
* Reading is performed one raw sector at a time, extracting as many
|
||||
* valid bytes as possible from that raw sector (available)
|
||||
*/
|
||||
|
||||
size_t read_bincue(void *fh, void *b, loff_t offset, size_t len)
|
||||
{
|
||||
size_t bytes_read = 0; // bytes read so far
|
||||
unsigned char *buf = (unsigned char *) b; // target buffer
|
||||
unsigned char secbuf[RAW_SECTOR_SIZE]; // temporary buffer
|
||||
|
||||
off_t sec = ((offset/COOKED_SECTOR_SIZE) * RAW_SECTOR_SIZE);
|
||||
off_t secoff = offset % COOKED_SECTOR_SIZE;
|
||||
|
||||
// sec contains location (in bytes) of next raw sector to read
|
||||
// secoff contains offset within that sector at which to start
|
||||
// reading since we can request a read that starts in the middle
|
||||
// of a sector
|
||||
|
||||
CueSheet *cs = (CueSheet *) fh;
|
||||
|
||||
if (cs == NULL || lseek(cs->binfh, sec, SEEK_SET) < 0) {
|
||||
return -1;
|
||||
}
|
||||
while (len) {
|
||||
|
||||
// bytes available in next raw sector or len (bytes)
|
||||
// we want whichever is less
|
||||
|
||||
size_t available = COOKED_SECTOR_SIZE - secoff;
|
||||
available = (available > len) ? len : available;
|
||||
|
||||
// read the next raw sector
|
||||
|
||||
if (read(cs->binfh, secbuf, RAW_SECTOR_SIZE) != RAW_SECTOR_SIZE) {
|
||||
return bytes_read;
|
||||
}
|
||||
|
||||
// copy cooked sector bytes (skip first 16)
|
||||
// we want out of those available
|
||||
|
||||
bcopy(&secbuf[16+secoff], &buf[bytes_read], available);
|
||||
|
||||
// next sector we start at the beginning
|
||||
|
||||
secoff = 0;
|
||||
|
||||
// increment running count decrement request
|
||||
|
||||
bytes_read += available;
|
||||
len -= available;
|
||||
}
|
||||
return bytes_read;
|
||||
}
|
||||
|
||||
loff_t size_bincue(void *fh)
|
||||
{
|
||||
if (fh) {
|
||||
return ((CueSheet *)fh)->length * COOKED_SECTOR_SIZE;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
bool readtoc_bincue(void *fh, unsigned char *toc)
|
||||
{
|
||||
CueSheet *cs = (CueSheet *) fh;
|
||||
if (cs) {
|
||||
|
||||
MSF msf;
|
||||
unsigned char *p = toc + 2;
|
||||
*p++ = cs->tracks[0].number;
|
||||
*p++ = cs->tracks[cs->tcnt - 1].number;
|
||||
for (int i = 0; i < cs->tcnt; i++) {
|
||||
|
||||
FramesToMSF(cs->tracks[i].start, &msf);
|
||||
*p++ = 0;
|
||||
*p++ = 0x10 | cs->tracks[i].tcf;
|
||||
*p++ = cs->tracks[i].number;
|
||||
*p++ = 0;
|
||||
*p++ = 0;
|
||||
*p++ = msf.m;
|
||||
*p++ = msf.s;
|
||||
*p++ = msf.f;
|
||||
}
|
||||
FramesToMSF(cs->length, &msf);
|
||||
*p++ = 0;
|
||||
*p++ = 0x14;
|
||||
*p++ = 0xAA;
|
||||
*p++ = 0;
|
||||
*p++ = 0;
|
||||
*p++ = msf.m;
|
||||
*p++ = msf.s;
|
||||
*p++ = msf.f;
|
||||
|
||||
int toc_size = p - toc;
|
||||
*toc++ = toc_size >> 8;
|
||||
*toc++ = toc_size & 0xff;
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
bool GetPosition_bincue(void *fh, uint8 *pos)
|
||||
{
|
||||
CueSheet *cs = (CueSheet *) fh;
|
||||
if (cs && player.cs == cs) {
|
||||
MSF abs, rel;
|
||||
int fpos = player.audioposition / RAW_SECTOR_SIZE + player.audiostart;
|
||||
int trackno = PositionToTrack(cs, fpos);
|
||||
|
||||
if (!audio_enabled)
|
||||
return false;
|
||||
|
||||
FramesToMSF(fpos, &abs);
|
||||
if (trackno < cs->tcnt) {
|
||||
// compute position relative to start of frame
|
||||
|
||||
unsigned int position = player.audioposition/RAW_SECTOR_SIZE +
|
||||
player.audiostart - player.cs->tracks[trackno].start;
|
||||
|
||||
FramesToMSF(position, &rel);
|
||||
}
|
||||
else
|
||||
FramesToMSF(0, &rel);
|
||||
|
||||
*pos++ = 0;
|
||||
*pos++ = player.audiostatus;
|
||||
*pos++ = 0;
|
||||
*pos++ = 12; // Sub-Q data length
|
||||
*pos++ = 0;
|
||||
if (trackno < cs->tcnt)
|
||||
*pos++ = 0x10 | cs->tracks[trackno].tcf;
|
||||
*pos++ = (trackno < cs->tcnt) ? cs->tracks[trackno].number : 0xAA;
|
||||
*pos++ = 1; // track index
|
||||
*pos++ = 0;
|
||||
*pos++ = abs.m;
|
||||
*pos++ = abs.s;
|
||||
*pos++ = abs.f;
|
||||
*pos++ = 0;
|
||||
*pos++ = rel.m;
|
||||
*pos++ = rel.s;
|
||||
*pos++ = rel.f;
|
||||
*pos++ = 0;
|
||||
// D(bug("CDROM position %02d:%02d:%02d track %02d\n", abs.m, abs.s, abs.f, trackno));
|
||||
return true;
|
||||
}
|
||||
else
|
||||
return false;
|
||||
}
|
||||
|
||||
bool CDPause_bincue(void *fh)
|
||||
{
|
||||
CueSheet *cs = (CueSheet *) fh;
|
||||
if (cs && cs == player.cs) {
|
||||
if (player.audiostatus == CDROM_AUDIO_PLAY) {
|
||||
player.audiostatus = CDROM_AUDIO_PAUSED;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
bool CDStop_bincue(void *fh)
|
||||
{
|
||||
CueSheet *cs = (CueSheet *) fh;
|
||||
|
||||
if (cs && cs == player.cs) {
|
||||
#ifdef OSX_CORE_AUDIO
|
||||
player.soundoutput.stop();
|
||||
#endif
|
||||
if (player.audiostatus != CDROM_AUDIO_INVALID)
|
||||
player.audiostatus = CDROM_AUDIO_NO_STATUS;
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
bool CDResume_bincue(void *fh)
|
||||
{
|
||||
CueSheet *cs = (CueSheet *) fh;
|
||||
if (cs && cs == player.cs) {
|
||||
if (player.audiostatus == CDROM_AUDIO_PAUSED) {
|
||||
player.audiostatus = CDROM_AUDIO_PLAY;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
bool CDPlay_bincue(void *fh, uint8 start_m, uint8 start_s, uint8 start_f,
|
||||
uint8 end_m, uint8 end_s, uint8 end_f)
|
||||
{
|
||||
CueSheet *cs = (CueSheet *)fh;
|
||||
if (cs && cs == player.cs) {
|
||||
int track;
|
||||
MSF msf;
|
||||
|
||||
#ifdef USE_SDL_AUDIO
|
||||
SDL_LockAudio();
|
||||
#endif
|
||||
|
||||
player.audiostatus = CDROM_AUDIO_NO_STATUS;
|
||||
|
||||
player.audiostart = (start_m * 60 * CD_FRAMES) +
|
||||
(start_s * CD_FRAMES) + start_f;
|
||||
player.audioend = (end_m * 60 * CD_FRAMES) + (end_s * CD_FRAMES) + end_f;
|
||||
|
||||
track = PositionToTrack(player.cs, player.audiostart);
|
||||
|
||||
if (track < player.cs->tcnt) {
|
||||
player.audioposition = 0;
|
||||
|
||||
// here we need to compute silence
|
||||
|
||||
if (player.audiostart - player.cs->tracks[track].start >
|
||||
player.cs->tracks[track].pregap)
|
||||
player.silence = 0;
|
||||
else
|
||||
player.silence = (player.cs->tracks[track].pregap -
|
||||
player.audiostart +
|
||||
player.cs->tracks[track].start) * RAW_SECTOR_SIZE;
|
||||
|
||||
player.fileoffset = player.cs->tracks[track].fileoffset;
|
||||
|
||||
D(bug("file offset %d\n", (unsigned int) player.fileoffset));
|
||||
|
||||
// fix up file offset if beyond the silence bytes
|
||||
|
||||
if (!player.silence) // not at the beginning
|
||||
player.fileoffset += (player.audiostart -
|
||||
player.cs->tracks[track].start -
|
||||
player.cs->tracks[track].pregap) * RAW_SECTOR_SIZE;
|
||||
|
||||
FramesToMSF(player.cs->tracks[track].start, &msf);
|
||||
D(bug("CDPlay_bincue track %02d start %02d:%02d:%02d silence %d",
|
||||
player.cs->tracks[track].number, msf.m, msf.s, msf.f,
|
||||
player.silence/RAW_SECTOR_SIZE));
|
||||
D(bug(" Stop %02u:%02u:%02u\n", end_m, end_s, end_f));
|
||||
}
|
||||
else
|
||||
D(bug("CDPlay_bincue: play beyond last track !\n"));
|
||||
|
||||
#ifdef USE_SDL_AUDIO
|
||||
SDL_UnlockAudio();
|
||||
#endif
|
||||
|
||||
if (audio_enabled) {
|
||||
player.audiostatus = CDROM_AUDIO_PLAY;
|
||||
#ifdef OSX_CORE_AUDIO
|
||||
D(bug("starting os x sound"));
|
||||
player.soundoutput.setCallback(bincue_core_audio_callback);
|
||||
// should be from current track !
|
||||
player.soundoutput.start(16, 2, 44100);
|
||||
#endif
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
static uint8 *fill_buffer(int stream_len)
|
||||
{
|
||||
static uint8 *buf = 0;
|
||||
static int bufsize = 0;
|
||||
int offset = 0;
|
||||
|
||||
if (bufsize < stream_len) {
|
||||
free(buf);
|
||||
buf = (uint8 *) malloc(stream_len);
|
||||
if (buf) {
|
||||
bufsize = stream_len;
|
||||
}
|
||||
else {
|
||||
D(bug("malloc failed \n"));
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
|
||||
memset(buf, silence_byte, stream_len);
|
||||
|
||||
if (player.audiostatus == CDROM_AUDIO_PLAY) {
|
||||
int remaining_silence = player.silence - player.audioposition;
|
||||
|
||||
if (player.audiostart + player.audioposition/RAW_SECTOR_SIZE
|
||||
>= player.audioend) {
|
||||
player.audiostatus = CDROM_AUDIO_COMPLETED;
|
||||
return buf;
|
||||
}
|
||||
|
||||
if (remaining_silence >= stream_len) {
|
||||
player.audioposition += stream_len;
|
||||
return buf;
|
||||
}
|
||||
|
||||
if (remaining_silence > 0) {
|
||||
offset += remaining_silence;
|
||||
player.audioposition += remaining_silence;
|
||||
}
|
||||
|
||||
int ret = 0;
|
||||
int available = ((player.audioend - player.audiostart) *
|
||||
RAW_SECTOR_SIZE) - player.audioposition;
|
||||
if (available > (stream_len - offset))
|
||||
available = stream_len - offset;
|
||||
|
||||
if (lseek(player.audiofh,
|
||||
player.fileoffset + player.audioposition - player.silence,
|
||||
SEEK_SET) < 0)
|
||||
return NULL;
|
||||
|
||||
if (available < 0) {
|
||||
player.audioposition += available; // correct end !;
|
||||
available = 0;
|
||||
}
|
||||
|
||||
if ((ret = read(player.audiofh, &buf[offset], available)) >= 0) {
|
||||
player.audioposition += ret;
|
||||
offset += ret;
|
||||
available -= ret;
|
||||
}
|
||||
|
||||
while (offset < stream_len) {
|
||||
buf[offset++] = silence_byte;
|
||||
if (available-- > 0){
|
||||
player.audioposition++;
|
||||
}
|
||||
}
|
||||
}
|
||||
return buf;
|
||||
}
|
||||
|
||||
|
||||
#ifdef USE_SDL_AUDIO
|
||||
void MixAudio_bincue(uint8 *stream, int stream_len)
|
||||
{
|
||||
if (audio_enabled && (player.audiostatus == CDROM_AUDIO_PLAY)) {
|
||||
uint8 *buf = fill_buffer(stream_len);
|
||||
if (buf)
|
||||
SDL_MixAudio(stream, buf, stream_len, SDL_MIX_MAXVOLUME);
|
||||
}
|
||||
}
|
||||
|
||||
void OpenAudio_bincue(int freq, int format, int channels, uint8 silence)
|
||||
{
|
||||
if (freq == 44100 && format == AUDIO_S16MSB && channels == 2) {
|
||||
audio_enabled = true;
|
||||
silence_byte = silence;
|
||||
}
|
||||
else {
|
||||
D(bug("unexpected frequency %d , format %d, or channels %d\n",
|
||||
freq, format, channels));
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef OSX_CORE_AUDIO
|
||||
static int bincue_core_audio_callback(void)
|
||||
{
|
||||
int frames = player.soundoutput.bufferSizeFrames();
|
||||
uint8 *buf = fill_buffer(frames*4);
|
||||
|
||||
// D(bug("Audio request %d\n", stream_len));
|
||||
|
||||
player.soundoutput.sendAudioBuffer((void *) buf, (buf ? frames : 0));
|
||||
|
||||
return 1;
|
||||
}
|
||||
#endif
|
299
BasiliskII/src/Unix/color_scheme.cpp
Normal file
299
BasiliskII/src/Unix/color_scheme.cpp
Normal file
@ -0,0 +1,299 @@
|
||||
/* color_scheme.cpp - Change application theme based on D-Bus
|
||||
*
|
||||
* Copyright (C) 2022-2024 Rob Hall
|
||||
*
|
||||
* This program 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 Foundation, either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program 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 this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*
|
||||
* SPDX-License-Identifier: GPL-2.0-or-later
|
||||
*/
|
||||
|
||||
#include "color_scheme.h"
|
||||
|
||||
#if GTK_CHECK_VERSION(3, 22, 0)
|
||||
|
||||
#define APP_DARK APP_PREFERS_DARK /* 1 */
|
||||
#define APP_FORCE APP_FORCES_LIGHT /* 2 */
|
||||
#define DBUS_TIMEOUT 1000 /* Timeout for D-Bus to respond in ms */
|
||||
|
||||
#if GLIB_CHECK_VERSION(2, 72, 0)
|
||||
#define SETTING_CHANGED_SIGNAL "g-signal::SettingChanged"
|
||||
#else
|
||||
#define SETTING_CHANGED_SIGNAL "g-signal"
|
||||
#endif
|
||||
|
||||
static AppColorScheme app_scheme = APP_FORCES_LIGHT;
|
||||
static GDBusProxy *desktop_portal;
|
||||
static GtkSettings *settings;
|
||||
static gboolean init_done = FALSE;
|
||||
|
||||
static void
|
||||
set_gtk_theme (gboolean dark)
|
||||
{
|
||||
g_object_set(settings, "gtk-application-prefer-dark-theme", dark, NULL);
|
||||
}
|
||||
|
||||
/*
|
||||
* Returns the currently selected app colour scheme.
|
||||
*/
|
||||
AppColorScheme
|
||||
color_scheme_get_app_scheme (void)
|
||||
{
|
||||
return app_scheme;
|
||||
}
|
||||
|
||||
/*
|
||||
* Returns TRUE if the app is currently using the dark theme.
|
||||
*/
|
||||
gboolean
|
||||
color_scheme_is_dark_theme (void)
|
||||
{
|
||||
gboolean is_dark;
|
||||
|
||||
g_object_get (settings, "gtk-application-prefer-dark-theme", &is_dark, NULL);
|
||||
return is_dark;
|
||||
}
|
||||
|
||||
/*
|
||||
* Switches the color state of the app, no matter which color
|
||||
* is currently in use. Afterwards, the app color scheme is
|
||||
* changed to APP_FORCES_LIGHT or APP_FORCES_DARK, so changes
|
||||
* to the desktop color scheme no longer have any effect.
|
||||
*/
|
||||
gboolean
|
||||
color_scheme_toggle (void)
|
||||
{
|
||||
gboolean set_dark = !color_scheme_is_dark_theme();
|
||||
g_object_set(settings, "gtk-application-prefer-dark-theme",
|
||||
set_dark, NULL);
|
||||
|
||||
/* Change app_scheme to APP_FORCES_[DARK|LIGHT] */
|
||||
app_scheme = (AppColorScheme) (set_dark | APP_FORCE);
|
||||
|
||||
return set_dark;
|
||||
}
|
||||
|
||||
static void
|
||||
setting_changed (GDBusProxy *proxy, char *sender_name, char *signal_name,
|
||||
GVariant *parameters, gpointer user_data)
|
||||
{
|
||||
const char *namespace_;
|
||||
const char *key;
|
||||
g_autoptr (GVariant) var = NULL;
|
||||
guint32 portal_value;
|
||||
gboolean set_dark;
|
||||
|
||||
if (g_strcmp0(signal_name, "SettingChanged"))
|
||||
return;
|
||||
|
||||
g_variant_get(parameters, "(&s&sv)", &namespace_, &key, &var);
|
||||
|
||||
if (!g_strcmp0(namespace_, "org.freedesktop.appearance") &&
|
||||
!g_strcmp0(key, "color-scheme"))
|
||||
{
|
||||
g_variant_get(var, "u", &portal_value);
|
||||
set_dark = (portal_value == DESKTOP_PREFERS_DARK) ? TRUE : FALSE;
|
||||
if (!(app_scheme & APP_FORCE))
|
||||
set_gtk_theme(set_dark);
|
||||
}
|
||||
}
|
||||
|
||||
static GDBusProxy *
|
||||
portal_init (void)
|
||||
{
|
||||
GDBusProxy *portal;
|
||||
GError *error = NULL;
|
||||
|
||||
portal = g_dbus_proxy_new_for_bus_sync (G_BUS_TYPE_SESSION,
|
||||
G_DBUS_PROXY_FLAGS_NONE, NULL,
|
||||
"org.freedesktop.portal.Desktop",
|
||||
"/org/freedesktop/portal/desktop",
|
||||
"org.freedesktop.portal.Settings",
|
||||
NULL, &error);
|
||||
if (!portal)
|
||||
g_debug ("Could not access portal: %s", error->message);
|
||||
|
||||
return portal;
|
||||
}
|
||||
|
||||
static void
|
||||
set_theme (void)
|
||||
{
|
||||
DesktopColorScheme desktop_scheme;
|
||||
gboolean set_dark;
|
||||
|
||||
desktop_scheme = color_scheme_get_desktop_scheme();
|
||||
if ((app_scheme & APP_FORCE) || desktop_scheme == DESKTOP_NO_PREFERENCE)
|
||||
set_dark = (app_scheme & APP_DARK);
|
||||
else
|
||||
set_dark = (desktop_scheme == DESKTOP_PREFERS_DARK);
|
||||
|
||||
set_gtk_theme(set_dark);
|
||||
}
|
||||
|
||||
static void
|
||||
init_color_scheme_cb (GObject *object, GAsyncResult *res, gpointer user_data)
|
||||
{
|
||||
GDBusProxy *portal;
|
||||
GError *error = NULL;
|
||||
|
||||
portal = g_dbus_proxy_new_for_bus_finish(res, &error);
|
||||
|
||||
if (portal)
|
||||
{
|
||||
g_signal_connect(portal, SETTING_CHANGED_SIGNAL,
|
||||
G_CALLBACK(setting_changed), NULL);
|
||||
}
|
||||
else
|
||||
{
|
||||
g_debug("Could not access portal: %s", error->message);
|
||||
}
|
||||
init_done = TRUE;
|
||||
}
|
||||
|
||||
static void
|
||||
init_color_scheme_async (void)
|
||||
{
|
||||
static size_t init = 0;
|
||||
|
||||
if (g_once_init_enter(&init))
|
||||
{
|
||||
settings = gtk_settings_get_default();
|
||||
g_dbus_proxy_new_for_bus (G_BUS_TYPE_SESSION,
|
||||
G_DBUS_PROXY_FLAGS_NONE, NULL,
|
||||
"org.freedesktop.portal.Desktop",
|
||||
"/org/freedesktop/portal/desktop",
|
||||
"org.freedesktop.portal.Settings",
|
||||
NULL,
|
||||
(GAsyncReadyCallback)init_color_scheme_cb,
|
||||
NULL);
|
||||
g_once_init_leave(&init, 1);
|
||||
}
|
||||
set_theme();
|
||||
}
|
||||
|
||||
static gboolean
|
||||
init_color_scheme (void)
|
||||
{
|
||||
static GMutex init_mutex;
|
||||
|
||||
g_mutex_lock(&init_mutex);
|
||||
{
|
||||
if (!init_done)
|
||||
{
|
||||
settings = gtk_settings_get_default();
|
||||
desktop_portal = portal_init();
|
||||
if (desktop_portal)
|
||||
{
|
||||
g_signal_connect(desktop_portal, SETTING_CHANGED_SIGNAL,
|
||||
G_CALLBACK(setting_changed), NULL);
|
||||
}
|
||||
}
|
||||
}
|
||||
init_done = TRUE;
|
||||
g_mutex_unlock(&init_mutex);
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
/*
|
||||
* Returns the current desktop color scheme, given by
|
||||
* the org.freedesktop.portal.Settings portal. If the portal
|
||||
* is not available, DESKTOP_NO_PREFERENCE is returned.
|
||||
*/
|
||||
DesktopColorScheme
|
||||
color_scheme_get_desktop_scheme (void)
|
||||
{
|
||||
g_autoptr (GVariant) outer = NULL;
|
||||
g_autoptr (GVariant) inner = NULL;
|
||||
g_autoptr (GVariant) result = NULL;
|
||||
g_autoptr (GError) error = NULL;
|
||||
DesktopColorScheme scheme;
|
||||
|
||||
if (!init_done && !init_color_scheme())
|
||||
return DESKTOP_NO_PREFERENCE;
|
||||
|
||||
if (!desktop_portal)
|
||||
return DESKTOP_NO_PREFERENCE;
|
||||
|
||||
GVariant *call = g_variant_new("(ss)", "org.freedesktop.appearance",
|
||||
"color-scheme");
|
||||
result = g_dbus_proxy_call_sync(desktop_portal, "Read", call,
|
||||
G_DBUS_CALL_FLAGS_NONE, DBUS_TIMEOUT,
|
||||
NULL, &error);
|
||||
if (!result)
|
||||
{
|
||||
g_debug("%s", error->message);
|
||||
return DESKTOP_NO_PREFERENCE;
|
||||
}
|
||||
|
||||
g_variant_get(result, "(v)", &outer);
|
||||
g_variant_get(outer, "v", &inner);
|
||||
scheme = (DesktopColorScheme) g_variant_get_uint32(inner);
|
||||
|
||||
if (scheme > DESKTOP_PREFERS_LIGHT)
|
||||
scheme = DESKTOP_NO_PREFERENCE;
|
||||
return scheme;
|
||||
}
|
||||
|
||||
/*
|
||||
* Sets the color scheme to one of the four options.
|
||||
* Can be called once GTK has been initialised.
|
||||
* Returns FALSE if the color scheme could not be set.
|
||||
* If the return value is not needed, use color_scheme_set_async instead.
|
||||
*/
|
||||
gboolean
|
||||
color_scheme_set (AppColorScheme scheme)
|
||||
{
|
||||
gboolean set_dark;
|
||||
DesktopColorScheme desktop_scheme;
|
||||
|
||||
if (!init_done && !init_color_scheme())
|
||||
return FALSE;
|
||||
|
||||
app_scheme = scheme;
|
||||
desktop_scheme = color_scheme_get_desktop_scheme();
|
||||
|
||||
if ((app_scheme & APP_FORCE) || desktop_scheme == DESKTOP_NO_PREFERENCE)
|
||||
set_dark = (app_scheme & APP_DARK);
|
||||
else
|
||||
set_dark = (desktop_scheme == DESKTOP_PREFERS_DARK);
|
||||
|
||||
set_gtk_theme(set_dark);
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
/*
|
||||
* Sets the color scheme to one of the four options.
|
||||
* Can be called once GTK has been initialised.
|
||||
* Runs asynchronously, so preferred over color_scheme_set.
|
||||
*/
|
||||
void
|
||||
color_scheme_set_async (AppColorScheme scheme)
|
||||
{
|
||||
app_scheme = scheme;
|
||||
if (init_done)
|
||||
set_theme();
|
||||
else
|
||||
init_color_scheme_async();
|
||||
}
|
||||
|
||||
void
|
||||
color_scheme_disconnect (void)
|
||||
{
|
||||
if (desktop_portal)
|
||||
{
|
||||
g_object_unref(desktop_portal);
|
||||
}
|
||||
}
|
||||
|
||||
#endif // GTK_CHECK_VERSION
|
1756
BasiliskII/src/Unix/config.guess
vendored
1756
BasiliskII/src/Unix/config.guess
vendored
File diff suppressed because it is too large
Load Diff
2550
BasiliskII/src/Unix/config.sub
vendored
2550
BasiliskII/src/Unix/config.sub
vendored
File diff suppressed because it is too large
Load Diff
264
BasiliskII/src/Unix/configure.ac
Executable file → Normal file
264
BasiliskII/src/Unix/configure.ac
Executable file → Normal file
@ -28,7 +28,7 @@ dnl Video options.
|
||||
AC_ARG_ENABLE(xf86-dga, [ --enable-xf86-dga use the XFree86 DGA extension [default=yes]], [WANT_XF86_DGA=$enableval], [WANT_XF86_DGA=yes])
|
||||
AC_ARG_ENABLE(xf86-vidmode, [ --enable-xf86-vidmode use the XFree86 VidMode extension [default=yes]], [WANT_XF86_VIDMODE=$enableval], [WANT_XF86_VIDMODE=yes])
|
||||
AC_ARG_ENABLE(fbdev-dga, [ --enable-fbdev-dga use direct frame buffer access via /dev/fb [default=yes]], [WANT_FBDEV_DGA=$enableval], [WANT_FBDEV_DGA=yes])
|
||||
AC_ARG_ENABLE(vosf, [ --enable-vosf enable video on SEGV signals [default=yes]], [WANT_VOSF=$enableval], [WANT_VOSF=yes])
|
||||
AC_ARG_ENABLE(vosf, [ --enable-vosf enable video on SEGV signals [default=no]], [WANT_VOSF=$enableval], [WANT_VOSF=no])
|
||||
|
||||
dnl SDL options.
|
||||
AC_ARG_ENABLE(sdl-static, [ --enable-sdl-static use SDL static libraries for linking [default=no]], [WANT_SDL_STATIC=$enableval], [WANT_SDL_STATIC=no])
|
||||
@ -37,9 +37,10 @@ AC_ARG_ENABLE(sdl-audio, [ --enable-sdl-audio use SDL for audio [defau
|
||||
AC_ARG_ENABLE(sdl-framework, [ --enable-sdl-framework use SDL framework [default=no]], [WANT_SDL_FRAMEWORK=$enableval], [WANT_SDL_FRAMEWORK=no])
|
||||
AC_ARG_ENABLE(sdl-framework-prefix, [ --enable-sdl-framework-prefix=PFX default=/Library/Frameworks], [SDL_FRAMEWORK="$enableval"], [SDL_FRAMEWORK=/Library/Frameworks])
|
||||
AC_ARG_WITH(sdl1, [ --with-sdl1 use SDL 1.x, rather than SDL 2.x [default=no]], [WANT_SDL_VERSION_MAJOR=1], [])
|
||||
AC_ARG_WITH(sdl3, [ --with-sdl3 use SDL 3.x, rather than SDL 2.x [default=no]], [WANT_SDL_VERSION_MAJOR=3], [])
|
||||
|
||||
dnl JIT compiler options.
|
||||
AC_ARG_ENABLE(jit-compiler, [ --enable-jit-compiler enable JIT compiler [default=no]], [WANT_JIT=$enableval], [WANT_JIT=yes])
|
||||
AC_ARG_ENABLE(jit-compiler, [ --enable-jit-compiler enable JIT compiler [default=yes]], [WANT_JIT=$enableval], [WANT_JIT=yes])
|
||||
AC_ARG_ENABLE(jit-debug, [ --enable-jit-debug activate native code disassemblers [default=no]], [WANT_JIT_DEBUG=$enableval], [WANT_JIT_DEBUG=no])
|
||||
|
||||
dnl FPU emulation core.
|
||||
@ -73,15 +74,15 @@ AC_ARG_ENABLE(addressing,
|
||||
|
||||
dnl External packages.
|
||||
AC_ARG_WITH(esd, [ --with-esd support ESD for sound under Linux/FreeBSD [default=yes]], [WANT_ESD=$withval], [WANT_ESD=yes])
|
||||
AC_ARG_WITH(gtk, [ --with-gtk use GTK user interface [default=yes]],
|
||||
AC_ARG_WITH(gtk, [ --with-gtk use GTK 2 or 3 for user interface [default=any]],
|
||||
[case "$withval" in
|
||||
gtk1) WANT_GTK="gtk";;
|
||||
gtk|gtk2) WANT_GTK="$withval";;
|
||||
yes) WANT_GTK="gtk2 gtk";;
|
||||
*) WANT_GTK="no";;
|
||||
yes|true|any) WANT_GTK="any";;
|
||||
*3) WANT_GTK="GTK3";;
|
||||
*2) WANT_GTK="GTK2";;
|
||||
*) WANT_GTK="no";;
|
||||
esac],
|
||||
[WANT_GTK="gtk2 gtk"])
|
||||
AC_ARG_WITH(mon, [ --with-mon use mon as debugger [default=yes]], [WANT_MON=$withval], [WANT_MON=yes])
|
||||
[WANT_GTK="any"])
|
||||
AC_ARG_WITH(mon, [ --with-mon use mon as debugger [default=no]], [WANT_MON=$withval], [WANT_MON=no])
|
||||
|
||||
AC_ARG_WITH(bincue,
|
||||
AS_HELP_STRING([--with-bincue], [Allow cdrom image files in bin/cue mode]))
|
||||
@ -89,6 +90,11 @@ AC_ARG_WITH(bincue,
|
||||
AC_ARG_WITH(libvhd,
|
||||
AS_HELP_STRING([--with-libvhd], [Enable VHD disk images]))
|
||||
|
||||
AC_ARG_WITH(vdeplug,
|
||||
AS_HELP_STRING([--with-vdeplug], [Enable VDE virtual network support]),
|
||||
[],
|
||||
[with_vdeplug=yes])
|
||||
|
||||
|
||||
dnl Cross Compiling results in 'guesses' being made about the target system. These defaults are oftetimes incorrect.
|
||||
dnl The following Environment variables allow you to configure the default guess value for each option in the configure script.
|
||||
@ -213,7 +219,7 @@ if [[ "x$HAVE_I386" = "xyes" ]]; then
|
||||
fi
|
||||
|
||||
dnl Checks for programs.
|
||||
AC_PROG_CC
|
||||
AC_PROG_CC_C99
|
||||
AC_PROG_CC_C_O
|
||||
AC_PROG_CPP
|
||||
AC_PROG_CXX
|
||||
@ -326,9 +332,18 @@ if [[ "x$WANT_SDL" = "xyes" ]]; then
|
||||
dnl never got defined (bizarrely-enough). -- dludwig@pobox.com
|
||||
PKG_PROG_PKG_CONFIG
|
||||
|
||||
if [[ "x$TEMP_WANT_SDL_VERSION_MAJOR" = "x3" ]]; then
|
||||
PKG_CHECK_MODULES([sdl3], [sdl3 >= 3.0], [
|
||||
CXXFLAGS="$CXXFLAGS $sdl3_CFLAGS"
|
||||
CXXFLAGS="$CXXFLAGS `echo " $sdl3_CFLAGS" | sed -e 's/\(-I.*include\)/\1\/SDL3/'`"
|
||||
LIBS="$LIBS $sdl3_LIBS"
|
||||
WANT_SDL_VERSION_MAJOR=3
|
||||
], [
|
||||
TEMP_WANT_SDL_VERSION_MAJOR=1
|
||||
])
|
||||
fi
|
||||
if [[ "x$TEMP_WANT_SDL_VERSION_MAJOR" = "x2" ]]; then
|
||||
PKG_CHECK_MODULES([sdl2], [sdl2 >= 2.0], [
|
||||
CFLAGS="$CFLAGS $sdl2_CFLAGS"
|
||||
CXXFLAGS="$CXXFLAGS $sdl2_CFLAGS"
|
||||
LIBS="$LIBS $sdl2_LIBS"
|
||||
WANT_SDL_VERSION_MAJOR=2
|
||||
@ -369,6 +384,7 @@ AS_IF([test "x$with_bincue" = "xyes" ], [have_bincue=yes], [have_bincue=no])
|
||||
AS_IF([test "x$have_bincue" = "xyes" ], [
|
||||
if [[ "x$WANT_SDL_AUDIO" = "xyes" ]]; then
|
||||
DEFINES="$DEFINES -DBINCUE"
|
||||
CPPFLAGS="$CPPFLAGS -DBINCUE"
|
||||
AC_SUBST(USE_BINCUE, yes)
|
||||
else
|
||||
AC_MSG_ERROR([You need SDL Audio to use BINCUE support.])
|
||||
@ -444,52 +460,57 @@ if [[ "x$WANT_XF86_VIDMODE" = "xyes" ]]; then
|
||||
])
|
||||
fi
|
||||
|
||||
# Check for pkg-config macro, thanks to rdiez
|
||||
m4_ifndef([PKG_PROG_PKG_CONFIG], [m4_fatal(
|
||||
[The PKG_PROG_PKG_CONFIG macro is not available. You need to install pkg-config.]
|
||||
)])
|
||||
PKG_PROG_PKG_CONFIG
|
||||
|
||||
dnl We use GTK+ if possible.
|
||||
UISRCS=../dummy/prefs_editor_dummy.cpp
|
||||
case "x$WANT_GTK" in
|
||||
xgtk2*)
|
||||
AM_PATH_GTK_2_0(1.3.15, [
|
||||
GUI_CFLAGS="$GTK_CFLAGS"
|
||||
GUI_LIBS="$GTK_LIBS"
|
||||
WANT_GTK=gtk2
|
||||
if [[ "$WANT_GTK" = "any" -o "$WANT_GTK" = "GTK3" ]]; then
|
||||
PKG_CHECK_MODULES([GTK3], [gtk+-3.0 >= 3.14.5], [
|
||||
WANT_GTK=GTK3
|
||||
GUI_CFLAGS="$GTK3_CFLAGS"
|
||||
GUI_LIBS="$GTK3_LIBS"
|
||||
LDFLAGS="$LDFLAGS -Wl,--export-dynamic"
|
||||
AC_CHECK_PROG([ac_cv_gcr], [glib-compile-resources], [yes])
|
||||
if [[ "$ac_cv_gcr" = "yes" ]]; then
|
||||
GCR="glib-compile-resources"
|
||||
else
|
||||
AC_MSG_ERROR([glib-compile-resources not found.])
|
||||
fi
|
||||
], [
|
||||
case "x${WANT_GTK}x" in
|
||||
*gtkx)
|
||||
AC_MSG_WARN([Could not find GTK+ 2.0, trying with GTK+ 1.2.])
|
||||
WANT_GTK=gtk
|
||||
;;
|
||||
*)
|
||||
AC_MSG_WARN([Could not find GTK+, disabling user interface.])
|
||||
if [[ "$WANT_GTK" = "any" ]]; then
|
||||
AC_MSG_WARN([Could not find GTK3 (version >= 3.14.5), falling back to GTK2.])
|
||||
WANT_GTK=GTK2
|
||||
else
|
||||
AC_MSG_WARN([Could not find GTK3 (version >= 3.14.5), disabling user interface.])
|
||||
WANT_GTK=no
|
||||
;;
|
||||
esac
|
||||
fi
|
||||
])
|
||||
;;
|
||||
esac
|
||||
if [[ "x$WANT_GTK" = "xgtk" ]]; then
|
||||
AM_PATH_GTK(1.2.0, [
|
||||
GUI_CFLAGS="$GTK_CFLAGS"
|
||||
GUI_LIBS="$GTK_LIBS"
|
||||
dnl somehow, <gnome-i18n.h> would redefine gettext() to nothing if
|
||||
dnl ENABLE_NLS is not set, thusly conflicting with C++ <string> which
|
||||
dnl includes <libintl.h>
|
||||
AM_GNU_GETTEXT
|
||||
B2_PATH_GNOMEUI([
|
||||
AC_DEFINE(HAVE_GNOMEUI, 1, [Define if libgnomeui is available.])
|
||||
GUI_CFLAGS="$GUI_CFLAGS $GNOMEUI_CFLAGS"
|
||||
GUI_LIBS="$GUI_LIBS $GNOMEUI_LIBS"
|
||||
], [])
|
||||
fi
|
||||
if [[ "$WANT_GTK" = "GTK2" ]]; then
|
||||
PKG_CHECK_MODULES([GTK2], [gtk+-2.0 >= 2.6.4], [
|
||||
WANT_GTK=GTK2
|
||||
GUI_CFLAGS="$GTK2_CFLAGS"
|
||||
GUI_LIBS="$GTK2_LIBS"
|
||||
], [
|
||||
AC_MSG_WARN([Could not find GTK+, disabling user interface.])
|
||||
AC_MSG_WARN([Could not find GTK2 (version >= 2.6.4), disabling user interface.])
|
||||
WANT_GTK=no
|
||||
])
|
||||
fi
|
||||
if [[ "x$WANT_GTK" != "xno" -a "x$WANT_STANDALONE_GUI" = "xno" ]]; then
|
||||
AC_DEFINE(ENABLE_GTK, 1, [Define if using GTK.])
|
||||
UISRCS=prefs_editor_gtk.cpp
|
||||
if [[ "$WANT_GTK" = "GTK3" ]]; then
|
||||
UISRCS="prefs_editor_gtk3.cpp g_resource.cpp color_scheme.cpp"
|
||||
else
|
||||
UISRCS="prefs_editor_gtk.cpp"
|
||||
fi
|
||||
fi
|
||||
AC_SUBST(GUI_CFLAGS)
|
||||
AC_SUBST(GUI_LIBS)
|
||||
AC_SUBST(GCR)
|
||||
|
||||
dnl Build external GUI if requested.
|
||||
if [[ "$WANT_STANDALONE_GUI" != "yes" ]]; then
|
||||
@ -575,7 +596,7 @@ fi
|
||||
|
||||
dnl Checks for library functions.
|
||||
AC_CHECK_FUNCS(strdup strerror cfmakeraw)
|
||||
AC_CHECK_FUNCS(clock_gettime timer_create)
|
||||
AC_CHECK_FUNCS(clock_gettime clock_nanosleep timer_create)
|
||||
AC_CHECK_FUNCS(sigaction signal)
|
||||
AC_CHECK_FUNCS(mmap mprotect munmap)
|
||||
AC_CHECK_FUNCS(vm_allocate vm_deallocate vm_protect)
|
||||
@ -588,7 +609,8 @@ dnl Check for headers and functions related to pty support (sshpty.c)
|
||||
dnl From openssh-3.2.2p1 configure.ac
|
||||
|
||||
AC_CHECK_HEADERS(strings.h login.h sys/bsdtty.h sys/stat.h util.h pty.h)
|
||||
AC_CHECK_FUNCS(_getpty vhangup strlcpy)
|
||||
AC_SEARCH_LIBS([openpty], [util bsd])
|
||||
AC_CHECK_FUNCS(_getpty openpty vhangup strlcpy)
|
||||
|
||||
case "$host" in
|
||||
*-*-hpux10.26)
|
||||
@ -611,11 +633,13 @@ mips-sony-bsd|mips-sony-newsos4)
|
||||
;;
|
||||
*-*-darwin*)
|
||||
no_dev_ptmx=1
|
||||
LIBS="$LIBS -lstdc++"
|
||||
;;
|
||||
*-*-freebsd*)
|
||||
no_dev_ptmx=1
|
||||
;;
|
||||
*-*-netbsd*)
|
||||
no_dev_ptmx=1
|
||||
;;
|
||||
esac
|
||||
|
||||
if test ! -z "$cross_compiling" && test "x$cross_compiling" = "xyes"; then
|
||||
@ -725,6 +749,7 @@ AC_CHECK_FRAMEWORK(AppKit, [])
|
||||
AC_CHECK_FRAMEWORK(Carbon, [#include <Carbon/Carbon.h>])
|
||||
AC_CHECK_FRAMEWORK(IOKit, [#include <IOKit/IOKitLib.h>])
|
||||
AC_CHECK_FRAMEWORK(CoreFoundation, [#include <CoreFoundation/CoreFoundation.h>])
|
||||
AC_CHECK_FRAMEWORK(Metal, [])
|
||||
|
||||
dnl Select system-dependant source files.
|
||||
SERIALSRC=serial_unix.cpp
|
||||
@ -768,8 +793,11 @@ netbsd*)
|
||||
ETHERSRC=ether_unix.cpp
|
||||
;;
|
||||
solaris*)
|
||||
AUDIOSRC=Solaris/audio_solaris.cpp
|
||||
DEFINES="$DEFINES -DBSD_COMP -D_POSIX_PTHREAD_SEMANTICS"
|
||||
dnl Needed for sys/socket.h
|
||||
LIBS="$LIBS -lsocket -lnsl"
|
||||
dnl Needed for SDL2
|
||||
CXXFLAGS="$CXXFLAGS -std=c++11"
|
||||
;;
|
||||
irix*)
|
||||
AUDIOSRC=Irix/audio_irix.cpp
|
||||
@ -822,6 +850,13 @@ if [[ -n "$CAN_SLIRP" ]]; then
|
||||
fi
|
||||
AC_SUBST(SLIRP_SRCS)
|
||||
|
||||
dnl Is libvdeplug available?
|
||||
have_vdeplug=no
|
||||
AS_IF([test "x$with_vdeplug" = "xyes"], [
|
||||
have_vdeplug=yes
|
||||
AC_CHECK_LIB(vdeplug, vde_close, [], [have_vdeplug=no])
|
||||
])
|
||||
|
||||
if [[ "x$WANT_MACOSX_GUI" = "xyes" ]]; then
|
||||
CPPFLAGS="$CPPFLAGS -I../MacOSX"
|
||||
LIBS="$LIBS -framework CoreAudio -framework AudioUnit -framework AudioToolbox"
|
||||
@ -855,7 +890,7 @@ if [[ "x$WANT_SDL" = "xyes" ]]; then
|
||||
fi
|
||||
if [[ "x$WANT_SDL_VIDEO" = "xyes" ]]; then
|
||||
AC_DEFINE(USE_SDL_VIDEO, 1, [Define to enable SDL video graphics support])
|
||||
VIDEOSRCS="../SDL/video_sdl.cpp ../SDL/video_sdl2.cpp"
|
||||
VIDEOSRCS="../SDL/video_sdl.cpp ../SDL/video_sdl2.cpp ../SDL/video_sdl3.cpp "
|
||||
KEYCODES="../SDL/keycodes"
|
||||
if [[ "x$ac_cv_framework_Carbon" = "xyes" ]]; then
|
||||
AC_MSG_CHECKING([whether __LP64__ is defined])
|
||||
@ -889,13 +924,13 @@ elif [[ "x$WANT_MACOSX_GUI" != "xyes" ]]; then
|
||||
fi
|
||||
if [[ "x$WANT_SDL_AUDIO" = "xyes" ]]; then
|
||||
AC_DEFINE(USE_SDL_AUDIO, 1, [Define to enable SDL audio support])
|
||||
AUDIOSRC="../SDL/audio_sdl.cpp"
|
||||
AUDIOSRC="../SDL/audio_sdl.cpp ../SDL/audio_sdl3.cpp"
|
||||
fi
|
||||
|
||||
dnl BINCUE overrides
|
||||
|
||||
if [[ "x$have_bincue" = "xyes" ]]; then
|
||||
EXTRASYSSRCS="$EXTRASYSSRCS bincue_unix.cpp"
|
||||
EXTRASYSSRCS="$EXTRASYSSRCS bincue.cpp"
|
||||
fi
|
||||
|
||||
dnl libvhd overrides
|
||||
@ -947,6 +982,9 @@ AC_CACHE_CHECK([whether TUN/TAP is supported],
|
||||
#include <net/if.h>
|
||||
#include <net/if_tun.h>
|
||||
#endif
|
||||
#ifdef HAVE_STRING_H
|
||||
#include <string.h>
|
||||
#endif
|
||||
], [
|
||||
struct ifreq ifr;
|
||||
memset(&ifr, 0, sizeof(ifr));
|
||||
@ -1104,42 +1142,37 @@ AC_TRANSLATE_DEFINE(HAVE_MMAP_VM, "$have_mmap_vm",
|
||||
|
||||
fi dnl HAVE_MMAP_VM
|
||||
|
||||
if [[ "$OS_TYPE" != "darwin" ]]; then
|
||||
dnl Check if we can disable position-independent code
|
||||
AC_CACHE_CHECK([whether the compiler supports -no-pie],
|
||||
ac_cv_no_pie, [
|
||||
saved_LDFLAGS="$LDFLAGS"
|
||||
LDFLAGS="$LDFLAGS -no-pie"
|
||||
AC_LINK_IFELSE([AC_LANG_PROGRAM()],[
|
||||
ac_cv_no_pie="yes"],[
|
||||
ac_cv_no_pie="no"
|
||||
])
|
||||
if [[ "$ac_cv_no_pie" = "no" ]]; then
|
||||
LDFLAGS="$saved_LDFLAGS"
|
||||
fi
|
||||
])
|
||||
fi
|
||||
|
||||
dnl Check if we can modify the __PAGEZERO segment for use as Low Memory
|
||||
AC_CACHE_CHECK([whether __PAGEZERO can be Low Memory area 0x0000-0x2000],
|
||||
ac_cv_pagezero_hack, [
|
||||
ac_cv_pagezero_hack=no
|
||||
if AC_TRY_COMMAND([Darwin/testlmem.sh 0x2000]); then
|
||||
case $target_os:$target_cpu in
|
||||
darwin*:x86_64)
|
||||
ac_cv_pagezero_hack=yes
|
||||
dnl might as well skip the test for mmap-able low memory
|
||||
ac_cv_can_map_lm=no
|
||||
fi
|
||||
;;
|
||||
esac
|
||||
])
|
||||
AC_TRANSLATE_DEFINE(PAGEZERO_HACK, "$ac_cv_pagezero_hack",
|
||||
[Define if the __PAGEZERO Mach-O Low Memory Globals hack works on this system.])
|
||||
|
||||
dnl Check if we can mmap 0x2000 bytes from 0x0000
|
||||
AC_CACHE_CHECK([whether we can map Low Memory area 0x0000-0x2000],
|
||||
ac_cv_can_map_lm, [
|
||||
AC_LANG_SAVE
|
||||
AC_LANG_CPLUSPLUS
|
||||
AC_TRY_RUN([
|
||||
#include "../CrossPlatform/vm_alloc.cpp"
|
||||
int main(void) { /* returns 0 if we could map the lowmem globals */
|
||||
volatile char * lm = 0;
|
||||
if (vm_init() < 0) exit(1);
|
||||
if (vm_acquire_fixed(0, 0x2000) < 0) exit(1);
|
||||
lm[0] = 'z';
|
||||
if (vm_release((char *)lm, 0x2000) < 0) exit(1);
|
||||
vm_exit(); exit(0);
|
||||
}
|
||||
], ac_cv_can_map_lm=yes, ac_cv_can_map_lm=no,
|
||||
dnl When cross-compiling, do not assume anything.
|
||||
ac_cv_can_map_lm="$BII_CROSS_MAP_LOW_AREA"
|
||||
)
|
||||
AC_LANG_RESTORE
|
||||
]
|
||||
)
|
||||
|
||||
dnl Check signal handlers need to be reinstalled
|
||||
AC_CACHE_CHECK([whether signal handlers need to be reinstalled],
|
||||
ac_cv_signal_need_reinstall, [
|
||||
@ -1224,6 +1257,11 @@ AC_CACHE_CHECK([whether your system supports Mach exceptions],
|
||||
AC_LANG_RESTORE
|
||||
]
|
||||
)
|
||||
|
||||
case $target_os:$target_cpu in
|
||||
darwin*:arm) ac_cv_have_mach_exceptions=yes;;
|
||||
esac
|
||||
|
||||
AC_TRANSLATE_DEFINE(HAVE_MACH_EXCEPTIONS, "$ac_cv_have_mach_exceptions",
|
||||
[Define if your system supports Mach exceptions.])
|
||||
|
||||
@ -1360,6 +1398,11 @@ AC_CACHE_CHECK([whether we can skip instruction in SIGSEGV handler],
|
||||
AC_LANG_RESTORE
|
||||
]
|
||||
)
|
||||
|
||||
if [[ "$target_cpu" = "arm" -o "$target_cpu" = "aarch64" ]]; then
|
||||
ac_cv_have_skip_instruction=yes
|
||||
fi
|
||||
|
||||
AC_TRANSLATE_DEFINE(HAVE_SIGSEGV_SKIP_INSTRUCTION, "$ac_cv_have_skip_instruction",
|
||||
[Define if we can ignore the fault (instruction skipping in SIGSEGV handler).])
|
||||
|
||||
@ -1375,11 +1418,10 @@ AC_PATH_PROG([BLESS], "true")
|
||||
dnl Check for linker script support
|
||||
case $target_os:$target_cpu in
|
||||
linux*:i?86) LINKER_SCRIPT_FLAGS="-Wl,-T,ldscripts/linux-i386.ld";;
|
||||
linux*:x86_64) LINKER_SCRIPT_FLAGS="-Wl,-T,ldscripts/linux-x86_64.ld";;
|
||||
linux*:powerpc) LINKER_SCRIPT_FLAGS="-Wl,-T,ldscripts/linux-ppc.ld";;
|
||||
netbsd*:i?86) LINKER_SCRIPT_FLAGS="-Wl,-T,ldscripts/linux-i386.ld";;
|
||||
freebsd*:i?86) LINKER_SCRIPT_FLAGS="-Wl,-T,ldscripts/freebsd-i386.ld";;
|
||||
darwin*:*) LINKER_SCRIPT_FLAGS="-Wl,-seg1addr,0x78048000";;
|
||||
#darwin*:*) LINKER_SCRIPT_FLAGS="-Wl,-seg1addr,0x78048000";;
|
||||
esac
|
||||
if [[ -n "$LINKER_SCRIPT_FLAGS" ]]; then
|
||||
AC_CACHE_CHECK([whether linker script is usable],
|
||||
@ -1414,17 +1456,12 @@ else
|
||||
for am in $ADDRESSING_TEST_ORDER; do
|
||||
case $am in
|
||||
real)
|
||||
dnl Requires ability to mmap() Low Memory globals
|
||||
if [[ "x$ac_cv_can_map_lm$ac_cv_pagezero_hack" = "xnono" ]]; then
|
||||
continue
|
||||
fi
|
||||
dnl Requires VOSF screen updates
|
||||
if [[ "x$CAN_VOSF" = "xno" ]]; then
|
||||
continue
|
||||
fi
|
||||
dnl Real addressing will probably work.
|
||||
ADDRESSING_MODE="real"
|
||||
WANT_VOSF=yes dnl we can use VOSF and we need it actually
|
||||
DEFINES="$DEFINES -DREAL_ADDRESSING"
|
||||
if [[ "x$ac_cv_pagezero_hack" = "xyes" ]]; then
|
||||
BLESS=Darwin/lowmem
|
||||
@ -1436,7 +1473,6 @@ else
|
||||
dnl Requires VOSF screen updates
|
||||
if [[ "x$CAN_VOSF" = "xyes" ]]; then
|
||||
ADDRESSING_MODE="direct"
|
||||
WANT_VOSF=yes dnl we can use VOSF and we need it actually
|
||||
DEFINES="$DEFINES -DDIRECT_ADDRESSING"
|
||||
break
|
||||
fi
|
||||
@ -1459,7 +1495,15 @@ fi
|
||||
|
||||
dnl Banked Memory Addressing mode is not supported by the JIT compiler
|
||||
if [[ "x$WANT_JIT" = "xyes" -a "x$ADDRESSING_MODE" = "xmemory banks" ]]; then
|
||||
AC_MSG_ERROR([Sorry, the JIT Compiler requires Direct Addressing, at least])
|
||||
AC_MSG_WARN([The JIT Compiler requires Direct Addressing, disabling])
|
||||
WANT_JIT="no"
|
||||
fi
|
||||
|
||||
if [[ "x$OS_TYPE" = "xdarwin" ]]; then
|
||||
WANT_VOSF=no
|
||||
if [[ "$target_cpu" != "arm" ]]; then
|
||||
LDFLAGS="$LDFLAGS -Wl,-no_pie -pagezero_size 0x1000"
|
||||
fi
|
||||
fi
|
||||
|
||||
dnl Enable VOSF screen updates with this feature is requested and feasible
|
||||
@ -1635,9 +1679,15 @@ elif [[ "x$WANT_NATIVE_M68K" = "xyes" ]]; then
|
||||
CPUSRCS="asm_support.s"
|
||||
fi
|
||||
|
||||
if [[ "$target_cpu" = "arm" -o "$target_cpu" = "aarch64" ]]; then
|
||||
UAE_PATH="../uae_cpu_2021"
|
||||
else
|
||||
UAE_PATH="../uae_cpu"
|
||||
fi
|
||||
|
||||
dnl Enable JIT compiler, if possible.
|
||||
if [[ "x$WANT_JIT" = "xyes" -a "x$CAN_JIT" ]]; then
|
||||
JITSRCS="$JITSRCS ../uae_cpu/compiler/compemu_support.cpp ../uae_cpu/compiler/compemu_fpp.cpp compstbl.o cpustbl_nf.o"
|
||||
if [[ "x$WANT_JIT" = "xyes" -a "x$CAN_JIT" = "xyes" ]]; then
|
||||
JITSRCS="$JITSRCS $UAE_PATH/compiler/compemu_support.cpp $UAE_PATH/compiler/compemu_fpp.cpp compstbl.o cpustbl_nf.o"
|
||||
DEFINES="$DEFINES -DUSE_JIT -DUSE_JIT_FPU"
|
||||
|
||||
if [[ "x$WANT_JIT_DEBUG" = "xyes" ]]; then
|
||||
@ -1685,7 +1735,19 @@ cat > conftest.$ac_ext <<EOF
|
||||
#include "confdefs.h"
|
||||
$1
|
||||
]EOF
|
||||
ac_save_CFLAGS=$CFLAGS
|
||||
CFLAGS="$CFLAGS -fno-lto"
|
||||
gcc_ac_compile_ok=0
|
||||
if AC_TRY_EVAL(ac_compile); then
|
||||
gcc_ac_compile_ok=1
|
||||
else
|
||||
CFLAGS=$ac_save_CFLAGS
|
||||
if AC_TRY_EVAL(ac_compile); then
|
||||
gcc_ac_compile_ok=1
|
||||
fi
|
||||
fi
|
||||
CFLAGS=$ac_save_CFLAGS
|
||||
if test "$gcc_ac_compile_ok" = 1; then
|
||||
od -c conftest.o |
|
||||
sed ['s/^[0-7]*[ ]*/ /
|
||||
s/\*/./g
|
||||
@ -1807,9 +1869,16 @@ for fpe in $FPE_CORE_TEST_ORDER; do
|
||||
ieee)
|
||||
case $ac_cv_c_float_format in
|
||||
IEEE*)
|
||||
FPE_CORE="IEEE fpu core"
|
||||
DEFINES="$DEFINES -DFPU_IEEE"
|
||||
FPUSRCS="../uae_cpu/fpu/fpu_ieee.cpp"
|
||||
if [[ "$target_cpu" = "arm" -o "$target_cpu" = "aarch64" ]]; then
|
||||
FPE_CORE="IEEE fpu core (MPFR)"
|
||||
DEFINES="$DEFINES -DFPU_MPFR"
|
||||
FPUSRCS="$UAE_PATH/fpu/fpu_mpfr.cpp"
|
||||
LIBS="$LIBS -lmpfr -lgmp"
|
||||
else
|
||||
FPE_CORE="IEEE fpu core"
|
||||
DEFINES="$DEFINES -DFPU_IEEE"
|
||||
FPUSRCS="$UAE_PATH/fpu/fpu_ieee.cpp"
|
||||
fi
|
||||
dnl Math functions not mandated by C99 standard
|
||||
AC_CHECK_FUNCS(isnanl isinfl)
|
||||
dnl Math functions required by C99 standard, but probably not
|
||||
@ -1827,14 +1896,14 @@ for fpe in $FPE_CORE_TEST_ORDER; do
|
||||
if [[ ":$HAVE_GCC27:$HAVE_I386:$HAVE_GAS:" = ":yes:yes:yes:" ]]; then
|
||||
FPE_CORE="i387 fpu core"
|
||||
DEFINES="$DEFINES -DFPU_X86"
|
||||
FPUSRCS="../uae_cpu/fpu/fpu_x86.cpp"
|
||||
FPUSRCS="$UAE_PATH/fpu/fpu_x86.cpp"
|
||||
break
|
||||
fi
|
||||
;;
|
||||
uae)
|
||||
FPE_CORE="uae fpu core"
|
||||
DEFINES="$DEFINES -DFPU_UAE"
|
||||
FPUSRCS="../uae_cpu/fpu/fpu_uae.cpp"
|
||||
FPUSRCS="$UAE_PATH/fpu/fpu_uae.cpp"
|
||||
break
|
||||
;;
|
||||
*)
|
||||
@ -1852,8 +1921,12 @@ AC_CHECK_FUNCS(isnan isinf finite isnormal signbit)
|
||||
|
||||
dnl UAE CPU sources for all non-m68k-native architectures.
|
||||
if [[ "x$WANT_NATIVE_M68K" = "xno" ]]; then
|
||||
CPUINCLUDES="-I../uae_cpu"
|
||||
CPUSRCS="../uae_cpu/basilisk_glue.cpp ../uae_cpu/memory.cpp ../uae_cpu/newcpu.cpp ../uae_cpu/readcpu.cpp $FPUSRCS cpustbl.cpp cpudefs.cpp $CPUSRCS $JITSRCS"
|
||||
CPUINCLUDES="-I$UAE_PATH"
|
||||
CPUSRCS="$UAE_PATH/basilisk_glue.cpp $UAE_PATH/memory.cpp $UAE_PATH/newcpu.cpp $UAE_PATH/readcpu.cpp $FPUSRCS cpustbl.cpp cpudefs.cpp $CPUSRCS $JITSRCS"
|
||||
if [[ "$target_cpu" = "arm" -o "$target_cpu" = "aarch64" ]]; then
|
||||
CPUSRCS="$CPUSRCS cpufunctbl.cpp"
|
||||
DEFINES="$DEFINES -DUPDATE_UAE"
|
||||
fi
|
||||
fi
|
||||
|
||||
dnl Or if we have -IPA (MIPSPro compilers)
|
||||
@ -1864,6 +1937,9 @@ if [[ "x$HAVE_IPA" = "xyes" ]]; then
|
||||
LDFLAGS="$LDFLAGS -O3 -OPT:Olimit=0 -IPA"
|
||||
fi
|
||||
|
||||
CFLAGS="$CFLAGS -fwrapv"
|
||||
CXXFLAGS="$CXXFLAGS -fwrapv"
|
||||
|
||||
dnl Generate Makefile.
|
||||
AC_SUBST(DEFINES)
|
||||
AC_SUBST(SYSSRCS)
|
||||
@ -1871,6 +1947,7 @@ AC_SUBST(CPUINCLUDES)
|
||||
AC_SUBST(CPUSRCS)
|
||||
AC_SUBST(BLESS)
|
||||
AC_SUBST(KEYCODES)
|
||||
AC_SUBST(UAE_PATH)
|
||||
AC_CONFIG_FILES([Makefile])
|
||||
AC_OUTPUT
|
||||
|
||||
@ -1884,6 +1961,7 @@ echo SDL support ............................ : $SDL_SUPPORT
|
||||
echo SDL major-version ...................... : $WANT_SDL_VERSION_MAJOR
|
||||
echo BINCUE support ......................... : $have_bincue
|
||||
echo LIBVHD support ......................... : $have_libvhd
|
||||
echo VDE support ............................ : $have_vdeplug
|
||||
echo XFree86 DGA support .................... : $WANT_XF86_DGA
|
||||
echo XFree86 VidMode support ................ : $WANT_XF86_VIDMODE
|
||||
echo fbdev DGA support ...................... : $WANT_FBDEV_DGA
|
||||
|
@ -39,8 +39,28 @@
|
||||
#ifdef HAVE_SYS_POLL_H
|
||||
#include <sys/poll.h>
|
||||
#endif
|
||||
|
||||
#ifdef __sun__
|
||||
#define BSD_COMP 1
|
||||
#endif
|
||||
|
||||
#include <sys/ioctl.h>
|
||||
#include <sys/socket.h>
|
||||
|
||||
#ifdef ENABLE_MACOSX_ETHERHELPER
|
||||
|
||||
#ifdef __APPLE__
|
||||
#include <net/if_dl.h>
|
||||
#endif
|
||||
|
||||
#ifdef __linux__
|
||||
#include <linux/if_packet.h>
|
||||
#endif
|
||||
|
||||
#include <sys/socket.h>
|
||||
#include <ifaddrs.h>
|
||||
#endif
|
||||
|
||||
#include <sys/wait.h>
|
||||
#include <netinet/in.h>
|
||||
#include <pthread.h>
|
||||
@ -49,8 +69,9 @@
|
||||
#include <stdio.h>
|
||||
#include <signal.h>
|
||||
#include <map>
|
||||
#include <string>
|
||||
|
||||
#if defined(__FreeBSD__) || defined(sgi) || (defined(__APPLE__) && defined(__MACH__))
|
||||
#if defined(__FreeBSD__) || defined (__sun__) || defined(sgi) || (defined(__APPLE__) && defined(__MACH__))
|
||||
#include <net/if.h>
|
||||
#endif
|
||||
|
||||
@ -69,6 +90,12 @@
|
||||
#include "ctl.h"
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_LIBVDEPLUG
|
||||
extern "C" {
|
||||
#include <libvdeplug.h>
|
||||
}
|
||||
#endif
|
||||
|
||||
#include "cpu_emulation.h"
|
||||
#include "main.h"
|
||||
#include "macos_util.h"
|
||||
@ -93,9 +120,18 @@ enum {
|
||||
NET_IF_SHEEPNET,
|
||||
NET_IF_ETHERTAP,
|
||||
NET_IF_TUNTAP,
|
||||
NET_IF_SLIRP
|
||||
NET_IF_SLIRP,
|
||||
NET_IF_VDE,
|
||||
NET_IF_ETHERHELPER
|
||||
};
|
||||
|
||||
|
||||
#ifdef ENABLE_MACOSX_ETHERHELPER
|
||||
extern "C" {
|
||||
extern FILE * run_tool(const char *if_name, const char *tool_name);
|
||||
}
|
||||
#endif
|
||||
|
||||
// Constants
|
||||
#if ENABLE_TUNTAP
|
||||
static const char ETHERCONFIG_FILE_NAME[] = DATADIR "/tunconfig";
|
||||
@ -115,6 +151,9 @@ static pthread_t slirp_thread; // Slirp reception thread
|
||||
static bool slirp_thread_active = false; // Flag: Slirp reception threadinstalled
|
||||
static int slirp_output_fd = -1; // fd of slirp output pipe
|
||||
static int slirp_input_fds[2] = { -1, -1 }; // fds of slirp input pipe
|
||||
#ifdef HAVE_LIBVDEPLUG
|
||||
static VDECONN *vde_conn;
|
||||
#endif
|
||||
#ifdef SHEEPSHAVER
|
||||
static bool net_open = false; // Flag: initialization succeeded, network device open
|
||||
static uint8 ether_addr[6]; // Our Ethernet address
|
||||
@ -122,6 +161,11 @@ static uint8 ether_addr[6]; // Our Ethernet address
|
||||
const bool ether_driver_opened = true; // Flag: is the MacOS driver opened?
|
||||
#endif
|
||||
|
||||
|
||||
#ifdef ENABLE_MACOSX_ETHERHELPER
|
||||
static uint8 packet_buffer[2048];
|
||||
#endif
|
||||
|
||||
// Attached network protocols, maps protocol type to MacOS handler address
|
||||
static map<uint16, uint32> net_protocols;
|
||||
|
||||
@ -135,6 +179,11 @@ static void ether_do_interrupt(void);
|
||||
static void slirp_add_redirs();
|
||||
static int slirp_add_redir(const char *redir_str);
|
||||
|
||||
#ifdef ENABLE_MACOSX_ETHERHELPER
|
||||
static int get_mac_address(const char* dev, unsigned char *addr);
|
||||
static bool open_ether_helper(const std::string &if_name);
|
||||
static int read_packet(void);
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Start packet reception thread
|
||||
@ -235,32 +284,56 @@ bool ether_init(void)
|
||||
|
||||
// Do nothing if no Ethernet device specified
|
||||
const char *name = PrefsFindString("ether");
|
||||
#ifdef ENABLE_MACOSX_ETHERHELPER
|
||||
std::string slave_dev;
|
||||
#endif
|
||||
if (name == NULL)
|
||||
return false;
|
||||
|
||||
// Determine Ethernet device type
|
||||
net_if_type = -1;
|
||||
if (strncmp(name, "tap", 3) == 0)
|
||||
if (strncmp(name, "tap", 3) == 0) {
|
||||
net_if_type = NET_IF_ETHERTAP;
|
||||
printf("selected Ethernet device type tap\n");
|
||||
}
|
||||
#if ENABLE_TUNTAP
|
||||
else if (strcmp(name, "tun") == 0)
|
||||
else if (strcmp(name, "tun") == 0) {
|
||||
net_if_type = NET_IF_TUNTAP;
|
||||
printf("selected Ethernet device type tun\n");
|
||||
}
|
||||
#endif
|
||||
#ifdef HAVE_SLIRP
|
||||
else if (strcmp(name, "slirp") == 0)
|
||||
else if (strcmp(name, "slirp") == 0) {
|
||||
net_if_type = NET_IF_SLIRP;
|
||||
printf("selected Ethernet device type slirp\n");
|
||||
}
|
||||
#endif
|
||||
else
|
||||
#ifdef HAVE_LIBVDEPLUG
|
||||
else if (strcmp(name, "vde") == 0) {
|
||||
net_if_type = NET_IF_VDE;
|
||||
printf("selected Ethernet device type VDE\n");
|
||||
}
|
||||
#endif
|
||||
#ifdef ENABLE_MACOSX_ETHERHELPER
|
||||
else if (strncmp(name, "etherhelper", 10) == 0)
|
||||
net_if_type = NET_IF_ETHERHELPER;
|
||||
#endif
|
||||
else {
|
||||
net_if_type = NET_IF_SHEEPNET;
|
||||
printf("selected Ethernet device type sheep_net\n");
|
||||
}
|
||||
|
||||
// Don't raise SIGPIPE, let errno be set to EPIPE
|
||||
struct sigaction sigpipe_sa;
|
||||
if (sigaction(SIGPIPE, NULL, &sigpipe_sa) == 0) {
|
||||
assert(sigpipe_sa.sa_handler == SIG_DFL || sigpipe_sa.sa_handler == SIG_IGN);
|
||||
sigfillset(&sigpipe_sa.sa_mask);
|
||||
sigpipe_sa.sa_flags = 0;
|
||||
sigpipe_sa.sa_handler = SIG_IGN;
|
||||
sigaction(SIGPIPE, &sigpipe_sa, NULL);
|
||||
if (sigpipe_sa.sa_handler == SIG_DFL || sigpipe_sa.sa_handler == SIG_IGN) {
|
||||
sigfillset(&sigpipe_sa.sa_mask);
|
||||
sigpipe_sa.sa_flags = 0;
|
||||
sigpipe_sa.sa_handler = SIG_IGN;
|
||||
sigaction(SIGPIPE, &sigpipe_sa, NULL);
|
||||
}
|
||||
// If something else in the process has installed a SIGPIPE handler (SDL kmsdrm?),
|
||||
// and wants to eat our unwanted signals instead, that's fine too.
|
||||
}
|
||||
|
||||
#ifdef HAVE_SLIRP
|
||||
@ -300,8 +373,55 @@ bool ether_init(void)
|
||||
case NET_IF_SHEEPNET:
|
||||
strcpy(dev_name, "/dev/sheep_net");
|
||||
break;
|
||||
#ifdef ENABLE_MACOSX_ETHERHELPER
|
||||
case NET_IF_ETHERHELPER: {
|
||||
std::string device(name);
|
||||
size_t pos;
|
||||
|
||||
pos = device.find('/');
|
||||
if(pos != device.npos) {
|
||||
slave_dev = device.substr(pos + 1);
|
||||
}
|
||||
|
||||
if(slave_dev.size() == 0) {
|
||||
WarningAlert("No network device specified.");
|
||||
return false;
|
||||
}
|
||||
|
||||
return open_ether_helper(slave_dev);
|
||||
}
|
||||
if (net_if_type != NET_IF_SLIRP) {
|
||||
|
||||
#endif
|
||||
}
|
||||
|
||||
#ifdef HAVE_LIBVDEPLUG
|
||||
//vde switch information
|
||||
int port = 0;
|
||||
char *init_group = NULL;
|
||||
mode_t mode = 0700;
|
||||
|
||||
struct vde_open_args args = {
|
||||
.port = port,
|
||||
.group = init_group,
|
||||
.mode = mode,
|
||||
};
|
||||
|
||||
if (net_if_type == NET_IF_VDE) {
|
||||
/* calling vde open to open the vde connection to the vde switch */
|
||||
vde_conn = vde_open(vde_sock, (char *)"macemu", &args);
|
||||
|
||||
if (!vde_conn) {
|
||||
D(bug("VDE open failed\n"));
|
||||
return -1;
|
||||
} else {
|
||||
/* for select/poll when this fd receive data, there are
|
||||
* packets to recv(call vde_recv) */
|
||||
fd = vde_datafd(vde_conn);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
if (net_if_type != NET_IF_SLIRP && net_if_type != NET_IF_VDE) {
|
||||
fd = open(dev_name, O_RDWR);
|
||||
if (fd < 0) {
|
||||
sprintf(str, GetString(STR_NO_SHEEP_NET_DRIVER_WARN), dev_name, strerror(errno));
|
||||
@ -387,6 +507,15 @@ bool ether_init(void)
|
||||
ether_addr[3] = 0x12;
|
||||
ether_addr[4] = 0x34;
|
||||
ether_addr[5] = 0x56;
|
||||
#endif
|
||||
#ifdef HAVE_LIBVDEPLUG
|
||||
} else if (net_if_type == NET_IF_VDE) {
|
||||
ether_addr[0] = 0x52;
|
||||
ether_addr[1] = 0x54;
|
||||
ether_addr[2] = 0x00;
|
||||
ether_addr[3] = 0x12;
|
||||
ether_addr[4] = 0x34;
|
||||
ether_addr[5] = 0x56;
|
||||
#endif
|
||||
} else
|
||||
ioctl(fd, SIOCGIFADDR, ether_addr);
|
||||
@ -453,6 +582,11 @@ void ether_exit(void)
|
||||
if (slirp_output_fd > 0)
|
||||
close(slirp_output_fd);
|
||||
|
||||
#ifdef HAVE_LIBVDEPLUG
|
||||
// Close vde_connection
|
||||
if (net_if_type == NET_IF_VDE)
|
||||
vde_close(vde_conn);
|
||||
#endif
|
||||
#if STATISTICS
|
||||
// Show statistics
|
||||
printf("%ld messages put on write queue\n", num_wput);
|
||||
@ -750,6 +884,40 @@ static int16 ether_do_write(uint32 arg)
|
||||
write(slirp_input_fd, packet, len);
|
||||
return noErr;
|
||||
} else
|
||||
#endif
|
||||
#ifdef HAVE_LIBVDEPLUG
|
||||
if (net_if_type == NET_IF_VDE) {
|
||||
if (fd == -1) { // which means vde service is not running
|
||||
D(bug("WARNING: Couldn't transmit VDE packet\n"));
|
||||
return excessCollsns;
|
||||
}
|
||||
|
||||
if (vde_conn == NULL) {
|
||||
D(bug("WARNING: vde_conn is NULL\n"));
|
||||
return -1;
|
||||
}
|
||||
|
||||
do {
|
||||
len = vde_send(vde_conn, packet, sizeof(packet), 0);
|
||||
} while (len < 0);
|
||||
|
||||
return noErr;
|
||||
} else
|
||||
#endif
|
||||
#ifdef ENABLE_MACOSX_ETHERHELPER
|
||||
if (net_if_type == NET_IF_ETHERHELPER) {
|
||||
unsigned short pkt_len;
|
||||
|
||||
pkt_len = len;
|
||||
if (write(fd, &pkt_len, 2) < 2) {
|
||||
return excessCollsns;
|
||||
}
|
||||
|
||||
if (write(fd, packet, len) < len) {
|
||||
return excessCollsns;
|
||||
}
|
||||
return noErr;
|
||||
} else
|
||||
#endif
|
||||
if (write(fd, packet, len) < 0) {
|
||||
D(bug("WARNING: Couldn't transmit packet\n"));
|
||||
@ -884,6 +1052,13 @@ static void *receive_func(void *arg)
|
||||
if (res <= 0)
|
||||
break;
|
||||
|
||||
#ifdef ENABLE_MACOSX_ETHERHELPER
|
||||
if (net_if_type == NET_IF_ETHERHELPER) {
|
||||
if (read_packet() < 1) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
if (ether_driver_opened) {
|
||||
// Trigger Ethernet interrupt
|
||||
D(bug(" packet received, triggering Ethernet interrupt\n"));
|
||||
@ -924,14 +1099,33 @@ void ether_do_interrupt(void)
|
||||
|
||||
} else
|
||||
#endif
|
||||
{
|
||||
#ifdef ENABLE_MACOSX_ETHERHELPER
|
||||
if (net_if_type == NET_IF_ETHERHELPER) {
|
||||
unsigned short *pkt_len;
|
||||
uint32 p = packet;
|
||||
|
||||
// Read packet from sheep_net device
|
||||
#if defined(__linux__)
|
||||
length = read(fd, Mac2HostAddr(packet), net_if_type == NET_IF_ETHERTAP ? 1516 : 1514);
|
||||
#else
|
||||
length = read(fd, Mac2HostAddr(packet), 1514);
|
||||
pkt_len = (unsigned short *)packet_buffer;
|
||||
length = *pkt_len;
|
||||
memcpy(Mac2HostAddr(packet), pkt_len + 1, length);
|
||||
ether_dispatch_packet(p, length);
|
||||
break;
|
||||
} else
|
||||
#endif
|
||||
{
|
||||
#ifdef HAVE_LIBVDEPLUG
|
||||
if (net_if_type == NET_IF_VDE) {
|
||||
length = vde_recv(vde_conn, Mac2HostAddr(packet), 1514, 0);
|
||||
} else
|
||||
#endif
|
||||
{
|
||||
// Read packet from sheep_net device
|
||||
#if defined(__linux__)
|
||||
length = read(fd, Mac2HostAddr(packet), net_if_type == NET_IF_ETHERTAP ? 1516 : 1514);
|
||||
#else
|
||||
length = read(fd, Mac2HostAddr(packet), 1514);
|
||||
#endif
|
||||
}
|
||||
|
||||
if (length < 14)
|
||||
break;
|
||||
|
||||
@ -1049,3 +1243,144 @@ static int slirp_add_redir(const char *redir_str)
|
||||
WarningAlert(str);
|
||||
return -1;
|
||||
}
|
||||
|
||||
#ifdef ENABLE_MACOSX_ETHERHELPER
|
||||
static int get_mac_address(const char* dev, unsigned char *addr)
|
||||
{
|
||||
struct ifaddrs *ifaddrs, *next;
|
||||
int ret = -1;
|
||||
#ifdef __APPLE__
|
||||
struct sockaddr_dl *sa;
|
||||
#endif
|
||||
|
||||
#ifdef __linux__
|
||||
struct sockaddr_ll *sa;
|
||||
#endif
|
||||
if (getifaddrs(&ifaddrs) != 0) {
|
||||
perror("getifaddrs");
|
||||
return -1;
|
||||
}
|
||||
|
||||
next = ifaddrs;
|
||||
while (next != NULL) {
|
||||
switch (next->ifa_addr->sa_family) {
|
||||
#ifdef __APPLE__
|
||||
case AF_LINK:
|
||||
if (!strcmp(dev, next->ifa_name)) {
|
||||
sa = (struct sockaddr_dl *)next->ifa_addr;
|
||||
memcpy(addr, LLADDR(sa), 6);
|
||||
ret = 0;
|
||||
}
|
||||
break;
|
||||
#endif
|
||||
|
||||
#ifdef __linux__
|
||||
case AF_PACKET:
|
||||
if (!strcmp(dev, next->ifa_name)) {
|
||||
sa = (struct sockaddr_ll *)next->ifa_addr;
|
||||
memcpy(addr, sa->sll_addr, 6);
|
||||
ret = 0;
|
||||
}
|
||||
break;
|
||||
#endif
|
||||
default:
|
||||
break;
|
||||
}
|
||||
next = next->ifa_next;
|
||||
}
|
||||
|
||||
freeifaddrs(ifaddrs);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static bool open_ether_helper(const std::string &if_name)
|
||||
{
|
||||
FILE *fp;
|
||||
char str[64];
|
||||
std::string dev_name;
|
||||
size_t pos;
|
||||
|
||||
fp = run_tool(if_name.c_str(), "etherhelpertool");
|
||||
if (fp == NULL) {
|
||||
snprintf(str, sizeof(str), "Unable to run ether helper helper tool.");
|
||||
WarningAlert(str);
|
||||
return false;
|
||||
}
|
||||
|
||||
pos = if_name.find('/');
|
||||
dev_name = if_name;
|
||||
if(pos != if_name.npos) {
|
||||
dev_name.erase(pos);
|
||||
}
|
||||
|
||||
if(strncmp(if_name.c_str(), "tap", 3) != 0) {
|
||||
if (get_mac_address(dev_name.c_str(), ether_addr) != 0) {
|
||||
snprintf(str, sizeof(str), "Unable to find interface %s.",
|
||||
dev_name.c_str());
|
||||
WarningAlert(str);
|
||||
return false;
|
||||
}
|
||||
} else {
|
||||
/* There is something special about this address. */
|
||||
pid_t p = getpid();
|
||||
ether_addr[0] = 0xfe;
|
||||
ether_addr[1] = 0xfd;
|
||||
ether_addr[2] = p >> 24;
|
||||
ether_addr[3] = p >> 16;
|
||||
ether_addr[4] = p >> 8;
|
||||
ether_addr[5] = p;
|
||||
}
|
||||
|
||||
fd = dup(fileno(fp));
|
||||
fclose(fp);
|
||||
|
||||
if (start_thread() == false) {
|
||||
close(fd);
|
||||
fd = -1;
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
static int read_packet()
|
||||
{
|
||||
int index;
|
||||
unsigned short *pkt_len;
|
||||
int ret = -1;
|
||||
|
||||
pkt_len = (unsigned short *)packet_buffer;
|
||||
|
||||
index = 0;
|
||||
while (1) {
|
||||
if (index < 2) {
|
||||
ret = read(fd, packet_buffer + index, 2 - index);
|
||||
} else {
|
||||
ret = read(fd, packet_buffer + index, *pkt_len - index + 2);
|
||||
}
|
||||
|
||||
if (ret < 1) {
|
||||
fprintf(stderr, "%s: read() returned %d.\n", __func__, ret);
|
||||
break;
|
||||
}
|
||||
|
||||
index += ret;
|
||||
|
||||
if (index > 1) {
|
||||
if (*pkt_len > (sizeof(packet_buffer) + 2)) {
|
||||
fprintf(stderr, "%s: pkt_len (%d) too large.\n", __func__, *pkt_len);
|
||||
break;
|
||||
}
|
||||
|
||||
if (index == (*pkt_len + 2)) {
|
||||
ret = *pkt_len;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
@ -2,29 +2,696 @@
|
||||
#
|
||||
# Basilisk II (C) 1997-2005 Christian Bauer
|
||||
#
|
||||
# This file is used to translate the (server-specific) X11 keycodes to Mac
|
||||
# keycodes depending on the X11 server being used.
|
||||
# This file is used to translate the (server-specific) scancodes to
|
||||
# Mac keycodes depending on the window server being used.
|
||||
#
|
||||
# The format of this file is as follows:
|
||||
#
|
||||
# sdl <driver string>
|
||||
# <SDL scancode> <Mac keycode>
|
||||
# <SDL scancode> <Mac keycode>
|
||||
# <SDL scancode> <Mac keycode>
|
||||
# ...
|
||||
# <vendor string>
|
||||
# <X11 keycode> <Mac keycode>
|
||||
# <X11 keycode> <Mac keycode>
|
||||
# <X11 keycode> <Mac keycode>
|
||||
# ...
|
||||
# <vendor string>
|
||||
# <X11 keycode> <Mac keycode>
|
||||
# <X11 keycode> <Mac keycode>
|
||||
# ...
|
||||
#
|
||||
# The "vendor string" must match the first part of the X11 server vendor
|
||||
# description as reported by ServerVendor(). If a match is found, the keycode
|
||||
# translation table is constructed from the following lines. Each line
|
||||
# contains an X11 keycode followed by its associated Mac keycode. Both
|
||||
# keycodes have to be given in decimal. Lines beginning with "#" or ";" are
|
||||
# treated as comments and ignored.
|
||||
# The "driver string" must match the first part of the SDL driver
|
||||
# vendor description as reported by SDL_VideoDriverName(), while the
|
||||
# "vendor string" must match the first part of the X11 server vendor
|
||||
# description as reported by ServerVendor(). If a match is found,
|
||||
# the keycode translation table is constructed from the following
|
||||
# lines. Each line contains an SDL scancode or X11 keycode followed
|
||||
# by its associated Mac keycode. Both keycodes have to be given in
|
||||
# decimal. Lines beginning with "#" or ";" are treated as comments
|
||||
# and ignored.
|
||||
#
|
||||
|
||||
#
|
||||
# X11 server
|
||||
# X.Org
|
||||
# Wayland
|
||||
#
|
||||
sdl x11
|
||||
sdl wayland
|
||||
sdl dga
|
||||
The X.Org Foundation
|
||||
9 53 # Esc
|
||||
67 122 # F1
|
||||
68 120 # F2
|
||||
69 99 # F3
|
||||
70 118 # F4
|
||||
71 96 # F5
|
||||
72 97 # F6
|
||||
73 98 # F7
|
||||
74 100 # F8
|
||||
75 101 # F9
|
||||
76 109 # F10
|
||||
95 103 # F11
|
||||
96 111 # F12
|
||||
111 105 # PrintScrn
|
||||
78 107 # Scroll Lock
|
||||
110 113 # Pause
|
||||
49 50 # `
|
||||
10 18 # 1
|
||||
11 19 # 2
|
||||
12 20 # 3
|
||||
13 21 # 4
|
||||
14 23 # 5
|
||||
15 22 # 6
|
||||
16 26 # 7
|
||||
17 28 # 8
|
||||
18 25 # 9
|
||||
19 29 # 0
|
||||
20 27 # -
|
||||
21 24 # =
|
||||
22 51 # Backspace
|
||||
106 114 # Insert
|
||||
97 115 # Home
|
||||
99 116 # Page Up
|
||||
77 71 # Num Lock
|
||||
112 75 # KP /
|
||||
63 67 # KP *
|
||||
82 78 # KP -
|
||||
23 48 # Tab
|
||||
24 12 # Q
|
||||
25 13 # W
|
||||
26 14 # E
|
||||
27 15 # R
|
||||
28 17 # T
|
||||
29 16 # Y
|
||||
30 32 # U
|
||||
31 34 # I
|
||||
32 31 # O
|
||||
33 35 # P
|
||||
34 33 # [
|
||||
35 30 # ]
|
||||
36 36 # Return
|
||||
107 117 # Delete
|
||||
103 119 # End
|
||||
105 121 # Page Down
|
||||
79 89 # KP 7
|
||||
80 91 # KP 8
|
||||
81 92 # KP 9
|
||||
86 69 # KP +
|
||||
66 57 # Caps Lock
|
||||
38 0 # A
|
||||
39 1 # S
|
||||
40 2 # D
|
||||
41 3 # F
|
||||
42 5 # G
|
||||
43 4 # H
|
||||
44 38 # J
|
||||
45 40 # K
|
||||
46 37 # L
|
||||
47 41 # ;
|
||||
48 39 # '
|
||||
83 86 # KP 4
|
||||
84 87 # KP 5
|
||||
85 88 # KP 6
|
||||
50 56 # Shift Left
|
||||
94 50 # International
|
||||
52 6 # Z
|
||||
53 7 # X
|
||||
54 8 # C
|
||||
55 9 # V
|
||||
56 11 # B
|
||||
57 45 # N
|
||||
58 46 # M
|
||||
59 43 # ,
|
||||
60 47 # .
|
||||
61 44 # /
|
||||
62 56 # Shift Right
|
||||
51 42 # \
|
||||
98 62 # Cursor Up
|
||||
87 83 # KP 1
|
||||
88 84 # KP 2
|
||||
89 85 # KP 3
|
||||
108 76 # KP Enter
|
||||
37 54 # Ctrl Left
|
||||
115 58 # Logo Left (-> Option)
|
||||
64 55 # Alt Left (-> Command)
|
||||
65 49 # Space
|
||||
113 55 # Alt Right (-> Command)
|
||||
116 58 # Logo Right (-> Option)
|
||||
117 50 # Menu (-> International)
|
||||
109 54 # Ctrl Right
|
||||
100 59 # Cursor Left
|
||||
104 61 # Cursor Down
|
||||
102 60 # Cursor Right
|
||||
90 82 # KP 0
|
||||
91 65 # KP .
|
||||
|
||||
#
|
||||
# Linux Framebuffer Console
|
||||
#
|
||||
sdl fbcon
|
||||
1 53 # Esc
|
||||
59 122 # F1
|
||||
60 120 # F2
|
||||
61 99 # F3
|
||||
62 118 # F4
|
||||
63 96 # F5
|
||||
64 97 # F6
|
||||
65 98 # F7
|
||||
66 100 # F8
|
||||
67 101 # F9
|
||||
68 109 # F10
|
||||
87 103 # F11
|
||||
88 111 # F12
|
||||
99 105 # PrintScrn
|
||||
70 107 # Scroll Lock
|
||||
119 113 # Pause
|
||||
41 50 # `
|
||||
2 18 # 1
|
||||
3 19 # 2
|
||||
4 20 # 3
|
||||
5 21 # 4
|
||||
6 23 # 5
|
||||
7 22 # 6
|
||||
8 26 # 7
|
||||
9 28 # 8
|
||||
10 25 # 9
|
||||
11 29 # 0
|
||||
12 27 # -
|
||||
13 24 # =
|
||||
14 51 # Backspace
|
||||
110 114 # Insert
|
||||
102 115 # Home
|
||||
104 116 # Page Up
|
||||
69 71 # Num Lock
|
||||
98 75 # KP /
|
||||
55 67 # KP *
|
||||
74 78 # KP -
|
||||
15 48 # Tab
|
||||
16 12 # Q
|
||||
17 13 # W
|
||||
18 14 # E
|
||||
19 15 # R
|
||||
20 17 # T
|
||||
21 16 # Y
|
||||
22 32 # U
|
||||
23 34 # I
|
||||
24 31 # O
|
||||
25 35 # P
|
||||
26 33 # [
|
||||
27 30 # ]
|
||||
28 36 # Return
|
||||
111 117 # Delete
|
||||
107 119 # End
|
||||
109 121 # Page Down
|
||||
71 89 # KP 7
|
||||
72 91 # KP 8
|
||||
73 92 # KP 9
|
||||
78 69 # KP +
|
||||
58 57 # Caps Lock
|
||||
30 0 # A
|
||||
31 1 # S
|
||||
32 2 # D
|
||||
33 3 # F
|
||||
34 5 # G
|
||||
35 4 # H
|
||||
36 38 # J
|
||||
37 40 # K
|
||||
38 37 # L
|
||||
39 41 # ;
|
||||
40 39 # '
|
||||
75 86 # KP 4
|
||||
76 87 # KP 5
|
||||
77 88 # KP 6
|
||||
42 56 # Shift Left
|
||||
86 50 # International
|
||||
44 6 # Z
|
||||
45 7 # X
|
||||
46 8 # C
|
||||
47 9 # V
|
||||
48 11 # B
|
||||
49 45 # N
|
||||
50 46 # M
|
||||
51 43 # ,
|
||||
52 47 # .
|
||||
53 44 # /
|
||||
54 56 # Shift Right
|
||||
43 42 # \
|
||||
103 62 # Cursor Up
|
||||
79 83 # KP 1
|
||||
80 84 # KP 2
|
||||
81 85 # KP 3
|
||||
96 76 # KP Enter
|
||||
29 54 # Ctrl Left
|
||||
125 58 # Logo Left (-> Option)
|
||||
56 55 # Alt Left (-> Command)
|
||||
57 49 # Space
|
||||
100 55 # Alt Right (-> Command)
|
||||
126 58 # Logo Right (-> Option)
|
||||
97 54 # Ctrl Right
|
||||
105 59 # Cursor Left
|
||||
108 61 # Cursor Down
|
||||
106 60 # Cursor Right
|
||||
82 82 # KP 0
|
||||
83 65 # KP .
|
||||
|
||||
#
|
||||
# Quartz (1:1 translation actually)
|
||||
#
|
||||
sdl Quartz
|
||||
53 53 # Esc
|
||||
122 122 # F1
|
||||
120 120 # F2
|
||||
99 99 # F3
|
||||
118 118 # F4
|
||||
96 96 # F5
|
||||
97 97 # F6
|
||||
98 98 # F7
|
||||
100 100 # F8
|
||||
101 101 # F9
|
||||
109 109 # F10
|
||||
103 103 # F11
|
||||
111 111 # F12
|
||||
105 105 # F13/PrintScrn
|
||||
107 107 # F14/Scroll Lock
|
||||
113 113 # F15/Pause
|
||||
10 10 # `
|
||||
18 18 # 1
|
||||
19 19 # 2
|
||||
20 20 # 3
|
||||
21 21 # 4
|
||||
23 23 # 5
|
||||
22 22 # 6
|
||||
26 26 # 7
|
||||
28 28 # 8
|
||||
25 25 # 9
|
||||
29 29 # 0
|
||||
27 27 # -
|
||||
24 24 # =
|
||||
51 51 # Backspace
|
||||
114 114 # Help/Insert
|
||||
115 115 # Home
|
||||
116 116 # Page Up
|
||||
71 71 # Num Lock
|
||||
81 81 # KP =
|
||||
75 75 # KP /
|
||||
67 67 # KP *
|
||||
48 48 # Tab
|
||||
12 12 # Q
|
||||
13 13 # W
|
||||
14 14 # E
|
||||
15 15 # R
|
||||
17 17 # T
|
||||
16 16 # Y
|
||||
32 32 # U
|
||||
34 34 # I
|
||||
31 31 # O
|
||||
35 35 # P
|
||||
33 33 # [
|
||||
30 30 # ]
|
||||
36 36 # Return
|
||||
117 117 # Delete
|
||||
119 119 # End
|
||||
121 121 # Page Down
|
||||
89 89 # KP 7
|
||||
91 91 # KP 8
|
||||
92 92 # KP 9
|
||||
78 78 # KP -
|
||||
57 57 # Caps Lock
|
||||
0 0 # A
|
||||
1 1 # S
|
||||
2 2 # D
|
||||
3 3 # F
|
||||
5 5 # G
|
||||
4 4 # H
|
||||
38 38 # J
|
||||
40 40 # K
|
||||
37 37 # L
|
||||
41 41 # ;
|
||||
39 39 # '
|
||||
42 42 # \
|
||||
86 86 # KP 4
|
||||
87 87 # KP 5
|
||||
88 88 # KP 6
|
||||
69 69 # KP +
|
||||
56 56 # Shift
|
||||
50 50 # International
|
||||
6 6 # Z
|
||||
7 7 # X
|
||||
8 8 # C
|
||||
9 9 # V
|
||||
11 11 # B
|
||||
45 45 # N
|
||||
46 46 # M
|
||||
43 43 # ,
|
||||
47 47 # .
|
||||
44 44 # /
|
||||
126 62 # Cursor Up
|
||||
123 59 # Cursor Left
|
||||
125 61 # Cursor Down
|
||||
124 60 # Cursor Right
|
||||
83 83 # KP 1
|
||||
84 84 # KP 2
|
||||
85 85 # KP 3
|
||||
76 76 # KP Enter
|
||||
54 54 # Ctrl
|
||||
58 58 # Option
|
||||
55 55 # Command
|
||||
54 54 # Ctrl Left
|
||||
49 49 # Space
|
||||
82 82 # KP 0
|
||||
65 65 # KP .
|
||||
|
||||
#
|
||||
# cocoa (SDL2)
|
||||
#
|
||||
sdl cocoa
|
||||
41 53 # Esc
|
||||
58 122 # F1
|
||||
59 120 # F2
|
||||
60 99 # F3
|
||||
61 118 # F4
|
||||
62 96 # F5
|
||||
63 97 # F6
|
||||
64 98 # F7
|
||||
65 100 # F8
|
||||
66 101 # F9
|
||||
67 109 # F10
|
||||
68 103 # F11
|
||||
69 111 # F12
|
||||
70 105 # F13/PrintScrn
|
||||
71 107 # F14/Scroll Lock
|
||||
72 113 # F15/Pause
|
||||
53 10 # `
|
||||
30 18 # 1
|
||||
31 19 # 2
|
||||
32 20 # 3
|
||||
33 21 # 4
|
||||
34 23 # 5
|
||||
35 22 # 6
|
||||
36 26 # 7
|
||||
37 28 # 8
|
||||
38 25 # 9
|
||||
39 29 # 0
|
||||
45 27 # -
|
||||
46 24 # =
|
||||
42 51 # Backspace
|
||||
73 114 # Help/Insert
|
||||
74 115 # Home
|
||||
75 116 # Page Up
|
||||
83 71 # Num Lock
|
||||
103 81 # KP =
|
||||
84 75 # KP /
|
||||
85 67 # KP *
|
||||
43 48 # Tab
|
||||
20 12 # Q
|
||||
26 13 # W
|
||||
8 14 # E
|
||||
21 15 # R
|
||||
23 17 # T
|
||||
28 16 # Y
|
||||
24 32 # U
|
||||
12 34 # I
|
||||
18 31 # O
|
||||
19 35 # P
|
||||
47 33 # [
|
||||
48 30 # ]
|
||||
40 36 # Return
|
||||
76 117 # Delete
|
||||
77 119 # End
|
||||
78 121 # Page Down
|
||||
95 89 # KP 7
|
||||
96 91 # KP 8
|
||||
97 92 # KP 9
|
||||
86 78 # KP -
|
||||
57 57 # Caps Lock
|
||||
4 0 # A
|
||||
22 1 # S
|
||||
7 2 # D
|
||||
9 3 # F
|
||||
10 5 # G
|
||||
11 4 # H
|
||||
13 38 # J
|
||||
14 40 # K
|
||||
15 37 # L
|
||||
51 41 # ;
|
||||
52 39 # '
|
||||
49 42 # \
|
||||
92 86 # KP 4
|
||||
93 87 # KP 5
|
||||
94 88 # KP 6
|
||||
87 69 # KP +
|
||||
100 50 # International
|
||||
29 6 # Z
|
||||
27 7 # X
|
||||
6 8 # C
|
||||
25 9 # V
|
||||
5 11 # B
|
||||
17 45 # N
|
||||
16 46 # M
|
||||
54 43 # ,
|
||||
55 47 # .
|
||||
56 44 # /
|
||||
82 62 # Cursor Up
|
||||
80 59 # Cursor Left
|
||||
81 61 # Cursor Down
|
||||
79 60 # Cursor Right
|
||||
89 83 # KP 1
|
||||
90 84 # KP 2
|
||||
91 85 # KP 3
|
||||
88 76 # KP Enter
|
||||
225 56 # Shift Left
|
||||
224 54 # Ctrl Left
|
||||
226 58 # Option Left
|
||||
227 55 # Command Left
|
||||
44 49 # Space
|
||||
231 55 # Command Right
|
||||
230 58 # Option Right
|
||||
228 54 # Ctrl Right
|
||||
229 56 # Shift Right
|
||||
98 82 # KP 0
|
||||
99 65 # KP .
|
||||
|
||||
#
|
||||
# Windows (SDL2)
|
||||
#
|
||||
sdl windows
|
||||
41 53 # Esc
|
||||
58 122 # F1
|
||||
59 120 # F2
|
||||
60 99 # F3
|
||||
61 118 # F4
|
||||
62 96 # F5
|
||||
63 97 # F6
|
||||
64 98 # F7
|
||||
65 100 # F8
|
||||
66 101 # F9
|
||||
67 109 # F10
|
||||
68 103 # F11
|
||||
69 111 # F12
|
||||
70 105 # F13/PrintScrn
|
||||
71 107 # F14/Scroll Lock
|
||||
72 113 # F15/Pause
|
||||
53 50 # `
|
||||
30 18 # 1
|
||||
31 19 # 2
|
||||
32 20 # 3
|
||||
33 21 # 4
|
||||
34 23 # 5
|
||||
35 22 # 6
|
||||
36 26 # 7
|
||||
37 28 # 8
|
||||
38 25 # 9
|
||||
39 29 # 0
|
||||
45 27 # -
|
||||
46 24 # =
|
||||
42 51 # Backspace
|
||||
73 114 # Help/Insert
|
||||
74 115 # Home
|
||||
75 116 # Page Up
|
||||
83 71 # Num Lock
|
||||
103 81 # KP =
|
||||
84 75 # KP /
|
||||
85 67 # KP *
|
||||
43 48 # Tab
|
||||
20 12 # Q
|
||||
26 13 # W
|
||||
8 14 # E
|
||||
21 15 # R
|
||||
23 17 # T
|
||||
28 16 # Y
|
||||
24 32 # U
|
||||
12 34 # I
|
||||
18 31 # O
|
||||
19 35 # P
|
||||
47 33 # [
|
||||
48 30 # ]
|
||||
40 36 # Return
|
||||
76 117 # Delete
|
||||
77 119 # End
|
||||
78 121 # Page Down
|
||||
95 89 # KP 7
|
||||
96 91 # KP 8
|
||||
97 92 # KP 9
|
||||
86 78 # KP -
|
||||
57 57 # Caps Lock
|
||||
4 0 # A
|
||||
22 1 # S
|
||||
7 2 # D
|
||||
9 3 # F
|
||||
10 5 # G
|
||||
11 4 # H
|
||||
13 38 # J
|
||||
14 40 # K
|
||||
15 37 # L
|
||||
51 41 # ;
|
||||
52 39 # '
|
||||
49 42 # \
|
||||
92 86 # KP 4
|
||||
93 87 # KP 5
|
||||
94 88 # KP 6
|
||||
87 69 # KP +
|
||||
100 50 # International
|
||||
29 6 # Z
|
||||
27 7 # X
|
||||
6 8 # C
|
||||
25 9 # V
|
||||
5 11 # B
|
||||
17 45 # N
|
||||
16 46 # M
|
||||
54 43 # ,
|
||||
55 47 # .
|
||||
56 44 # /
|
||||
82 62 # Cursor Up
|
||||
80 59 # Cursor Left
|
||||
81 61 # Cursor Down
|
||||
79 60 # Cursor Right
|
||||
89 83 # KP 1
|
||||
90 84 # KP 2
|
||||
91 85 # KP 3
|
||||
88 76 # KP Enter
|
||||
225 56 # Shift Left
|
||||
224 58 # Ctrl Left (--> Option)
|
||||
# 227 # Logo Left
|
||||
226 55 # Alt Left (--> Command)
|
||||
44 49 # Space
|
||||
230 58 # Alt Right (--> Option)
|
||||
# 231 # Logo Right
|
||||
101 50 # Menu (--> International)
|
||||
228 54 # Ctrl Right
|
||||
229 56 # Shift Right
|
||||
98 82 # KP 0
|
||||
99 65 # KP .
|
||||
|
||||
#
|
||||
# Windows
|
||||
#
|
||||
sdl windib
|
||||
sdl directx
|
||||
1 53 # Esc
|
||||
59 122 # F1
|
||||
60 120 # F2
|
||||
61 99 # F3
|
||||
62 118 # F4
|
||||
63 96 # F5
|
||||
64 97 # F6
|
||||
65 98 # F7
|
||||
66 100 # F8
|
||||
67 101 # F9
|
||||
68 109 # F10
|
||||
87 103 # F11
|
||||
88 111 # F12
|
||||
183 105 # PrintScrn
|
||||
70 107 # Scroll Lock
|
||||
197 113 # Pause
|
||||
41 50 # `
|
||||
2 18 # 1
|
||||
3 19 # 2
|
||||
4 20 # 3
|
||||
5 21 # 4
|
||||
6 23 # 5
|
||||
7 22 # 6
|
||||
8 26 # 7
|
||||
9 28 # 8
|
||||
10 25 # 9
|
||||
11 29 # 0
|
||||
12 27 # -
|
||||
13 24 # =
|
||||
14 51 # Backspace
|
||||
210 114 # Insert
|
||||
199 115 # Home
|
||||
201 116 # Page Up
|
||||
69 71 # Num Lock
|
||||
181 75 # KP /
|
||||
55 67 # KP *
|
||||
74 78 # KP -
|
||||
15 48 # Tab
|
||||
16 12 # Q
|
||||
17 13 # W
|
||||
18 14 # E
|
||||
19 15 # R
|
||||
20 17 # T
|
||||
21 16 # Y
|
||||
22 32 # U
|
||||
23 34 # I
|
||||
24 31 # O
|
||||
25 35 # P
|
||||
26 33 # [
|
||||
27 30 # ]
|
||||
28 36 # Return
|
||||
211 117 # Delete
|
||||
207 119 # End
|
||||
209 121 # Page Down
|
||||
71 89 # KP 7
|
||||
72 91 # KP 8
|
||||
73 92 # KP 9
|
||||
78 69 # KP +
|
||||
58 57 # Caps Lock
|
||||
30 0 # A
|
||||
31 1 # S
|
||||
32 2 # D
|
||||
33 3 # F
|
||||
34 5 # G
|
||||
35 4 # H
|
||||
36 38 # J
|
||||
37 40 # K
|
||||
38 37 # L
|
||||
39 41 # ;
|
||||
40 39 # '
|
||||
75 86 # KP 4
|
||||
76 87 # KP 5
|
||||
77 88 # KP 6
|
||||
42 56 # Shift Left
|
||||
86 50 # International
|
||||
44 6 # Z
|
||||
45 7 # X
|
||||
46 8 # C
|
||||
47 9 # V
|
||||
48 11 # B
|
||||
49 45 # N
|
||||
50 46 # M
|
||||
51 43 # ,
|
||||
52 47 # .
|
||||
53 44 # /
|
||||
54 56 # Shift Right
|
||||
43 42 # \
|
||||
200 62 # Cursor Up
|
||||
79 83 # KP 1
|
||||
80 84 # KP 2
|
||||
81 85 # KP 3
|
||||
156 76 # KP Enter
|
||||
29 54 # Ctrl Left
|
||||
219 58 # Logo Left (-> Option)
|
||||
56 55 # Alt Left (-> Command)
|
||||
57 49 # Space
|
||||
184 55 # Alt Right (-> Command)
|
||||
220 58 # Logo Right (-> Option)
|
||||
221 50 # Menu (-> International)
|
||||
157 54 # Ctrl Right
|
||||
203 59 # Cursor Left
|
||||
208 61 # Cursor Down
|
||||
205 60 # Cursor Right
|
||||
82 82 # KP 0
|
||||
83 65 # KP .
|
||||
|
||||
#
|
||||
# XFree86
|
||||
#
|
||||
|
240
BasiliskII/src/Unix/main_unix.cpp
Normal file → Executable file
240
BasiliskII/src/Unix/main_unix.cpp
Normal file → Executable file
@ -29,6 +29,9 @@
|
||||
#ifdef USE_SDL
|
||||
# include <SDL.h>
|
||||
# include <SDL_main.h>
|
||||
#if !SDL_VERSION_ATLEAST(3, 0, 0)
|
||||
#define SDL_PLATFORM_MACOS __MACOSX__
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#ifndef USE_SDL_VIDEO
|
||||
@ -43,6 +46,10 @@
|
||||
# include <sys/mman.h>
|
||||
#endif
|
||||
|
||||
#if SDL_PLATFORM_MACOS
|
||||
# include "utils_macosx.h"
|
||||
#endif
|
||||
|
||||
#if !EMULATED_68K && defined(__NetBSD__)
|
||||
# include <m68k/sync_icache.h>
|
||||
# include <m68k/frame.h>
|
||||
@ -60,8 +67,12 @@ struct sigstate {
|
||||
#ifdef ENABLE_GTK
|
||||
# include <gtk/gtk.h>
|
||||
# include <gdk/gdk.h>
|
||||
# ifdef HAVE_GNOMEUI
|
||||
# include <gnome.h>
|
||||
# if GTK_CHECK_VERSION(3, 14, 0)
|
||||
# define ENABLE_GTK3
|
||||
# endif
|
||||
# if GTK_CHECK_VERSION(3, 22, 0)
|
||||
# define ENABLE_GTK_3_22
|
||||
# include "color_scheme.h"
|
||||
# endif
|
||||
#endif
|
||||
|
||||
@ -91,8 +102,13 @@ using std::string;
|
||||
#include "rpc.h"
|
||||
|
||||
#if USE_JIT
|
||||
#ifdef UPDATE_UAE
|
||||
extern void (*flush_icache)(void); // from compemu_support.cpp
|
||||
extern bool UseJIT;
|
||||
#else
|
||||
extern void flush_icache_range(uint8 *start, uint32 size); // from compemu_support.cpp
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#ifdef ENABLE_MON
|
||||
# include "mon.h"
|
||||
@ -143,6 +159,7 @@ static uint8 last_xpram[XPRAM_SIZE]; // Buffer for monitoring XPRAM changes
|
||||
#if !EMULATED_68K
|
||||
static pthread_t emul_thread; // Handle of MacOS emulation thread (main thread)
|
||||
#endif
|
||||
static int use_gui = -1; // Override prefs and show gui
|
||||
|
||||
static bool xpram_thread_active = false; // Flag: XPRAM watchdog installed
|
||||
static volatile bool xpram_thread_cancel = false; // Flag: Cancel XPRAM thread
|
||||
@ -208,6 +225,8 @@ static void sigill_handler(int sig, int code, struct sigcontext *scp);
|
||||
extern "C" void EmulOpTrampoline(void);
|
||||
#endif
|
||||
|
||||
// vde switch variable
|
||||
char* vde_sock;
|
||||
|
||||
/*
|
||||
* Ersatz functions
|
||||
@ -237,11 +256,12 @@ void *vm_acquire_mac(size_t size)
|
||||
return vm_acquire(size, VM_MAP_DEFAULT | VM_MAP_32BIT);
|
||||
}
|
||||
|
||||
#if REAL_ADDRESSING
|
||||
static int vm_acquire_mac_fixed(void *addr, size_t size)
|
||||
{
|
||||
return vm_acquire_fixed(addr, size, VM_MAP_DEFAULT | VM_MAP_32BIT);
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
/*
|
||||
* SIGSEGV handler
|
||||
@ -284,9 +304,14 @@ static void sigsegv_dump_state(sigsegv_info_t *sip)
|
||||
fprintf(stderr, "\n");
|
||||
#if EMULATED_68K
|
||||
uaecptr nextpc;
|
||||
#ifdef UPDATE_UAE
|
||||
extern void m68k_dumpstate(FILE *, uaecptr *nextpc);
|
||||
m68k_dumpstate(stderr, &nextpc);
|
||||
#else
|
||||
extern void m68k_dumpstate(uaecptr *nextpc);
|
||||
m68k_dumpstate(&nextpc);
|
||||
#endif
|
||||
#endif
|
||||
#if USE_JIT && JIT_DEBUG
|
||||
extern void compiler_dumpstate(void);
|
||||
compiler_dumpstate();
|
||||
@ -359,6 +384,16 @@ void cpu_do_check_ticks(void)
|
||||
if (emulated_ticks <= 0)
|
||||
emulated_ticks += emulated_ticks_quantum;
|
||||
}
|
||||
#else
|
||||
uint16 emulated_ticks;
|
||||
void cpu_do_check_ticks(void)
|
||||
{
|
||||
static int delay = -1;
|
||||
if (delay < 0)
|
||||
delay = PrefsFindInt32("delay");
|
||||
if (delay)
|
||||
usleep(delay);
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
@ -375,15 +410,49 @@ static void usage(const char *prg_name)
|
||||
" --display STRING\n X display to use\n"
|
||||
" --break ADDRESS\n set ROM breakpoint in hexadecimal\n"
|
||||
" --loadbreak FILE\n load breakpoint from FILE\n"
|
||||
" --rominfo\n dump ROM information\n", prg_name
|
||||
" --rominfo\n dump ROM information\n"
|
||||
" --switch SWITCH_PATH\n vde_switch address\n", prg_name
|
||||
);
|
||||
LoadPrefs(NULL); // read the prefs file so PrefsPrintUsage() will print the correct default values
|
||||
PrefsPrintUsage();
|
||||
printf("\nBuild Date: %s\n", __DATE__);
|
||||
exit(0);
|
||||
}
|
||||
|
||||
#ifdef ENABLE_GTK
|
||||
GtkWindow *win;
|
||||
|
||||
static void gui_startup (void)
|
||||
{
|
||||
#ifdef ENABLE_GTK_3_22
|
||||
color_scheme_set(APP_PREFERS_LIGHT);
|
||||
#endif
|
||||
if (use_gui && !PrefsEditor())
|
||||
QuitEmulator();
|
||||
#ifdef ENABLE_GTK_3_22
|
||||
else
|
||||
color_scheme_disconnect();
|
||||
#endif
|
||||
}
|
||||
|
||||
#ifdef ENABLE_GTK3
|
||||
static void gui_activate (GtkApplication *app)
|
||||
{
|
||||
g_assert (GTK_IS_APPLICATION (app));
|
||||
win = gtk_application_get_active_window (app);
|
||||
/* Ask the window manager/compositor to present the window. */
|
||||
if (win != NULL)
|
||||
gtk_window_present (win);
|
||||
}
|
||||
#endif
|
||||
#endif
|
||||
|
||||
int main(int argc, char **argv)
|
||||
{
|
||||
#ifdef ENABLE_GTK3
|
||||
GtkApplication *app = NULL;
|
||||
int ret;
|
||||
#endif
|
||||
const char *vmdir = NULL;
|
||||
char str[256];
|
||||
|
||||
@ -437,19 +506,47 @@ int main(int argc, char **argv)
|
||||
} else if (strcmp(argv[i], "--rominfo") == 0) {
|
||||
argv[i] = NULL;
|
||||
PrintROMInfo = true;
|
||||
} else if (strcmp(argv[i], "--switch") == 0) {
|
||||
argv[i] = NULL;
|
||||
if (argv[++i] == NULL) {
|
||||
printf("switch address not defined\n");
|
||||
usage(argv[0]);
|
||||
}
|
||||
vde_sock = argv[i];
|
||||
argv[i] = NULL;
|
||||
} else if (strcmp(argv[i], "--nogui") == 0) {
|
||||
// We intercept the --nogui commandline so that the settings
|
||||
// window can change the setting from the prefs file
|
||||
argv[i++] = NULL;
|
||||
if (i < argc) {
|
||||
if (strcmp(argv[i], "true") == 0) {
|
||||
use_gui = false;
|
||||
argv[i] = NULL;
|
||||
}
|
||||
else if (strcmp(argv[i], "false") == 0) {
|
||||
use_gui = true;
|
||||
argv[i] = NULL;
|
||||
}
|
||||
} else {
|
||||
use_gui = false;
|
||||
}
|
||||
} else if (strcmp(argv[i], "--gui") == 0 || strcmp(argv[i], "--settings") == 0) {
|
||||
// Alternative commands to enter the GUI
|
||||
use_gui = true;
|
||||
argv[i] = NULL;
|
||||
}
|
||||
|
||||
#if defined(__APPLE__) && defined(__MACH__)
|
||||
// Mac OS X likes to pass in various options of its own, when launching an app.
|
||||
// Attempt to ignore these.
|
||||
if (argv[i]) {
|
||||
const char * mac_psn_prefix = "-psn_";
|
||||
if (strcmp(argv[i], "-NSDocumentRevisionsDebugMode") == 0) {
|
||||
argv[i] = NULL;
|
||||
} else if (strncmp(mac_psn_prefix, argv[i], strlen(mac_psn_prefix)) == 0) {
|
||||
argv[i] = NULL;
|
||||
}
|
||||
}
|
||||
if (argv[i]) {
|
||||
const char * mac_psn_prefix = "-psn_";
|
||||
if (strcmp(argv[i], "-NSDocumentRevisionsDebugMode") == 0) {
|
||||
argv[i] = NULL;
|
||||
} else if (strncmp(mac_psn_prefix, argv[i], strlen(mac_psn_prefix)) == 0) {
|
||||
argv[i] = NULL;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
@ -475,23 +572,11 @@ int main(int argc, char **argv)
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef ENABLE_GTK
|
||||
if (!gui_connection) {
|
||||
#ifdef HAVE_GNOMEUI
|
||||
// Init GNOME/GTK
|
||||
char version[16];
|
||||
sprintf(version, "%d.%d", VERSION_MAJOR, VERSION_MINOR);
|
||||
gnome_init("Basilisk II", version, argc, argv);
|
||||
#else
|
||||
// Init GTK
|
||||
gtk_set_locale();
|
||||
gtk_init(&argc, &argv);
|
||||
#endif
|
||||
}
|
||||
#endif
|
||||
|
||||
// Read preferences
|
||||
PrefsInit(vmdir, argc, argv);
|
||||
// Only use nogui preference if not passed as command line argument
|
||||
if (use_gui == -1)
|
||||
use_gui = !PrefsFindBool("nogui");
|
||||
|
||||
// Any command line arguments left?
|
||||
for (int i=1; i<argc; i++) {
|
||||
@ -535,14 +620,13 @@ int main(int argc, char **argv)
|
||||
}
|
||||
atexit(SDL_Quit);
|
||||
|
||||
#if __MACOSX__ && SDL_VERSION_ATLEAST(2,0,0)
|
||||
#if SDL_PLATFORM_MACOS && SDL_VERSION_ATLEAST(2,0,0)
|
||||
// On Mac OS X hosts, SDL2 will create its own menu bar. This is mostly OK,
|
||||
// except that it will also install keyboard shortcuts, such as Command + Q,
|
||||
// which can interfere with keyboard shortcuts in the guest OS.
|
||||
//
|
||||
// HACK: disable these shortcuts, while leaving all other pieces of SDL2's
|
||||
// menu bar in-place.
|
||||
extern void disable_SDL2_macosx_menu_bar_keyboard_shortcuts();
|
||||
disable_SDL2_macosx_menu_bar_keyboard_shortcuts();
|
||||
#endif
|
||||
|
||||
@ -551,10 +635,24 @@ int main(int argc, char **argv)
|
||||
// Init system routines
|
||||
SysInit();
|
||||
|
||||
// Show preferences editor
|
||||
if (!gui_connection && !PrefsFindBool("nogui"))
|
||||
if (!PrefsEditor())
|
||||
QuitEmulator();
|
||||
#ifdef ENABLE_GTK3
|
||||
if (!gui_connection) {
|
||||
// Init GTK
|
||||
app = gtk_application_new (GetString(STR_APP_ID), G_APPLICATION_FLAGS_NONE);
|
||||
g_set_prgname (GetString(STR_APP_DISPLAY_NAME));
|
||||
g_signal_connect (app, "activate", G_CALLBACK (gui_activate), NULL);
|
||||
g_signal_connect (app, "startup", G_CALLBACK (gui_startup), NULL);
|
||||
g_application_register (G_APPLICATION (app), NULL, NULL);
|
||||
ret = g_application_run (G_APPLICATION (app), argc, argv);
|
||||
}
|
||||
#elif defined(ENABLE_GTK)
|
||||
if (!gui_connection) {
|
||||
// Init GTK
|
||||
gtk_set_locale();
|
||||
gtk_init(&argc, &argv);
|
||||
gui_startup();
|
||||
}
|
||||
#endif
|
||||
|
||||
// Install the handler for SIGSEGV
|
||||
if (!sigsegv_install_handler(sigsegv_handler)) {
|
||||
@ -598,7 +696,7 @@ int main(int argc, char **argv)
|
||||
#else
|
||||
const bool can_map_all_memory = false;
|
||||
#endif
|
||||
|
||||
|
||||
// Try to allocate all memory from 0x0000, if it is not known to crash
|
||||
if (can_map_all_memory && (vm_acquire_mac_fixed(0, RAMSize + 0x100000) == 0)) {
|
||||
D(bug("Could allocate RAM and ROM from 0x0000\n"));
|
||||
@ -659,10 +757,8 @@ int main(int argc, char **argv)
|
||||
RAMBaseMac = Host2MacAddr(RAMBaseHost);
|
||||
ROMBaseMac = Host2MacAddr(ROMBaseHost);
|
||||
#endif
|
||||
D(bug("Mac RAM starts at %p (%08x)\n", RAMBaseHost, RAMBaseMac));
|
||||
D(bug("Mac ROM starts at %p (%08x)\n", ROMBaseHost, ROMBaseMac));
|
||||
|
||||
#if __MACOSX__
|
||||
|
||||
#if SDL_PLATFORM_MACOS
|
||||
extern void set_current_directory();
|
||||
set_current_directory();
|
||||
#endif
|
||||
@ -724,6 +820,9 @@ int main(int argc, char **argv)
|
||||
QuitEmulator();
|
||||
D(bug("Initialization complete\n"));
|
||||
|
||||
D(bug("Mac RAM starts at %p (%08x)\n", RAMBaseHost, RAMBaseMac));
|
||||
D(bug("Mac ROM starts at %p (%08x)\n", ROMBaseHost, ROMBaseMac));
|
||||
|
||||
#if !EMULATED_68K
|
||||
// (Virtual) supervisor mode, disable interrupts
|
||||
EmulatedSR = 0x2700;
|
||||
@ -972,8 +1071,12 @@ void FlushCodeCache(void *start, uint32 size)
|
||||
{
|
||||
#if USE_JIT
|
||||
if (UseJIT)
|
||||
#ifdef UPDATE_UAE
|
||||
flush_icache();
|
||||
#else
|
||||
flush_icache_range((uint8 *)start, size);
|
||||
#endif
|
||||
#endif
|
||||
#if !EMULATED_68K && defined(__NetBSD__)
|
||||
m68k_sync_icache(start, size);
|
||||
#endif
|
||||
@ -989,8 +1092,13 @@ static void sigint_handler(...)
|
||||
{
|
||||
#if EMULATED_68K
|
||||
uaecptr nextpc;
|
||||
#ifdef UPDATE_UAE
|
||||
extern void m68k_dumpstate(FILE *, uaecptr *nextpc);
|
||||
m68k_dumpstate(stderr, &nextpc);
|
||||
#else
|
||||
extern void m68k_dumpstate(uaecptr *nextpc);
|
||||
m68k_dumpstate(&nextpc);
|
||||
#endif
|
||||
#endif
|
||||
VideoQuitFullScreen();
|
||||
const char *arg[4] = {"mon", "-m", "-r", NULL};
|
||||
@ -1223,13 +1331,15 @@ static void one_tick(...)
|
||||
}
|
||||
|
||||
#ifdef USE_PTHREADS_SERVICES
|
||||
bool tick_inhibit;
|
||||
static void *tick_func(void *arg)
|
||||
{
|
||||
uint64 start = GetTicks_usec();
|
||||
int64 ticks = 0;
|
||||
uint64 next = GetTicks_usec();
|
||||
uint64 next = start;
|
||||
while (!tick_thread_cancel) {
|
||||
one_tick();
|
||||
if (!tick_inhibit)
|
||||
one_tick();
|
||||
next += 16625;
|
||||
int64 delay = next - GetTicks_usec();
|
||||
if (delay > 0)
|
||||
@ -1238,8 +1348,10 @@ static void *tick_func(void *arg)
|
||||
next = GetTicks_usec();
|
||||
ticks++;
|
||||
}
|
||||
#if DEBUG
|
||||
uint64 end = GetTicks_usec();
|
||||
D(bug("%lld ticks in %lld usec = %f ticks/sec\n", ticks, end - start, ticks * 1000000.0 / (end - start)));
|
||||
#endif
|
||||
return NULL;
|
||||
}
|
||||
#endif
|
||||
@ -1555,37 +1667,23 @@ ill: printf("SIGILL num %d, code %d\n", sig, code);
|
||||
*/
|
||||
|
||||
#ifdef ENABLE_GTK
|
||||
static void dl_destroyed(void)
|
||||
{
|
||||
gtk_main_quit();
|
||||
}
|
||||
|
||||
static void dl_quit(GtkWidget *dialog)
|
||||
static GCallback dl_destroyed(GtkWidget *dialog)
|
||||
{
|
||||
gtk_widget_destroy(dialog);
|
||||
gtk_main_quit();
|
||||
return NULL;
|
||||
}
|
||||
|
||||
void display_alert(int title_id, int prefix_id, int button_id, const char *text)
|
||||
{
|
||||
char str[256];
|
||||
sprintf(str, GetString(prefix_id), text);
|
||||
|
||||
GtkWidget *dialog = gtk_dialog_new();
|
||||
gtk_window_set_title(GTK_WINDOW(dialog), GetString(title_id));
|
||||
gtk_container_border_width(GTK_CONTAINER(dialog), 5);
|
||||
gtk_widget_set_uposition(GTK_WIDGET(dialog), 100, 150);
|
||||
gtk_signal_connect(GTK_OBJECT(dialog), "destroy", GTK_SIGNAL_FUNC(dl_destroyed), NULL);
|
||||
|
||||
GtkWidget *label = gtk_label_new(str);
|
||||
gtk_widget_show(label);
|
||||
gtk_box_pack_start(GTK_BOX(GTK_DIALOG(dialog)->vbox), label, TRUE, TRUE, 0);
|
||||
|
||||
GtkWidget *button = gtk_button_new_with_label(GetString(button_id));
|
||||
gtk_widget_show(button);
|
||||
gtk_signal_connect_object(GTK_OBJECT(button), "clicked", GTK_SIGNAL_FUNC(dl_quit), GTK_OBJECT(dialog));
|
||||
gtk_box_pack_start(GTK_BOX(GTK_DIALOG(dialog)->action_area), button, FALSE, FALSE, 0);
|
||||
GTK_WIDGET_SET_FLAGS(button, GTK_CAN_DEFAULT);
|
||||
gtk_widget_grab_default(button);
|
||||
GtkWidget *dialog = gtk_message_dialog_new(NULL,
|
||||
GTK_DIALOG_MODAL,
|
||||
GTK_MESSAGE_WARNING,
|
||||
GTK_BUTTONS_NONE,
|
||||
GetString(title_id), NULL);
|
||||
gtk_message_dialog_format_secondary_text(GTK_MESSAGE_DIALOG(dialog), "%s", text);
|
||||
gtk_dialog_add_button(GTK_DIALOG(dialog), GetString(button_id), GTK_RESPONSE_CLOSE);
|
||||
g_signal_connect(dialog, "response", G_CALLBACK(dl_destroyed), NULL);
|
||||
gtk_widget_show(dialog);
|
||||
|
||||
gtk_main();
|
||||
@ -1604,11 +1702,13 @@ void ErrorAlert(const char *text)
|
||||
rpc_method_wait_for_reply(gui_connection, RPC_TYPE_INVALID) == RPC_ERROR_NO_ERROR)
|
||||
return;
|
||||
}
|
||||
#if defined(ENABLE_GTK) && !defined(USE_SDL_VIDEO)
|
||||
if (PrefsFindBool("nogui") || x_display == NULL) {
|
||||
#ifdef ENABLE_GTK
|
||||
#ifndef USE_SDL_VIDEO
|
||||
if (x_display == NULL) {
|
||||
printf(GetString(STR_SHELL_ERROR_PREFIX), text);
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
VideoQuitFullScreen();
|
||||
display_alert(STR_ERROR_ALERT_TITLE, STR_GUI_ERROR_PREFIX, STR_QUIT_BUTTON, text);
|
||||
#else
|
||||
@ -1628,11 +1728,13 @@ void WarningAlert(const char *text)
|
||||
rpc_method_wait_for_reply(gui_connection, RPC_TYPE_INVALID) == RPC_ERROR_NO_ERROR)
|
||||
return;
|
||||
}
|
||||
#if defined(ENABLE_GTK) && !defined(USE_SDL_VIDEO)
|
||||
if (PrefsFindBool("nogui") || x_display == NULL) {
|
||||
#ifdef ENABLE_GTK
|
||||
#ifndef USE_SDL_VIDEO
|
||||
if (x_display == NULL) {
|
||||
printf(GetString(STR_SHELL_WARNING_PREFIX), text);
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
display_alert(STR_WARNING_ALERT_TITLE, STR_GUI_WARNING_PREFIX, STR_OK_BUTTON, text);
|
||||
#else
|
||||
printf(GetString(STR_SHELL_WARNING_PREFIX), text);
|
||||
|
File diff suppressed because it is too large
Load Diff
1655
BasiliskII/src/Unix/prefs_editor_gtk3.cpp
Normal file
1655
BasiliskII/src/Unix/prefs_editor_gtk3.cpp
Normal file
File diff suppressed because it is too large
Load Diff
@ -1,7 +1,7 @@
|
||||
/*
|
||||
* prefs_unix.cpp - Preferences handling, Unix specific stuff
|
||||
*
|
||||
* Basilisk II (C) 1997-2008 Christian Bauer
|
||||
* Basilisk II, SheepShaver (C) 1997-2008 Christian Bauer and Marc Hellwig
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
@ -19,28 +19,27 @@
|
||||
*/
|
||||
|
||||
#include "sysdeps.h"
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
#include <sys/stat.h>
|
||||
#include <errno.h>
|
||||
#include <string>
|
||||
using std::string;
|
||||
|
||||
#include "prefs.h"
|
||||
|
||||
|
||||
// Platform-specific preferences items
|
||||
prefs_desc platform_prefs_items[] = {
|
||||
#ifdef SHEEPSHAVER
|
||||
{"ether", TYPE_STRING, false, "device name of Mac ethernet adapter"},
|
||||
{"etherconfig", TYPE_STRING, false, "path of network config script"},
|
||||
{"keycodes", TYPE_BOOLEAN, false, "use keycodes rather than keysyms to decode keyboard"},
|
||||
{"keycodefile", TYPE_STRING, false, "path of keycode translation file"},
|
||||
{"fbdevicefile", TYPE_STRING, false, "path of frame buffer device specification file"},
|
||||
{"mousewheelmode", TYPE_INT32, false, "mouse wheel support mode (0=page up/down, 1=cursor up/down)"},
|
||||
{"mousewheellines", TYPE_INT32, false, "number of lines to scroll in mouse wheel mode 1"},
|
||||
#else
|
||||
{"fbdevicefile", TYPE_STRING, false, "path of frame buffer device specification file"},
|
||||
#endif
|
||||
{"dsp", TYPE_STRING, false, "audio output (dsp) device name"},
|
||||
{"mixer", TYPE_STRING, false, "audio mixer device name"},
|
||||
#ifdef HAVE_SIGSEGV_SKIP_INSTRUCTION
|
||||
{"ignoresegv", TYPE_BOOLEAN, false, "ignore illegal memory accesses"},
|
||||
#endif
|
||||
{"idlewait", TYPE_BOOLEAN, false, "sleep when idle"},
|
||||
#ifdef USE_SDL_VIDEO
|
||||
{"sdlrender", TYPE_STRING, false, "SDL_Renderer driver (\"auto\", \"software\" (may be faster), etc.)"},
|
||||
@ -49,8 +48,222 @@ prefs_desc platform_prefs_items[] = {
|
||||
};
|
||||
|
||||
|
||||
#ifdef __linux__
|
||||
|
||||
|
||||
// Standard file names and paths
|
||||
#ifdef SHEEPSHAVER
|
||||
static const char PREFS_FILE_NAME[] = "/.sheepshaver_prefs";
|
||||
static const char XDG_PREFS_FILE_NAME[] = "/prefs";
|
||||
static const char XPRAM_FILE_NAME[] = "/.sheepshaver_nvram";
|
||||
static const char XDG_XPRAM_FILE_NAME[] = "/nvram";
|
||||
static const char XDG_CONFIG_SUBDIR[] = "/SheepShaver";
|
||||
#else
|
||||
static const char PREFS_FILE_NAME[] = "/.basilisk_ii_prefs";
|
||||
static const char XDG_PREFS_FILE_NAME[] = "/prefs";
|
||||
static const char XPRAM_FILE_NAME[] = "/.basilisk_ii_xpram";
|
||||
static const char XDG_XPRAM_FILE_NAME[] = "/xpram";
|
||||
static const char XDG_CONFIG_SUBDIR[] = "/BasiliskII";
|
||||
#endif
|
||||
|
||||
// Prefs file name and path
|
||||
const char PREFS_FILE_NAME[] = ".basilisk_ii_prefs";
|
||||
string UserPrefsPath;
|
||||
static string home_dir;
|
||||
static string xdg_config_dir;
|
||||
static string prefs_name;
|
||||
extern string xpram_name;
|
||||
|
||||
static string get_xdg_config_dir(void)
|
||||
{
|
||||
char *env;
|
||||
if (env = getenv("XDG_CONFIG_HOME"))
|
||||
return string(env) + XDG_CONFIG_SUBDIR;
|
||||
if (env = getenv("HOME"))
|
||||
return string(env) + "/.config" + XDG_CONFIG_SUBDIR;
|
||||
return "";
|
||||
}
|
||||
|
||||
static string get_home_dir(void)
|
||||
{
|
||||
char *env;
|
||||
if(env = getenv("HOME"))
|
||||
return string(env);
|
||||
return "."; // last resort, use the current directory
|
||||
}
|
||||
|
||||
static string get_dir(string *path)
|
||||
{
|
||||
int pos = path->find_last_of('/');
|
||||
if (pos == 0)
|
||||
return ""; // file is in root folder
|
||||
if (pos == std::string::npos)
|
||||
return "."; // file is in current folder
|
||||
return path->substr(0, pos);
|
||||
}
|
||||
|
||||
static void exit_if_dir(const string& path)
|
||||
{
|
||||
struct stat info;
|
||||
if (stat(path.c_str(), &info) != 0){
|
||||
return;
|
||||
}
|
||||
if ((info.st_mode & S_IFDIR) != 0)
|
||||
{
|
||||
fprintf(stderr, "ERROR: Cannot open %s (Is a directory)\n", prefs_name.c_str());
|
||||
exit(1);
|
||||
}
|
||||
}
|
||||
|
||||
static bool load_prefs_file(const string& path, bool exit_on_failure)
|
||||
{
|
||||
exit_if_dir(path);
|
||||
FILE *prefs = fopen(path.c_str(), "r");
|
||||
if (prefs != NULL)
|
||||
{
|
||||
LoadPrefsFromStream(prefs);
|
||||
fclose(prefs);
|
||||
printf("Using prefs file at %s\n", prefs_name.c_str());
|
||||
return true;
|
||||
}
|
||||
else if (exit_on_failure)
|
||||
{
|
||||
fprintf(stderr, "ERROR: Could not load prefs file from %s (%s)\n",
|
||||
path.c_str(), strerror(errno));
|
||||
exit(1);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/*
|
||||
* Look for prefs file in the following locations (in order of priority):
|
||||
* 1. From vmdir/.basilisk_ii_prefs if a vmdir has been specified
|
||||
* 2. From path specified with --config command line
|
||||
* 3. From $HOME/.basilisk_ii_prefs if it exists
|
||||
* 4. From $XDG_CONFIG_HOME/BasiliskII/prefs if it exists
|
||||
* 5. Create a new prefs file at $XDG_CONFIG_HOME/BasiliskII/prefs
|
||||
* (or the equivalent paths for SheepShaver)
|
||||
* If $XDG_CONFIG_HOME doesn't exist, $HOME/.config is used instead,
|
||||
* in accordance with XDG Base Directory Specification:
|
||||
* https://specifications.freedesktop.org/basedir-spec/basedir-spec-latest.html
|
||||
*/
|
||||
|
||||
void LoadPrefs(const char* vmdir)
|
||||
{
|
||||
home_dir = get_home_dir();
|
||||
xdg_config_dir = get_xdg_config_dir();
|
||||
|
||||
// vmdir was specified on the command line
|
||||
if (vmdir)
|
||||
{
|
||||
prefs_name = string(vmdir) + XDG_PREFS_FILE_NAME;
|
||||
xpram_name = string(vmdir) + XDG_XPRAM_FILE_NAME;
|
||||
if (load_prefs_file(prefs_name, true))
|
||||
return;
|
||||
}
|
||||
|
||||
// --config was specified
|
||||
if (!UserPrefsPath.empty())
|
||||
{
|
||||
prefs_name = UserPrefsPath;
|
||||
xpram_name = get_dir(&prefs_name) + XPRAM_FILE_NAME;
|
||||
if (load_prefs_file(prefs_name, true))
|
||||
return;
|
||||
}
|
||||
|
||||
// Load .basilisk_ii_prefs from $HOME if it exists
|
||||
if (!home_dir.empty())
|
||||
{
|
||||
prefs_name = home_dir + PREFS_FILE_NAME;
|
||||
xpram_name = home_dir + XPRAM_FILE_NAME;
|
||||
if (load_prefs_file(prefs_name, false))
|
||||
return;
|
||||
}
|
||||
|
||||
// If no other prefs file exists, try the $XDG_CONFIG_HOME directory
|
||||
if (!xdg_config_dir.empty())
|
||||
{
|
||||
prefs_name = xdg_config_dir + XDG_PREFS_FILE_NAME;
|
||||
xpram_name = xdg_config_dir + XDG_XPRAM_FILE_NAME;
|
||||
if (load_prefs_file(prefs_name, false))
|
||||
return;
|
||||
}
|
||||
|
||||
// No prefs file, save defaults in $XDG_CONFIG_HOME directory
|
||||
//#ifdef __linux__
|
||||
PrefsAddString("cdrom", "/dev/cdrom");
|
||||
//#endif
|
||||
printf("No prefs file found, creating new one at %s\n", prefs_name.c_str());
|
||||
SavePrefs();
|
||||
}
|
||||
|
||||
static bool is_dir(const string& path)
|
||||
{
|
||||
struct stat info;
|
||||
if (stat(path.c_str(), &info) != 0){
|
||||
return false;
|
||||
}
|
||||
return (info.st_mode & S_IFDIR) != 0;
|
||||
}
|
||||
|
||||
static bool create_directories(const string& path, mode_t mode)
|
||||
{
|
||||
if (mkdir(path.c_str(), mode) == 0)
|
||||
return true;
|
||||
|
||||
switch (errno)
|
||||
{
|
||||
case ENOENT:
|
||||
{
|
||||
int pos = path.find_last_of('/');
|
||||
if (pos == std::string::npos)
|
||||
return false;
|
||||
if (!create_directories(path.substr(0,pos),mode))
|
||||
return false;
|
||||
}
|
||||
return 0 == mkdir(path.c_str(),mode);
|
||||
|
||||
case EEXIST:
|
||||
return is_dir(path);
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Save preferences to settings file
|
||||
*/
|
||||
|
||||
|
||||
void SavePrefs(void)
|
||||
{
|
||||
FILE *f;
|
||||
string prefs_dir = get_dir(&prefs_name);
|
||||
if (!prefs_dir.empty() && !is_dir(prefs_dir))
|
||||
{
|
||||
create_directories(prefs_dir, 0700);
|
||||
}
|
||||
if ((f = fopen(prefs_name.c_str(), "w")) != NULL)
|
||||
{
|
||||
SavePrefsToStream(f);
|
||||
fclose(f);
|
||||
}
|
||||
else
|
||||
{
|
||||
fprintf(stderr, "WARNING: Unable to save %s (%s)\n",
|
||||
prefs_name.c_str(), strerror(errno));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
#else // __linux__
|
||||
|
||||
|
||||
// Prefs file name and path
|
||||
#ifdef SHEEPSHAVER
|
||||
static const char PREFS_FILE_NAME[] = ".sheepshaver_prefs";
|
||||
#else
|
||||
static const char PREFS_FILE_NAME[] = ".basilisk_ii_prefs";
|
||||
#endif
|
||||
string UserPrefsPath;
|
||||
static string prefs_path;
|
||||
|
||||
@ -91,7 +304,9 @@ void LoadPrefs(const char *vmdir)
|
||||
fclose(f);
|
||||
|
||||
} else {
|
||||
|
||||
//#ifdef __linux__
|
||||
// PrefsAddString("cdrom", "/dev/cdrom");
|
||||
//#endif
|
||||
// No prefs file, save defaults
|
||||
SavePrefs();
|
||||
}
|
||||
@ -112,6 +327,9 @@ void SavePrefs(void)
|
||||
}
|
||||
|
||||
|
||||
#endif // __linux__
|
||||
|
||||
|
||||
/*
|
||||
* Add defaults of platform-specific prefs items
|
||||
* You may also override the defaults set in PrefsInit()
|
||||
@ -124,22 +342,28 @@ void AddPlatformPrefsDefaults(void)
|
||||
PrefsReplaceInt32("mousewheelmode", 1);
|
||||
PrefsReplaceInt32("mousewheellines", 3);
|
||||
#ifdef __linux__
|
||||
if (access("/dev/sound/dsp", F_OK) == 0) {
|
||||
if (access("/dev/sound/dsp", F_OK) == 0)
|
||||
{
|
||||
PrefsReplaceString("dsp", "/dev/sound/dsp");
|
||||
} else {
|
||||
}
|
||||
else
|
||||
{
|
||||
PrefsReplaceString("dsp", "/dev/dsp");
|
||||
}
|
||||
if (access("/dev/sound/mixer", F_OK) == 0) {
|
||||
if (access("/dev/sound/mixer", F_OK) == 0)
|
||||
{
|
||||
PrefsReplaceString("mixer", "/dev/sound/mixer");
|
||||
} else {
|
||||
}
|
||||
else
|
||||
{
|
||||
PrefsReplaceString("mixer", "/dev/mixer");
|
||||
}
|
||||
#elif defined (__NetBSD__)
|
||||
PrefsReplaceString("dsp", "/dev/audio");
|
||||
PrefsReplaceString("mixer", "/dev/mixer");
|
||||
#else
|
||||
PrefsReplaceString("dsp", "/dev/dsp");
|
||||
PrefsReplaceString("mixer", "/dev/mixer");
|
||||
#endif
|
||||
#ifdef HAVE_SIGSEGV_SKIP_INSTRUCTION
|
||||
PrefsAddBool("ignoresegv", false);
|
||||
#endif
|
||||
PrefsAddBool("idlewait", true);
|
||||
}
|
||||
|
@ -21,12 +21,18 @@
|
||||
#include "sysdeps.h"
|
||||
|
||||
#include <sys/ioctl.h>
|
||||
|
||||
#ifdef HAVE_SYS_FILIO_H
|
||||
#include <sys/filio.h>
|
||||
#endif
|
||||
|
||||
#include <sys/stat.h>
|
||||
#include <sys/wait.h>
|
||||
#include <pthread.h>
|
||||
#include <semaphore.h>
|
||||
#include <termios.h>
|
||||
#include <errno.h>
|
||||
|
||||
#ifdef __linux__
|
||||
#include <linux/lp.h>
|
||||
#include <linux/major.h>
|
||||
@ -648,16 +654,16 @@ bool XSERDPort::configure(uint16 config)
|
||||
// Set number of data bits
|
||||
switch (config & 0x0c00) {
|
||||
case data5:
|
||||
mode.c_cflag = mode.c_cflag & ~CSIZE | CS5;
|
||||
mode.c_cflag = (mode.c_cflag & ~CSIZE) | CS5;
|
||||
break;
|
||||
case data6:
|
||||
mode.c_cflag = mode.c_cflag & ~CSIZE | CS6;
|
||||
mode.c_cflag = (mode.c_cflag & ~CSIZE) | CS6;
|
||||
break;
|
||||
case data7:
|
||||
mode.c_cflag = mode.c_cflag & ~CSIZE | CS7;
|
||||
mode.c_cflag = (mode.c_cflag & ~CSIZE) | CS7;
|
||||
break;
|
||||
case data8:
|
||||
mode.c_cflag = mode.c_cflag & ~CSIZE | CS8;
|
||||
mode.c_cflag = (mode.c_cflag & ~CSIZE) | CS8;
|
||||
break;
|
||||
}
|
||||
|
||||
|
@ -22,6 +22,11 @@ RCSID("$OpenBSD: sshpty.c,v 1.4 2001/12/19 07:18:56 deraadt Exp $");
|
||||
#include <ctype.h>
|
||||
#include <errno.h>
|
||||
#include <fcntl.h> /* For O_NONBLOCK */
|
||||
|
||||
#ifdef HAVE_SYS_STAT_H
|
||||
#include <sys/stat.h>
|
||||
#endif
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <pwd.h>
|
||||
@ -45,10 +50,6 @@ RCSID("$OpenBSD: sshpty.c,v 1.4 2001/12/19 07:18:56 deraadt Exp $");
|
||||
# include <sys/bsdtty.h>
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_SYS_STAT_H
|
||||
# include <sys/stat.h> /* For S_* constants and macros */
|
||||
#endif
|
||||
|
||||
#ifndef _PATH_TTY
|
||||
# define _PATH_TTY "/dev/tty"
|
||||
#endif
|
||||
@ -73,7 +74,12 @@ RCSID("$OpenBSD: sshpty.c,v 1.4 2001/12/19 07:18:56 deraadt Exp $");
|
||||
#define fatal(x) do { printf("Fatal error: %s", x); return 0; } while(0)
|
||||
#endif /* not in BasiliskII */
|
||||
|
||||
#ifdef __sun__
|
||||
#define mysig_t void*
|
||||
#else
|
||||
#define mysig_t sig_t
|
||||
#endif
|
||||
|
||||
#define mysignal signal
|
||||
#include <signal.h>
|
||||
|
||||
|
@ -59,7 +59,7 @@
|
||||
#include "disk_unix.h"
|
||||
|
||||
#if defined(BINCUE)
|
||||
#include "bincue_unix.h"
|
||||
#include "bincue.h"
|
||||
#endif
|
||||
|
||||
|
||||
@ -369,6 +369,9 @@ void SysAddCDROMPrefs(void)
|
||||
closedir(cd_dir);
|
||||
}
|
||||
}
|
||||
#elif defined __FreeBSD__
|
||||
if (access("/cdrom", F_OK) == 0)
|
||||
PrefsAddString("cdrom", "/cdrom");
|
||||
#elif defined __MACOSX__
|
||||
// There is no predefined path for CD-ROMs on MacOS X. Rather, we
|
||||
// define a single fake CD-ROM entry for the emulated MacOS.
|
||||
@ -396,8 +399,8 @@ void SysAddSerialPrefs(void)
|
||||
PrefsAddString("serialb", "/dev/tts/1");
|
||||
}
|
||||
#elif defined(__FreeBSD__)
|
||||
PrefsAddString("seriala", "/dev/cuaa0");
|
||||
PrefsAddString("serialb", "/dev/cuaa1");
|
||||
PrefsAddString("seriala", "/dev/cuau0");
|
||||
PrefsAddString("serialb", "/dev/cuau1");
|
||||
#elif defined(__NetBSD__)
|
||||
PrefsAddString("seriala", "/dev/tty00");
|
||||
PrefsAddString("serialb", "/dev/tty01");
|
||||
@ -537,14 +540,14 @@ static mac_file_handle *open_filehandle(const char *name)
|
||||
return fh;
|
||||
}
|
||||
|
||||
void *Sys_open(const char *name, bool read_only)
|
||||
void *Sys_open(const char *name, bool read_only, bool is_cdrom)
|
||||
{
|
||||
bool is_file = strncmp(name, "/dev/", 5) != 0;
|
||||
#if defined(__FreeBSD__)
|
||||
// SCSI IDE
|
||||
bool is_cdrom = strncmp(name, "/dev/cd", 7) == 0 || strncmp(name, "/dev/acd", 8) == 0;
|
||||
is_cdrom |= strncmp(name, "/dev/cd", 7) == 0 || strncmp(name, "/dev/acd", 8) == 0;
|
||||
#else
|
||||
bool is_cdrom = strncmp(name, "/dev/cd", 7) == 0;
|
||||
is_cdrom |= strncmp(name, "/dev/cd", 7) == 0;
|
||||
#endif
|
||||
bool is_floppy = strncmp(name, "/dev/fd", 7) == 0;
|
||||
|
||||
@ -1407,8 +1410,13 @@ bool SysCDScan(void *arg, uint8 start_m, uint8 start_s, uint8 start_f, bool reve
|
||||
mac_file_handle *fh = (mac_file_handle *)arg;
|
||||
if (!fh)
|
||||
return false;
|
||||
|
||||
// Not supported under Linux
|
||||
|
||||
#if defined(BINCUE)
|
||||
if (fh->is_bincue)
|
||||
return CDScan_bincue(fh->bincue_fd,start_m,start_s,start_f,reverse);
|
||||
#endif
|
||||
|
||||
// Not supported outside bincue
|
||||
return false;
|
||||
}
|
||||
|
||||
@ -1422,6 +1430,11 @@ void SysCDSetVolume(void *arg, uint8 left, uint8 right)
|
||||
mac_file_handle *fh = (mac_file_handle *)arg;
|
||||
if (!fh)
|
||||
return;
|
||||
|
||||
#if defined(BINCUE)
|
||||
if (fh->is_bincue)
|
||||
CDSetVol_bincue(fh->bincue_fd,left,right);
|
||||
#endif
|
||||
|
||||
if (fh->is_cdrom) {
|
||||
#if defined(__linux__)
|
||||
@ -1450,6 +1463,12 @@ void SysCDGetVolume(void *arg, uint8 &left, uint8 &right)
|
||||
return;
|
||||
|
||||
left = right = 0;
|
||||
|
||||
#if defined(BINCUE)
|
||||
if (fh->is_bincue)
|
||||
CDGetVol_bincue(fh->bincue_fd,&left,&right);
|
||||
#endif
|
||||
|
||||
if (fh->is_cdrom) {
|
||||
#if defined(__linux__)
|
||||
cdrom_volctrl vol;
|
||||
|
@ -28,9 +28,9 @@
|
||||
#include <config.h>
|
||||
#include "user_strings_unix.h"
|
||||
|
||||
#ifndef STDC_HEADERS
|
||||
#error "You don't have ANSI C header files."
|
||||
#endif
|
||||
//#ifndef STDC_HEADERS
|
||||
//#error "You don't have ANSI C header files."
|
||||
//#endif
|
||||
|
||||
#ifdef HAVE_UNISTD_H
|
||||
# include <sys/types.h>
|
||||
@ -42,6 +42,7 @@
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <errno.h>
|
||||
|
||||
#ifdef HAVE_PTHREADS
|
||||
# include <pthread.h>
|
||||
@ -51,6 +52,10 @@
|
||||
# include <fcntl.h>
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_SYS_STAT_H
|
||||
# include <sys/stat.h> /* For S_* constants and macros */
|
||||
#endif
|
||||
|
||||
#ifdef TIME_WITH_SYS_TIME
|
||||
# include <sys/time.h>
|
||||
# include <time.h>
|
||||
@ -117,11 +122,6 @@
|
||||
#ifdef HAVE_PTHREADS
|
||||
#define USE_PTHREADS_SERVICES
|
||||
#endif
|
||||
#if EMULATED_68K
|
||||
#if defined(__NetBSD__)
|
||||
#define USE_CPU_EMUL_SERVICES
|
||||
#endif
|
||||
#endif
|
||||
#ifdef USE_CPU_EMUL_SERVICES
|
||||
#undef USE_PTHREADS_SERVICES
|
||||
#endif
|
||||
@ -490,4 +490,21 @@ static inline uae_u32 do_byteswap_16(uae_u32 v)
|
||||
#endif
|
||||
#define REGPARAM2
|
||||
|
||||
#ifndef UNUSED
|
||||
#define UNUSED(x) ((void)x)
|
||||
#endif
|
||||
|
||||
#define unlikely(x) __builtin_expect(!!(x), 0)
|
||||
#define ALWAYS_INLINE inline __attribute__((always_inline))
|
||||
#define memptr uint32
|
||||
|
||||
// High-precision timing
|
||||
#if defined(HAVE_PTHREADS) && defined(HAVE_CLOCK_NANOSLEEP)
|
||||
#define PRECISE_TIMING 1
|
||||
#define PRECISE_TIMING_POSIX 1
|
||||
#elif defined(HAVE_PTHREADS) && defined(__MACH__)
|
||||
#define PRECISE_TIMING 1
|
||||
#define PRECISE_TIMING_MACH 1
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
@ -47,6 +47,19 @@ static inline void mach_current_time(tm_time_t &t) {
|
||||
|
||||
clock_get_time(host_clock, (mach_timespec_t *)&t);
|
||||
}
|
||||
#else
|
||||
tm_time_t host_clock;
|
||||
static bool host_clock_inited = false;
|
||||
static void host_uptime(tm_time_t & t) {
|
||||
if (!host_clock_inited) {
|
||||
timer_current_time(host_clock);
|
||||
host_clock_inited = true;
|
||||
}
|
||||
|
||||
tm_time_t cur;
|
||||
timer_current_time(cur);
|
||||
timer_sub_time(t, cur, host_clock);
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
@ -61,14 +74,14 @@ void Microseconds(uint32 &hi, uint32 &lo)
|
||||
tm_time_t t;
|
||||
mach_current_time(t);
|
||||
uint64 tl = (uint64)t.tv_sec * 1000000 + t.tv_nsec / 1000;
|
||||
#elif defined(HAVE_CLOCK_GETTIME)
|
||||
struct timespec t;
|
||||
clock_gettime(CLOCK_REALTIME, &t);
|
||||
uint64 tl = (uint64)t.tv_sec * 1000000 + t.tv_nsec / 1000;
|
||||
#else
|
||||
struct timeval t;
|
||||
gettimeofday(&t, NULL);
|
||||
uint64 tl = (uint64)t.tv_sec * 1000000 + t.tv_usec;
|
||||
tm_time_t t;
|
||||
host_uptime(t);
|
||||
#if defined(HAVE_CLOCK_GETTIME)
|
||||
uint64 tl = (uint64)t.tv_sec * 1000000 + t.tv_nsec / 1000;
|
||||
#else
|
||||
uint64 tl = (uint64)t.tv_sec * 1000000 + t.tv_usec;
|
||||
#endif
|
||||
#endif
|
||||
hi = tl >> 32;
|
||||
lo = tl;
|
||||
|
8
BasiliskII/src/Unix/ui/basiliskii.gresource.xml
Normal file
8
BasiliskII/src/Unix/ui/basiliskii.gresource.xml
Normal file
@ -0,0 +1,8 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<gresources>
|
||||
<gresource prefix="/net/cebix/BasiliskII">
|
||||
<file preprocess="xml-stripblanks" compressed="true">ui/menu.ui</file>
|
||||
<file preprocess="xml-stripblanks" compressed="true">ui/prefs-editor.ui</file>
|
||||
<file preprocess="xml-stripblanks" compressed="true">ui/help-overlay.ui</file>
|
||||
</gresource>
|
||||
</gresources>
|
88
BasiliskII/src/Unix/ui/help-overlay.ui
Normal file
88
BasiliskII/src/Unix/ui/help-overlay.ui
Normal file
@ -0,0 +1,88 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<interface>
|
||||
<requires lib="gtk+" version="3.20"/>
|
||||
<object class="GtkShortcutsWindow" id="emulator-shortcuts">
|
||||
<property name="modal">1</property>
|
||||
<child>
|
||||
<object class="GtkShortcutsSection">
|
||||
<property name="visible">1</property>
|
||||
<property name="section-name">shortcuts</property>
|
||||
<property name="max-height">10</property>
|
||||
<child>
|
||||
<object class="GtkShortcutsGroup">
|
||||
<property name="visible">1</property>
|
||||
<property name="title" translatable="yes">Settings</property>
|
||||
<child>
|
||||
<object class="GtkShortcutsShortcut">
|
||||
<property name="visible">1</property>
|
||||
<property name="accelerator"><ctrl>S</property>
|
||||
<property name="title" translatable="yes">Start</property>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkShortcutsShortcut">
|
||||
<property name="visible">1</property>
|
||||
<property name="accelerator"><ctrl>Q</property>
|
||||
<property name="title" translatable="yes">Quit</property>
|
||||
</object>
|
||||
</child>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkShortcutsGroup">
|
||||
<property name="title" translatable="yes">Emulator Hotkeys</property>
|
||||
<property name="visible">1</property>
|
||||
<child>
|
||||
<object class="GtkShortcutsShortcut">
|
||||
<property name="visible">1</property>
|
||||
<property name="accelerator"><ctrl>Return</property>
|
||||
<property name="title" translatable="yes">Toggle Full Screen</property>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkShortcutsShortcut">
|
||||
<property name="visible">1</property>
|
||||
<property name="accelerator"><ctrl>F5</property>
|
||||
<property name="title" translatable="yes">Toggle Mouse Grab</property>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkShortcutsShortcut">
|
||||
<property name="visible">1</property>
|
||||
<property name="accelerator"><ctrl>Escape</property>
|
||||
<property name="title" translatable="yes">Force Quit</property>
|
||||
</object>
|
||||
</child>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkShortcutsGroup">
|
||||
<property name="visible">1</property>
|
||||
<property name="title" translatable="yes">Mac OS Modifier Keys</property>
|
||||
<child>
|
||||
<object class="GtkShortcutsShortcut">
|
||||
<property name="visible">1</property>
|
||||
<property name="accelerator"><ctrl></property>
|
||||
<property name="title" translatable="yes">⌃ Control</property>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkShortcutsShortcut">
|
||||
<property name="visible">1</property>
|
||||
<property name="accelerator"><alt></property>
|
||||
<property name="title" translatable="yes">⌘ Command</property>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkShortcutsShortcut">
|
||||
<property name="visible">1</property>
|
||||
<property name="accelerator"><super></property>
|
||||
<property name="title" translatable="yes">⌥ Option</property>
|
||||
</object>
|
||||
</child>
|
||||
</object>
|
||||
</child>
|
||||
</object>
|
||||
</child>
|
||||
</object>
|
||||
</interface>
|
84
BasiliskII/src/Unix/ui/menu.ui
Normal file
84
BasiliskII/src/Unix/ui/menu.ui
Normal file
@ -0,0 +1,84 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<interface>
|
||||
<requires lib="gtk+" version="3.14"/>
|
||||
<menu id="app-menu">
|
||||
<section>
|
||||
<item>
|
||||
<attribute name="action">win.save-settings</attribute>
|
||||
<attribute name="label" translatable="yes">_Save Settings</attribute>
|
||||
</item>
|
||||
<item>
|
||||
<attribute name="action">win.zap-pram</attribute>
|
||||
<attribute name="label" translatable="yes">_Clear XPRAM Data</attribute>
|
||||
</item>
|
||||
</section>
|
||||
<section>
|
||||
<item>
|
||||
<attribute name="action">win.show-help-overlay</attribute>
|
||||
<attribute name="label" translatable="yes">_Keyboard Shortcuts</attribute>
|
||||
</item>
|
||||
<item>
|
||||
<attribute name="action">win.help</attribute>
|
||||
<attribute name="label" translatable="yes">_Help</attribute>
|
||||
</item>
|
||||
<item>
|
||||
<attribute name="action">win.about</attribute>
|
||||
<attribute name="label" translatable="yes">_About</attribute>
|
||||
</item>
|
||||
</section>
|
||||
<section>
|
||||
<item>
|
||||
<attribute name="action">win.quit</attribute>
|
||||
<attribute name="label" translatable="yes">_Quit</attribute>
|
||||
<attribute name="accel"><control>Q</attribute>
|
||||
</item>
|
||||
</section>
|
||||
</menu>
|
||||
<menu id="prefs-editor-menu">
|
||||
<submenu>
|
||||
<attribute name="label" translatable="yes">_File</attribute>
|
||||
<section>
|
||||
<item>
|
||||
<attribute name="action">win.start</attribute>
|
||||
<attribute name="label" translatable="yes">_Start Basilisk II</attribute>
|
||||
<attribute name="accel"><control>S</attribute>
|
||||
</item>
|
||||
<item>
|
||||
<attribute name="action">win.save-settings</attribute>
|
||||
<attribute name="label" translatable="yes">Sa_ve Settings</attribute>
|
||||
</item>
|
||||
<item>
|
||||
<attribute name="action">win.zap-pram</attribute>
|
||||
<attribute name="label" translatable="yes">_Clear XPRAM Data</attribute>
|
||||
</item>
|
||||
</section>
|
||||
<section>
|
||||
<item>
|
||||
<attribute name="action">win.quit</attribute>
|
||||
<attribute name="label" translatable="yes">_Quit</attribute>
|
||||
<attribute name="accel"><control>Q</attribute>
|
||||
</item>
|
||||
</section>
|
||||
</submenu>
|
||||
<submenu>
|
||||
<attribute name="label" translatable="yes">_Help</attribute>
|
||||
<section>
|
||||
<item>
|
||||
<attribute name="action">win.help</attribute>
|
||||
<attribute name="label" translatable="yes">_Help</attribute>
|
||||
<attribute name="accel">F1</attribute>
|
||||
</item>
|
||||
<item>
|
||||
<attribute name="action">win.show-help-overlay</attribute>
|
||||
<attribute name="label" translatable="yes">_Keyboard Shortcuts</attribute>
|
||||
</item>
|
||||
</section>
|
||||
<section>
|
||||
<item>
|
||||
<attribute name="action">win.about</attribute>
|
||||
<attribute name="label" translatable="yes">_About Basilisk II</attribute>
|
||||
</item>
|
||||
</section>
|
||||
</submenu>
|
||||
</menu>
|
||||
</interface>
|
2280
BasiliskII/src/Unix/ui/prefs-editor.ui
Normal file
2280
BasiliskII/src/Unix/ui/prefs-editor.ui
Normal file
File diff suppressed because it is too large
Load Diff
@ -62,6 +62,7 @@ user_string_def platform_strings[] = {
|
||||
|
||||
{STR_PREFS_MENU_FILE_GTK, "/_File"},
|
||||
{STR_PREFS_ITEM_START_GTK, "/File/_Start Basilisk II"},
|
||||
{STR_PREFS_ITEM_SAVE_GTK, "/File/Save _Preferences"},
|
||||
{STR_PREFS_ITEM_ZAP_PRAM_GTK, "/File/_Zap PRAM File"},
|
||||
{STR_PREFS_ITEM_SEPL_GTK, "/File/sepl"},
|
||||
{STR_PREFS_ITEM_QUIT_GTK, "/File/_Quit Basilisk II"},
|
||||
@ -73,7 +74,8 @@ user_string_def platform_strings[] = {
|
||||
{STR_DSPDEVICE_FILE_CTRL, "Audio Output Device"},
|
||||
{STR_MIXERDEVICE_FILE_CTRL, "Audio Mixer Device"},
|
||||
|
||||
{STR_BROWSE_TITLE, "Browse file"},
|
||||
{STR_BROWSE_TITLE, "Select File"},
|
||||
{STR_BROWSE_FOLDER_TITLE, "Select Folder"},
|
||||
{STR_BROWSE_CTRL, "Browse..."},
|
||||
{STR_INPUT_PANE_TITLE, "Keyboard/Mouse"},
|
||||
{STR_KEYCODES_CTRL, "Use Raw Keycodes"},
|
||||
@ -87,6 +89,22 @@ user_string_def platform_strings[] = {
|
||||
|
||||
{STR_NO_B2_EXE_FOUND, "Could not start %s (%s)."},
|
||||
|
||||
{STR_ABOUT_COPYRIGHT, "© 1997-2008 Christian Bauer et al."},
|
||||
{STR_ABOUT_LICENSE, "This program 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 Foundation; either version 2 of the License, or \
|
||||
(at your option) any later version.\n\n\
|
||||
This program 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.\n\n\
|
||||
You should have received a copy of the GNU General Public License \
|
||||
along with this program; if not, write to the Free Software \
|
||||
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA"},
|
||||
{STR_ABOUT_COMMENTS, "Open source 68k Mac emulator"},
|
||||
{STR_ABOUT_WEBSITE, "http://basilisk.cebix.net"},
|
||||
{STR_ABOUT_WEBSITE_LABEL, "Website"},
|
||||
|
||||
{-1, NULL} // End marker
|
||||
};
|
||||
|
||||
|
@ -53,6 +53,7 @@ enum {
|
||||
|
||||
STR_PREFS_MENU_FILE_GTK,
|
||||
STR_PREFS_ITEM_START_GTK,
|
||||
STR_PREFS_ITEM_SAVE_GTK,
|
||||
STR_PREFS_ITEM_ZAP_PRAM_GTK,
|
||||
STR_PREFS_ITEM_SEPL_GTK,
|
||||
STR_PREFS_ITEM_QUIT_GTK,
|
||||
@ -66,6 +67,7 @@ enum {
|
||||
|
||||
STR_BROWSE_CTRL,
|
||||
STR_BROWSE_TITLE,
|
||||
STR_BROWSE_FOLDER_TITLE,
|
||||
STR_INPUT_PANE_TITLE,
|
||||
STR_KEYCODES_CTRL,
|
||||
STR_KEYCODE_FILE_CTRL,
|
||||
@ -76,7 +78,13 @@ enum {
|
||||
|
||||
STR_IGNORESEGV_CTRL,
|
||||
|
||||
STR_NO_B2_EXE_FOUND
|
||||
STR_NO_B2_EXE_FOUND,
|
||||
|
||||
STR_ABOUT_COPYRIGHT,
|
||||
STR_ABOUT_LICENSE,
|
||||
STR_ABOUT_COMMENTS,
|
||||
STR_ABOUT_WEBSITE,
|
||||
STR_ABOUT_WEBSITE_LABEL
|
||||
};
|
||||
|
||||
#endif
|
||||
|
@ -37,6 +37,7 @@
|
||||
#include <sys/ipc.h>
|
||||
#include <sys/shm.h>
|
||||
#include <errno.h>
|
||||
#include <string>
|
||||
|
||||
#include <algorithm>
|
||||
|
||||
@ -113,7 +114,9 @@ static bool use_vosf = true; // Flag: VOSF enabled
|
||||
static const bool use_vosf = false; // VOSF not possible
|
||||
#endif
|
||||
|
||||
static bool ctrl_down = false; // Flag: Ctrl key pressed
|
||||
static bool ctrl_down = false; // Flag: Ctrl key pressed (for use with hotkeys)
|
||||
static bool opt_down = false; // Flag: Opt/Alt key pressed (for use with hotkeys)
|
||||
static bool cmd_down = false; // Flag: Cmd/Super/Win key pressed (for use with hotkeys)
|
||||
static bool caps_on = false; // Flag: Caps Lock on
|
||||
static bool quit_full_screen = false; // Flag: DGA close requested from redraw thread
|
||||
static bool emerg_quit = false; // Flag: Ctrl-Esc pressed, emergency quit requested from MacOS thread
|
||||
@ -215,6 +218,7 @@ public:
|
||||
|
||||
virtual void switch_to_current_mode(void);
|
||||
virtual void set_palette(uint8 *pal, int num);
|
||||
virtual void set_gamma(uint8 *gamma, int num);
|
||||
|
||||
bool video_open(void);
|
||||
void video_close(void);
|
||||
@ -225,6 +229,30 @@ public:
|
||||
* Utility functions
|
||||
*/
|
||||
|
||||
static bool is_hotkey_down()
|
||||
{
|
||||
int hotkey = PrefsFindInt32("hotkey");
|
||||
if (!hotkey) hotkey = 1;
|
||||
return (ctrl_down || !(hotkey & 1)) &&
|
||||
(opt_down || !(hotkey & 2)) &&
|
||||
(cmd_down || !(hotkey & 4));
|
||||
}
|
||||
|
||||
static int modify_opt_cmd(int code) {
|
||||
static bool f, c;
|
||||
if (!f) {
|
||||
f = true;
|
||||
c = PrefsFindBool("swap_opt_cmd");
|
||||
}
|
||||
if (c) {
|
||||
switch (code) {
|
||||
case 0x37: return 0x3a;
|
||||
case 0x3a: return 0x37;
|
||||
}
|
||||
}
|
||||
return code;
|
||||
}
|
||||
|
||||
// Map video_mode depth ID to numerical depth value
|
||||
static inline int depth_of_video_mode(video_mode const & mode)
|
||||
{
|
||||
@ -439,92 +467,38 @@ static void set_window_name(Window w, int name)
|
||||
XClassHint *hints;
|
||||
hints = XAllocClassHint();
|
||||
if (hints) {
|
||||
hints->res_name = "BasiliskII";
|
||||
hints->res_class = "BasiliskII";
|
||||
hints->res_name = (char*) GetString(STR_WINDOW_TITLE);
|
||||
hints->res_class = (char*) GetString(STR_WINDOW_TITLE);
|
||||
XSetClassHint(x_display, w, hints);
|
||||
XFree(hints);
|
||||
}
|
||||
}
|
||||
|
||||
// This struct is designed to match the ones generated by GIMP in
|
||||
// BasiliskII_*_icon.c
|
||||
struct gimp_image {
|
||||
unsigned int width;
|
||||
unsigned int height;
|
||||
unsigned int bytes_per_pixel;
|
||||
unsigned char pixel_data[0]; // Variable-length
|
||||
};
|
||||
|
||||
// These were generated by using 'icns2png -x
|
||||
// ../MacOSX/BasiliskII.icns', then using GIMP to convert the
|
||||
// resulting .png files into "C source code (*.c)". GIMP doesn't
|
||||
// generate corresponding .h files with extern declarations, so just
|
||||
// #include the .c files here.
|
||||
#include "BasiliskII_32x32x32_icon.c"
|
||||
#include "BasiliskII_128x128x32_icon.c"
|
||||
|
||||
// Set window icons
|
||||
static void set_window_icons(Window w)
|
||||
{
|
||||
// As per the _NET_WM_ICON documentation at
|
||||
// https://standards.freedesktop.org/wm-spec/wm-spec-latest.html#idm140200472568384,
|
||||
// "The first two cardinals are width, height."
|
||||
const unsigned int HEADER_SIZE = 2;
|
||||
// We will pass 32-bit values to XChangeProperty()
|
||||
const unsigned int FORMAT = 32;
|
||||
|
||||
// Icon data from GIMP to be converted and passed to the
|
||||
// Window Manager
|
||||
const struct gimp_image* const icons[] =
|
||||
{(struct gimp_image *) &icon_32x32x32,
|
||||
(struct gimp_image *) &icon_128x128x32};
|
||||
const unsigned int num_icons = sizeof(icons) / sizeof(icons[0]);
|
||||
unsigned int icon;
|
||||
|
||||
// Work out how big the buffer needs to be to store all of our icons
|
||||
unsigned int buffer_size = 0;
|
||||
for (icon = 0; icon < num_icons; icon++) {
|
||||
buffer_size += HEADER_SIZE +
|
||||
icons[icon]->width * icons[icon]->height;
|
||||
// Set window name and class (ported from SDL implementation)
|
||||
static void set_window_name(Window w, bool mouse_grabbed) {
|
||||
const char *title = PrefsFindString("title");
|
||||
std::string s = title ? title : GetString(STR_WINDOW_TITLE);
|
||||
if (mouse_grabbed)
|
||||
{
|
||||
s += GetString(STR_WINDOW_TITLE_GRABBED_PRE);
|
||||
int hotkey = PrefsFindInt32("hotkey");
|
||||
hotkey = hotkey ? hotkey : 1;
|
||||
if (hotkey & 1) s += GetString(STR_WINDOW_TITLE_GRABBED1);
|
||||
if (hotkey & 2) s += GetString(STR_WINDOW_TITLE_GRABBED2);
|
||||
if (hotkey & 4) s += GetString(STR_WINDOW_TITLE_GRABBED4);
|
||||
s += GetString(STR_WINDOW_TITLE_GRABBED_POST);
|
||||
}
|
||||
XStoreName(x_display, w, s.c_str());
|
||||
XSetIconName(x_display, w, GetString(STR_WINDOW_TITLE));
|
||||
|
||||
// As per the XChangeProperty() man page, "If the specified
|
||||
// format is 32, the property data must be a long array."
|
||||
unsigned long buffer[buffer_size];
|
||||
// This points to the start of the current icon within buffer
|
||||
unsigned long *buffer_icon = buffer;
|
||||
|
||||
// Copy the icons into the buffer
|
||||
for (icon = 0; icon < num_icons; icon++) {
|
||||
const unsigned int pixel_count = icons[icon]->width *
|
||||
icons[icon]->height;
|
||||
assert(icons[icon]->bytes_per_pixel == 4);
|
||||
buffer_icon[0] = icons[icon]->width;
|
||||
buffer_icon[1] = icons[icon]->height;
|
||||
unsigned long *const buffer_pixels = buffer_icon + HEADER_SIZE;
|
||||
|
||||
unsigned int i;
|
||||
for (i = 0; i < pixel_count; i++) {
|
||||
const unsigned char *src =
|
||||
&icons[icon]->pixel_data[i * icons[icon]->bytes_per_pixel];
|
||||
buffer_pixels[i] = (src[3] << 24 |
|
||||
src[0] << 16 |
|
||||
src[1] << 8 |
|
||||
src[2]);
|
||||
}
|
||||
|
||||
buffer_icon += HEADER_SIZE + pixel_count;
|
||||
XClassHint *hints;
|
||||
hints = XAllocClassHint();
|
||||
if (hints) {
|
||||
hints->res_name = (char*) GetString(STR_WINDOW_TITLE);
|
||||
hints->res_class = (char*) GetString(STR_WINDOW_TITLE);
|
||||
XSetClassHint(x_display, w, hints);
|
||||
XFree(hints);
|
||||
}
|
||||
|
||||
Atom net_wm_icon = XInternAtom(x_display, "_NET_WM_ICON", False);
|
||||
if (net_wm_icon == None) {
|
||||
ErrorAlert(STR_X_ICON_ATOM_ALLOC_ERR);
|
||||
// We can still continue running, just without an icon
|
||||
return;
|
||||
}
|
||||
XChangeProperty(x_display, w, net_wm_icon, XA_CARDINAL, FORMAT,
|
||||
PropModeReplace, (const unsigned char *) buffer,
|
||||
buffer_size);
|
||||
}
|
||||
|
||||
// Set window input focus flag
|
||||
@ -813,10 +787,7 @@ driver_window::driver_window(X11_monitor_desc &m)
|
||||
D(bug(" window created\n"));
|
||||
|
||||
// Set window name/class
|
||||
set_window_name(w, STR_WINDOW_TITLE);
|
||||
|
||||
// Set window icons
|
||||
set_window_icons(w);
|
||||
set_window_name(w, mouse_grabbed);
|
||||
|
||||
// Indicate that we want keyboard input
|
||||
set_window_focus(w);
|
||||
@ -972,7 +943,7 @@ void driver_window::grab_mouse(void)
|
||||
Delay_usec(100000);
|
||||
}
|
||||
if (result == GrabSuccess) {
|
||||
XStoreName(x_display, w, GetString(STR_WINDOW_TITLE_GRABBED));
|
||||
set_window_name(w, true);
|
||||
ADBSetRelMouseMode(mouse_grabbed = true);
|
||||
disable_mouse_accel();
|
||||
}
|
||||
@ -983,7 +954,7 @@ void driver_window::ungrab_mouse(void)
|
||||
{
|
||||
if (mouse_grabbed) {
|
||||
XUngrabPointer(x_display, CurrentTime);
|
||||
XStoreName(x_display, w, GetString(STR_WINDOW_TITLE));
|
||||
set_window_name(w, false);
|
||||
ADBSetRelMouseMode(mouse_grabbed = false);
|
||||
restore_mouse_accel();
|
||||
}
|
||||
@ -1053,9 +1024,13 @@ driver_dga::~driver_dga()
|
||||
// Suspend emulation
|
||||
void driver_dga::suspend(void)
|
||||
{
|
||||
// Release ctrl key
|
||||
// Release hotkeys
|
||||
ADBKeyUp(0x36);
|
||||
ctrl_down = false;
|
||||
ADBKeyUp(0x37);
|
||||
cmd_down = false;
|
||||
ADBKeyUp(0x3a);
|
||||
opt_down = false;
|
||||
|
||||
// Lock frame buffer (this will stop the MacOS thread)
|
||||
LOCK_FRAME_BUFFER;
|
||||
@ -1233,7 +1208,7 @@ driver_fbdev::driver_fbdev(X11_monitor_desc &m) : driver_dga(m)
|
||||
&wattr);
|
||||
|
||||
// Set window name/class
|
||||
set_window_name(w, STR_WINDOW_TITLE);
|
||||
set_window_name(w, false);
|
||||
|
||||
// Indicate that we want keyboard input
|
||||
set_window_focus(w);
|
||||
@ -1370,7 +1345,7 @@ driver_xf86dga::driver_xf86dga(X11_monitor_desc &m)
|
||||
(color_class == DirectColor ? CWColormap : 0), &wattr);
|
||||
|
||||
// Set window name/class
|
||||
set_window_name(w, STR_WINDOW_TITLE);
|
||||
set_window_name(w, false);
|
||||
|
||||
// Indicate that we want keyboard input
|
||||
set_window_focus(w);
|
||||
@ -1780,7 +1755,7 @@ bool VideoInit(bool classic)
|
||||
default_width = -1; default_height = -1; // use entire screen
|
||||
#endif
|
||||
#ifdef ENABLE_XF86_DGA
|
||||
} else if (has_dga && sscanf(mode_str, "dga/%d/%d", &default_width, &default_height) == 2) {
|
||||
} else if (has_dga & sscanf(mode_str, "dga/%d/%d", &default_width, &default_height) == 2) {
|
||||
display_type = DISPLAY_DGA;
|
||||
#endif
|
||||
}
|
||||
@ -2015,6 +1990,10 @@ void X11_monitor_desc::set_palette(uint8 *pal, int num_in)
|
||||
UNLOCK_PALETTE;
|
||||
}
|
||||
|
||||
void X11_monitor_desc::set_gamma(uint8* gamma, int num)
|
||||
{
|
||||
// Not implemented
|
||||
}
|
||||
|
||||
/*
|
||||
* Switch video mode
|
||||
@ -2091,7 +2070,7 @@ static int kc_decode(KeySym ks, bool key_down)
|
||||
case XK_period: case XK_greater: return 0x2f;
|
||||
case XK_slash: case XK_question: return 0x2c;
|
||||
|
||||
case XK_Tab: if (ctrl_down) {if (key_down) drv->suspend(); return -2;} else return 0x30;
|
||||
case XK_Tab: if (is_hotkey_down()) {if (key_down) drv->suspend(); return -2;} else return 0x30;
|
||||
case XK_Return: return 0x24;
|
||||
case XK_space: return 0x31;
|
||||
case XK_BackSpace: return 0x33;
|
||||
@ -2112,10 +2091,10 @@ static int kc_decode(KeySym ks, bool key_down)
|
||||
case XK_Control_R: return 0x36;
|
||||
case XK_Shift_L: return 0x38;
|
||||
case XK_Shift_R: return 0x38;
|
||||
case XK_Alt_L: return 0x37;
|
||||
case XK_Alt_R: return 0x37;
|
||||
case XK_Meta_L: return 0x3a;
|
||||
case XK_Meta_R: return 0x3a;
|
||||
case XK_Alt_L: return 0x3a;
|
||||
case XK_Alt_R: return 0x3a;
|
||||
case XK_Meta_L: return 0x37;
|
||||
case XK_Meta_R: return 0x37;
|
||||
case XK_Menu: return 0x32;
|
||||
case XK_Caps_Lock: return 0x39;
|
||||
case XK_Num_Lock: return 0x47;
|
||||
@ -2125,13 +2104,13 @@ static int kc_decode(KeySym ks, bool key_down)
|
||||
case XK_Left: return 0x3b;
|
||||
case XK_Right: return 0x3c;
|
||||
|
||||
case XK_Escape: if (ctrl_down) {if (key_down) { quit_full_screen = true; emerg_quit = true; } return -2;} else return 0x35;
|
||||
case XK_Escape: if (is_hotkey_down()) {if (key_down) { quit_full_screen = true; emerg_quit = true; } return -2;} else return 0x35;
|
||||
|
||||
case XK_F1: if (ctrl_down) {if (key_down) SysMountFirstFloppy(); return -2;} else return 0x7a;
|
||||
case XK_F1: if (is_hotkey_down()) {if (key_down) SysMountFirstFloppy(); return -2;} else return 0x7a;
|
||||
case XK_F2: return 0x78;
|
||||
case XK_F3: return 0x63;
|
||||
case XK_F4: return 0x76;
|
||||
case XK_F5: if (ctrl_down) {if (key_down) drv->toggle_mouse_grab(); return -2;} else return 0x60;
|
||||
case XK_F5: if (is_hotkey_down()) {if (key_down) drv->toggle_mouse_grab(); return -2;} else return 0x60;
|
||||
case XK_F6: return 0x61;
|
||||
case XK_F7: return 0x62;
|
||||
case XK_F8: return 0x64;
|
||||
@ -2267,12 +2246,23 @@ static void handle_events(void)
|
||||
|
||||
// Keyboard
|
||||
case KeyPress: {
|
||||
int code = -1;
|
||||
int code = event2keycode(event.xkey, true);
|
||||
if(!emul_suspended)
|
||||
{
|
||||
if (code == 0x36) {
|
||||
ctrl_down = true;
|
||||
} else if (code == 0x3a) {
|
||||
opt_down = true;
|
||||
code = modify_opt_cmd(code);
|
||||
} else if (code == 0x37) {
|
||||
cmd_down = true;
|
||||
code = modify_opt_cmd(code);
|
||||
}
|
||||
}
|
||||
if (use_keycodes) {
|
||||
if (event2keycode(event.xkey, true) != -2) // This is called to process the hotkeys
|
||||
if (code != -2) // This is called to process the hotkeys
|
||||
code = keycode_table[event.xkey.keycode & 0xff];
|
||||
} else
|
||||
code = event2keycode(event.xkey, true);
|
||||
}
|
||||
if (code >= 0) {
|
||||
if (!emul_suspended) {
|
||||
if (code == 0x39) { // Caps Lock pressed
|
||||
@ -2285,8 +2275,6 @@ static void handle_events(void)
|
||||
}
|
||||
} else
|
||||
ADBKeyDown(code);
|
||||
if (code == 0x36)
|
||||
ctrl_down = true;
|
||||
} else {
|
||||
if (code == 0x31)
|
||||
drv->resume(); // Space wakes us up
|
||||
@ -2295,16 +2283,25 @@ static void handle_events(void)
|
||||
break;
|
||||
}
|
||||
case KeyRelease: {
|
||||
int code = -1;
|
||||
int code = event2keycode(event.xkey, false);
|
||||
if(!emul_suspended)
|
||||
{
|
||||
if (code == 0x36) {
|
||||
ctrl_down = false;
|
||||
} else if (code == 0x3a) {
|
||||
opt_down = false;
|
||||
code = modify_opt_cmd(code);
|
||||
} else if (code == 0x37) {
|
||||
cmd_down = false;
|
||||
code = modify_opt_cmd(code);
|
||||
}
|
||||
}
|
||||
if (use_keycodes) {
|
||||
if (event2keycode(event.xkey, false) != -2) // This is called to process the hotkeys
|
||||
if (code != -2) // This is called to process the hotkeys
|
||||
code = keycode_table[event.xkey.keycode & 0xff];
|
||||
} else
|
||||
code = event2keycode(event.xkey, false);
|
||||
}
|
||||
if (code >= 0 && code != 0x39) { // Don't propagate Caps Lock releases
|
||||
ADBKeyUp(code);
|
||||
if (code == 0x36)
|
||||
ctrl_down = false;
|
||||
}
|
||||
break;
|
||||
}
|
||||
@ -2359,10 +2356,10 @@ static void update_display_dynamic(int ticker, driver_window *drv)
|
||||
y2s = sm_uptd[ticker % 8];
|
||||
y2a = 8;
|
||||
for (i = 0; i < 6; i++) {
|
||||
max_box = sm_no_boxes[i];
|
||||
if (ticker % (2 << i))
|
||||
break;
|
||||
}
|
||||
max_box = sm_no_boxes[i];
|
||||
|
||||
if (y2a) {
|
||||
for (y1=0; y1<16; y1++) {
|
||||
|
@ -20,11 +20,68 @@
|
||||
|
||||
#include "sysdeps.h"
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <string>
|
||||
using std::string;
|
||||
|
||||
#include "xpram.h"
|
||||
|
||||
|
||||
#ifdef __linux__
|
||||
|
||||
|
||||
// XPRAM file name, set by LoadPrefs() in prefs_unix.cpp
|
||||
string xpram_name;
|
||||
|
||||
/*
|
||||
* Load XPRAM from settings file
|
||||
*/
|
||||
|
||||
void LoadXPRAM(const char* vmdir)
|
||||
{
|
||||
assert(!xpram_name.empty());
|
||||
int fd;
|
||||
if ((fd = open(xpram_name.c_str(), O_RDONLY)) >= 0)
|
||||
{
|
||||
read(fd, XPRAM, XPRAM_SIZE);
|
||||
close(fd);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Save XPRAM to settings file
|
||||
*/
|
||||
|
||||
void SaveXPRAM(void)
|
||||
{
|
||||
assert(!xpram_name.empty());
|
||||
int fd;
|
||||
if ((fd = open(xpram_name.c_str(), O_WRONLY | O_CREAT, 0666)) >= 0)
|
||||
{
|
||||
write(fd, XPRAM, XPRAM_SIZE);
|
||||
close(fd);
|
||||
}
|
||||
else
|
||||
{
|
||||
fprintf(stderr, "WARNING: Unable to save %s (%s)\n",
|
||||
xpram_name.c_str(), strerror(errno));
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Delete PRAM file
|
||||
*/
|
||||
|
||||
void ZapPRAM(void)
|
||||
{
|
||||
// Delete file
|
||||
assert(!xpram_name.empty());
|
||||
unlink(xpram_name.c_str());
|
||||
}
|
||||
|
||||
|
||||
#else // __linux__
|
||||
|
||||
|
||||
// XPRAM file name and path
|
||||
#if POWERPC_ROM
|
||||
const char XPRAM_FILE_NAME[] = ".sheepshaver_nvram";
|
||||
@ -98,3 +155,7 @@ void ZapPRAM(void)
|
||||
// Delete file
|
||||
unlink(xpram_path);
|
||||
}
|
||||
|
||||
|
||||
#endif // __linux__
|
||||
|
||||
|
Binary file not shown.
Before Width: | Height: | Size: 2.9 KiB After Width: | Height: | Size: 141 KiB |
18
BasiliskII/src/Windows/Makefile.in
Executable file → Normal file
18
BasiliskII/src/Windows/Makefile.in
Executable file → Normal file
@ -31,6 +31,8 @@ SLIRP_SRCS = \
|
||||
../slirp/ip_input.c ../slirp/socket.c ../slirp/udp.c
|
||||
SLIRP_OBJS = $(SLIRP_SRCS:../slirp/%.c=$(OBJ_DIR)/slirp-%.o)
|
||||
|
||||
USE_BINCUE = @USE_BINCUE@
|
||||
|
||||
LN_S = @LN_S@
|
||||
WINDRES = @WINDRES@
|
||||
CC = @CC@
|
||||
@ -42,6 +44,7 @@ DEFS = @DEFS@ @DEFINES@
|
||||
LDFLAGS = @LDFLAGS@ -Wl,-Bstatic
|
||||
LIBS = @LIBS@ -lws2_32 -lwsock32 -liphlpapi
|
||||
CPUSRCS = @CPUSRCS@
|
||||
EXTRASRCS = @EXTRASRCS@
|
||||
|
||||
HOST_CC = gcc
|
||||
HOST_CXX = g++
|
||||
@ -63,12 +66,13 @@ SRCS = ../main.cpp main_windows.cpp ../prefs.cpp ../prefs_items.cpp prefs_window
|
||||
../emul_op.cpp ../macos_util.cpp ../xpram.cpp xpram_windows.cpp ../timer.cpp \
|
||||
timer_windows.cpp ../adb.cpp ../serial.cpp serial_windows.cpp \
|
||||
../ether.cpp ether_windows.cpp ../sony.cpp ../disk.cpp ../cdrom.cpp \
|
||||
../scsi.cpp ../dummy/scsi_dummy.cpp ../video.cpp ../SDL/video_sdl.cpp ../SDL/video_sdl2.cpp \
|
||||
video_blit.cpp ../audio.cpp ../SDL/audio_sdl.cpp clip_windows.cpp \
|
||||
../scsi.cpp ../dummy/scsi_dummy.cpp ../video.cpp \
|
||||
../SDL/video_sdl.cpp ../SDL/video_sdl2.cpp ../SDL/video_sdl3.cpp \
|
||||
video_blit.cpp ../audio.cpp ../SDL/audio_sdl.cpp ../SDL/audio_sdl3.cpp clip_windows.cpp \
|
||||
../extfs.cpp extfs_windows.cpp ../user_strings.cpp user_strings_windows.cpp \
|
||||
vm_alloc.cpp sigsegv.cpp posix_emu.cpp util_windows.cpp \
|
||||
../dummy/prefs_editor_dummy.cpp BasiliskII.rc \
|
||||
$(CDENABLESRCS) $(ROUTERSRCS) $(CPUSRCS) $(SLIRP_OBJS)
|
||||
$(CDENABLESRCS) $(ROUTERSRCS) $(CPUSRCS) $(EXTRASRCS) $(SLIRP_OBJS)
|
||||
|
||||
UI_SRCS = ../prefs.cpp prefs_windows.cpp prefs_editor_gtk.cpp xpram_windows.cpp \
|
||||
../prefs_items.cpp ../user_strings.cpp user_strings_windows.cpp util_windows.cpp \
|
||||
@ -118,7 +122,7 @@ $(APP): $(XPLATSRCS) $(OBJ_DIR) $(OBJS)
|
||||
$(CXX) -o $@ $(LDFLAGS) $(OBJS) $(LIBS) $(SDL_LIBS)
|
||||
|
||||
$(UI_APP): $(XPLATSRCS) $(OBJ_DIR) $(UI_OBJS)
|
||||
$(CXX) -o $@ $(LDFLAGS) $(UI_OBJS) $(LIBS) $(GTK_LIBS) -mwindows -mno-cygwin
|
||||
$(CXX) -o $@ $(LDFLAGS) $(UI_OBJS) $(LIBS) -Wl,-Bdynamic $(GTK_LIBS) -Wl,-Bstatic -mwindows -static-libgcc
|
||||
|
||||
mostlyclean:
|
||||
rm -f $(APP) $(UI_APP) $(OBJ_DIR)/* core* *.core *~ *.bak
|
||||
@ -134,7 +138,9 @@ distclean: clean
|
||||
rm -f config.cache config.log config.status config.h
|
||||
|
||||
depend dep:
|
||||
makedepend $(CPPFLAGS) -Y. $(SRCS) 2>/dev/null
|
||||
makedepend $(CPPFLAGS) # Truncate out previous rules
|
||||
# Manually process emitted obj targets to take out extra directory layers
|
||||
makedepend $(CPPFLAGS) -pobj/ -Y. $(SRCS) -f- 2>/dev/null | sed 's#^obj/.*/\(.*\.o\):#obj/\1:#' >> Makefile
|
||||
|
||||
$(OBJ_DIR)/%.ho : %.c
|
||||
$(HOST_CC) $(CPPFLAGS) $(DEFS) $(HOST_CFLAGS) -c $< -o $@
|
||||
@ -149,7 +155,7 @@ $(OBJ_DIR)/%.o : %.cpp
|
||||
$(OBJ_DIR)/%.o : %.s
|
||||
$(CC) $(CPPFLAGS) $(DEFS) $(CFLAGS) -c $< -o $@
|
||||
$(OBJ_DIR)/prefs_editor_gtk.o: prefs_editor_gtk.cpp
|
||||
$(CXX) -O2 -mno-cygwin -mms-bitfields $(CPPFLAGS) $(DEFS) $(GTK_CFLAGS) -c $< -o $@
|
||||
$(CXX) -O2 -mms-bitfields $(CPPFLAGS) $(DEFS) $(GTK_CFLAGS) -c $< -o $@
|
||||
|
||||
# Windows resources
|
||||
$(OBJ_DIR)/%.o: %.rc
|
||||
|
@ -24,6 +24,10 @@
|
||||
|
||||
#include <winioctl.h>
|
||||
|
||||
#define DEBUG 0
|
||||
#include "debug.h"
|
||||
|
||||
|
||||
// Prototypes
|
||||
|
||||
extern "C" {
|
||||
@ -128,12 +132,17 @@ BOOL PreventRemovalOfVolume(HANDLE hVolume, BOOL fPreventRemoval)
|
||||
|
||||
PMRBuffer.PreventMediaRemoval = fPreventRemoval;
|
||||
|
||||
return DeviceIoControl( hVolume,
|
||||
IOCTL_STORAGE_MEDIA_REMOVAL,
|
||||
BOOL ret = DeviceIoControl( hVolume,
|
||||
IOCTL_STORAGE_EJECTION_CONTROL,
|
||||
&PMRBuffer, sizeof(PREVENT_MEDIA_REMOVAL),
|
||||
NULL, 0,
|
||||
&dwBytesReturned,
|
||||
NULL);
|
||||
D(bug(" PreventRemoval IOCTL returned %d\n", ret));
|
||||
if (!ret) {
|
||||
D(bug(" failed, last error %d\n", GetLastError()));
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
BOOL AutoEjectVolume( HANDLE hVolume, BOOL reload )
|
||||
|
74
BasiliskII/src/Windows/configure.ac
Executable file → Normal file
74
BasiliskII/src/Windows/configure.ac
Executable file → Normal file
@ -11,9 +11,6 @@ dnl Aliases for PACKAGE and VERSION macros.
|
||||
AC_DEFINE_UNQUOTED(PACKAGE, "$PACKAGE_NAME", [Define this program name.])
|
||||
AC_DEFINE_UNQUOTED(VERSION, "$PACKAGE_VERSION", [Define this program version.])
|
||||
|
||||
dnl SDL options.
|
||||
#AC_ARG_ENABLE(sdl-static, [ --enable-sdl-static use SDL static libraries for linking [default=no]], [WANT_SDL_STATIC=$enableval], [WANT_SDL_STATIC=no])
|
||||
|
||||
dnl JIT compiler options.
|
||||
AC_ARG_ENABLE(jit-compiler, [ --enable-jit-compiler enable JIT compiler [default=yes]], [WANT_JIT=$enableval], [WANT_JIT=yes])
|
||||
AC_ARG_ENABLE(jit-debug, [ --enable-jit-debug activate native code disassemblers [default=no]], [WANT_JIT_DEBUG=$enableval], [WANT_JIT_DEBUG=no])
|
||||
@ -35,6 +32,10 @@ AC_ARG_ENABLE(fpe,
|
||||
|
||||
dnl External packages.
|
||||
AC_ARG_WITH(gtk, [ --with-gtk use GTK user interface [default=yes]], [WANT_GTK=$withval], [WANT_GTK=yes])
|
||||
AC_ARG_ENABLE(vosf, [ --enable-vosf enable video on SEGV signals [default=no]], [WANT_VOSF=$enableval], [WANT_VOSF=no])
|
||||
|
||||
AC_ARG_WITH(bincue,
|
||||
AS_HELP_STRING([--with-bincue], [Allow cdrom image files in bin/cue mode]))
|
||||
|
||||
dnl Addressing modes.
|
||||
AC_ARG_ENABLE(addressing,
|
||||
@ -49,6 +50,8 @@ AC_ARG_ENABLE(addressing,
|
||||
[ ADDRESSING_TEST_ORDER="direct banks"
|
||||
])
|
||||
|
||||
AC_ARG_WITH(sdl3, [ --with-sdl3 use SDL 3.x, rather than SDL 2.x [default=no]], [WANT_SDL_VERSION_MAJOR=3], [WANT_SDL_VERSION_MAJOR=2])
|
||||
|
||||
dnl Canonical system information.
|
||||
AC_CANONICAL_HOST
|
||||
AC_CANONICAL_TARGET
|
||||
@ -85,6 +88,14 @@ AC_SUBST(WANT_GTK)
|
||||
dnl We use 64-bit file size support if possible.
|
||||
AC_SYS_LARGEFILE
|
||||
|
||||
dnl BINCUE
|
||||
AS_IF([test "x$with_bincue" = "xyes" ], [have_bincue=yes], [have_bincue=no])
|
||||
AS_IF([test "x$have_bincue" = "xyes" ], [
|
||||
DEFINES="$DEFINES -DBINCUE"
|
||||
CPPFLAGS="$CPPFLAGS -DBINCUE"
|
||||
AC_SUBST(USE_BINCUE, yes)
|
||||
], [AC_SUBST(USE_BINCUE, no)])
|
||||
|
||||
dnl Checks for header files.
|
||||
AC_HEADER_STDC
|
||||
|
||||
@ -200,8 +211,12 @@ AC_CACHE_CHECK([whether we can skip instruction in SIGSEGV handler],
|
||||
AC_TRANSLATE_DEFINE(HAVE_SIGSEGV_SKIP_INSTRUCTION, "$ac_cv_have_skip_instruction",
|
||||
[Define if we can ignore the fault (instruction skipping in SIGSEGV handler).])
|
||||
|
||||
dnl We really want VOSF (Video on SEGV Signals) screen updates acceleration
|
||||
AC_DEFINE(ENABLE_VOSF, 1, [Define if using video enabled on SEGV signals.])
|
||||
dnl Enable VOSF screen updates with this feature is requested
|
||||
if [[ "x$WANT_VOSF" = "xyes" ]]; then
|
||||
AC_DEFINE(ENABLE_VOSF, 1, [Define if using video enabled on SEGV signals.])
|
||||
else
|
||||
WANT_VOSF=no
|
||||
fi
|
||||
|
||||
dnl Determine the addressing mode to use
|
||||
ADDRESSING_MODE=""
|
||||
@ -269,10 +284,13 @@ if [[ "x$HAVE_GCC30" = "xyes" ]]; then
|
||||
AC_CACHE_CHECK([whether the compiler supports -fno-strict-aliasing],
|
||||
ac_cv_gcc_no_strict_aliasing, [
|
||||
AC_TRY_COMPILE([],[],
|
||||
[ac_cv_gcc_no_strict_aliasing=yes; AC_SUBST(SLIRP_CFLAGS, "-fno-strict-aliasing")],
|
||||
[ac_cv_gcc_no_strict_aliasing=yes],
|
||||
[ac_cv_gcc_no_strict_aliasing=no])
|
||||
])
|
||||
CFLAGS="$SAVED_CFLAGS"
|
||||
if test "x$ac_cv_gcc_no_strict_aliasing" = xyes; then
|
||||
AC_SUBST(SLIRP_CFLAGS, "-fno-strict-aliasing")
|
||||
fi
|
||||
fi
|
||||
|
||||
dnl Select appropriate CPU source and REGPARAM define.
|
||||
@ -304,6 +322,11 @@ elif [[ "x$HAVE_GCC30" = "xyes" -a "x$HAVE_X86_64" = "xyes" ]]; then
|
||||
fi
|
||||
fi
|
||||
|
||||
dnl BINCUE overrides
|
||||
if [[ "x$have_bincue" = "xyes" ]]; then
|
||||
EXTRASRCS="$EXTRASRCS bincue.cpp"
|
||||
fi
|
||||
|
||||
dnl Enable JIT compiler, if possible.
|
||||
if [[ "x$WANT_JIT" = "xyes" -a "x$CAN_JIT" ]]; then
|
||||
JITSRCS="$JITSRCS ../uae_cpu/compiler/compemu_support.cpp ../uae_cpu/compiler/compemu_fpp.cpp compstbl.o cpustbl_nf.o"
|
||||
@ -354,7 +377,19 @@ cat > conftest.$ac_ext <<EOF
|
||||
#include "confdefs.h"
|
||||
$1
|
||||
]EOF
|
||||
ac_save_CFLAGS=$CFLAGS
|
||||
CFLAGS="$CFLAGS -fno-lto"
|
||||
gcc_ac_compile_ok=0
|
||||
if AC_TRY_EVAL(ac_compile); then
|
||||
gcc_ac_compile_ok=1
|
||||
else
|
||||
CFLAGS=$ac_save_CFLAGS
|
||||
if AC_TRY_EVAL(ac_compile); then
|
||||
gcc_ac_compile_ok=1
|
||||
fi
|
||||
fi
|
||||
CFLAGS=$ac_save_CFLAGS
|
||||
if test "$gcc_ac_compile_ok" = 1; then
|
||||
od -c conftest.o |
|
||||
sed ['s/^[0-7]*[ ]*/ /
|
||||
s/\*/./g
|
||||
@ -524,19 +559,15 @@ CPUINCLUDES="-I../uae_cpu"
|
||||
CPUSRCS="../uae_cpu/basilisk_glue.cpp ../uae_cpu/memory.cpp ../uae_cpu/newcpu.cpp ../uae_cpu/readcpu.cpp $FPUSRCS cpustbl.cpp cpudefs.cpp $CPUSRCS $JITSRCS"
|
||||
|
||||
dnl We really want SDL for now
|
||||
AC_CHECK_TOOL(sdl_config, sdl2-config, [AC_MSG_ERROR([Sorry, you currently need SDL for this port])])
|
||||
SDL_CFLAGS=`$sdl_config --cflags`
|
||||
if [[ "x$WANT_SDL_VERSION_MAJOR" = "x3" ]]; then
|
||||
SDL_CFLAGS=`pkg-config sdl3 --cflags`
|
||||
SDL_CFLAGS="$SDL_CFLAGS `echo " $SDL_CFLAGS" | sed -e 's/\(-I.*include\)/\1\/SDL3/'`"
|
||||
SDL_LIBS=`pkg-config sdl3 --libs | sed -e 's/-lSDL3/-lSDL3.dll/'`
|
||||
else
|
||||
SDL_CFLAGS=`sdl2-config --cflags`
|
||||
SDL_LIBS=`sdl2-config --static-libs`
|
||||
fi
|
||||
AC_SUBST(SDL_CFLAGS)
|
||||
#if [[ "x$WANT_SDL_STATIC" = "xyes" ]]; then
|
||||
SDL_LIBS=`$sdl_config --static-libs`
|
||||
# sdl_prefix=`$sdl_config --exec-prefix`
|
||||
# if [[ -n "$sdl_prefix" ]]; then
|
||||
# SDL_LIBS=`echo "$SDL_LIBS" | sed -e "s,-l\(SDLmain\|SDL\),$sdl_prefix/lib/lib\1.a,g"`
|
||||
# fi
|
||||
# SDL_LIBS="$SDL_LIBS -lwinmm"
|
||||
#else
|
||||
# SDL_LIBS=`$sdl_config --libs`
|
||||
#fi
|
||||
AC_SUBST(SDL_LIBS)
|
||||
AC_DEFINE(USE_SDL, 1, [Define to enble SDL support])
|
||||
AC_DEFINE(USE_SDL_VIDEO, 1, [Define to enable SDL video graphics support])
|
||||
@ -548,10 +579,14 @@ if [[ "x$HAVE_GCC27" = "xyes" ]]; then
|
||||
CXXFLAGS=`echo $CXXFLAGS | sed -e 's/-g\b//g'`
|
||||
fi
|
||||
|
||||
CFLAGS="$CFLAGS -fwrapv"
|
||||
CXXFLAGS="$CXXFLAGS -fwrapv"
|
||||
|
||||
dnl Generate Makefile.
|
||||
AC_SUBST(DEFINES)
|
||||
AC_SUBST(CPUINCLUDES)
|
||||
AC_SUBST(CPUSRCS)
|
||||
AC_SUBST(EXTRASRCS)
|
||||
AC_CONFIG_FILES([Makefile])
|
||||
AC_OUTPUT
|
||||
|
||||
@ -559,11 +594,14 @@ dnl Print summary.
|
||||
echo
|
||||
echo Basilisk II configuration summary:
|
||||
echo
|
||||
echo SDL major-version ...................... : $WANT_SDL_VERSION_MAJOR
|
||||
echo Use JIT compiler ....................... : $WANT_JIT
|
||||
echo JIT debug mode ......................... : $WANT_JIT_DEBUG
|
||||
echo Floating-Point emulation core .......... : $FPE_CORE
|
||||
echo Assembly optimizations ................. : $ASM_OPTIMIZATIONS
|
||||
echo Addressing mode ........................ : $ADDRESSING_MODE
|
||||
echo BINCUE support ......................... : $have_bincue
|
||||
echo GTK user interface ..................... : $WANT_GTK
|
||||
echo Enable VOSF ............................ : $WANT_VOSF
|
||||
echo
|
||||
echo "Configuration done. Now type \"make\" (or \"gmake\")."
|
||||
|
@ -42,6 +42,7 @@
|
||||
// somehow util_windows undefines min
|
||||
#define min(x,y) ((x) < (y) ? (x) : (y))
|
||||
#include "libslirp.h"
|
||||
#include "ctl.h"
|
||||
|
||||
// Define to let the slirp library determine the right timeout for select()
|
||||
#define USE_SLIRP_TIMEOUT 1
|
||||
@ -101,6 +102,14 @@ static int net_if_type = -1; // Ethernet device type
|
||||
#ifdef SHEEPSHAVER
|
||||
static bool net_open = false; // Flag: initialization succeeded, network device open
|
||||
uint8 ether_addr[6]; // Our Ethernet address
|
||||
|
||||
#else
|
||||
const bool ether_driver_opened = true; // Flag: Driver is open on MacOS side
|
||||
// so ether.h layer is ready for
|
||||
// calls.
|
||||
// B2 doesn't provide this
|
||||
// but also calls don't need it
|
||||
|
||||
#endif
|
||||
|
||||
// These are protected by queue_csection
|
||||
@ -136,6 +145,8 @@ static LPPACKET send_queue = 0;
|
||||
static CRITICAL_SECTION wpool_csection;
|
||||
static LPPACKET write_packet_pool = 0;
|
||||
|
||||
// Calling slirp functions from multiple threads concurrently is unsafe; guard it
|
||||
static CRITICAL_SECTION slirp_single_call_csection;
|
||||
|
||||
|
||||
// Try to deal with echos. Protected by fetch_csection.
|
||||
@ -190,6 +201,8 @@ static int16 ether_do_add_multicast(uint8 *addr);
|
||||
static int16 ether_do_del_multicast(uint8 *addr);
|
||||
static int16 ether_do_write(uint32 arg);
|
||||
static void ether_do_interrupt(void);
|
||||
static void slirp_add_redirs();
|
||||
static int slirp_add_redir(const char *redir_str);
|
||||
|
||||
|
||||
/*
|
||||
@ -253,6 +266,7 @@ bool ether_init(void)
|
||||
WarningAlert(GetString(STR_SLIRP_NO_DNS_FOUND_WARN));
|
||||
return false;
|
||||
}
|
||||
slirp_add_redirs();
|
||||
}
|
||||
|
||||
// Open ethernet device
|
||||
@ -408,6 +422,8 @@ bool ether_init(void)
|
||||
InitializeCriticalSectionAndSpinCount( &send_csection, 5000 );
|
||||
InitializeCriticalSectionAndSpinCount( &wpool_csection, 5000 );
|
||||
|
||||
InitializeCriticalSection( &slirp_single_call_csection );
|
||||
|
||||
ether_th = (HANDLE)_beginthreadex( 0, 0, ether_thread_feed_int, 0, 0, ðer_tid );
|
||||
if (!ether_th) {
|
||||
D(bug("Failed to create ethernet thread\n"));
|
||||
@ -557,6 +573,7 @@ void ether_exit(void)
|
||||
DeleteCriticalSection( &queue_csection );
|
||||
DeleteCriticalSection( &send_csection );
|
||||
DeleteCriticalSection( &wpool_csection );
|
||||
DeleteCriticalSection( &slirp_single_call_csection );
|
||||
|
||||
D(bug("Freeing read packets\n"));
|
||||
free_read_packets();
|
||||
@ -1010,7 +1027,9 @@ unsigned int WINAPI ether_thread_write_packets(void *arg)
|
||||
}
|
||||
break;
|
||||
case NET_IF_SLIRP:
|
||||
EnterCriticalSection( &slirp_single_call_csection );
|
||||
slirp_input((uint8 *)Packet->Buffer, Packet->Length);
|
||||
LeaveCriticalSection( &slirp_single_call_csection );
|
||||
Packet->bIoComplete = TRUE;
|
||||
recycle_write_packet(Packet);
|
||||
break;
|
||||
@ -1364,7 +1383,9 @@ unsigned int WINAPI slirp_receive_func(void *arg)
|
||||
FD_ZERO(&rfds);
|
||||
FD_ZERO(&wfds);
|
||||
FD_ZERO(&xfds);
|
||||
EnterCriticalSection( &slirp_single_call_csection );
|
||||
timeout = slirp_select_fill(&nfds, &rfds, &wfds, &xfds);
|
||||
LeaveCriticalSection( &slirp_single_call_csection );
|
||||
#if ! USE_SLIRP_TIMEOUT
|
||||
timeout = 10000;
|
||||
#endif
|
||||
@ -1380,8 +1401,11 @@ unsigned int WINAPI slirp_receive_func(void *arg)
|
||||
tv.tv_usec = timeout;
|
||||
ret = select(0, &rfds, &wfds, &xfds, &tv);
|
||||
}
|
||||
if (ret >= 0)
|
||||
if (ret >= 0) {
|
||||
EnterCriticalSection( &slirp_single_call_csection );
|
||||
slirp_select_poll(&rfds, &wfds, &xfds);
|
||||
LeaveCriticalSection( &slirp_single_call_csection );
|
||||
}
|
||||
}
|
||||
|
||||
D(bug("slirp_receive_func exit\n"));
|
||||
@ -1571,10 +1595,16 @@ unsigned int WINAPI ether_thread_feed_int(void *arg)
|
||||
D(bug("Triggering\n"));
|
||||
looping = true;
|
||||
while(thread_active && looping) {
|
||||
trigger_queue();
|
||||
// Wait for interrupt acknowledge by EtherInterrupt()
|
||||
WaitForSingleObject(int_ack,INFINITE);
|
||||
if(thread_active) looping = set_wait_request();
|
||||
if (ether_driver_opened) {
|
||||
trigger_queue();
|
||||
// Wait for interrupt acknowledge by EtherInterrupt()
|
||||
WaitForSingleObject(int_ack,INFINITE);
|
||||
if(thread_active) looping = set_wait_request();
|
||||
} else {
|
||||
// Ether driver is closed on the MacOS side
|
||||
// ether.h calls in this case are undefined
|
||||
Delay_usec(20000);
|
||||
}
|
||||
}
|
||||
D(bug("Queue empty.\n"));
|
||||
}
|
||||
@ -1614,6 +1644,97 @@ static void ether_do_interrupt(void)
|
||||
}
|
||||
}
|
||||
|
||||
// Helper function for port forwarding
|
||||
static int get_str_sep(char *buf, int buf_size, const char **pp, int sep)
|
||||
{
|
||||
const char *p, *p1;
|
||||
int len;
|
||||
p = *pp;
|
||||
p1 = strchr(p, sep);
|
||||
if (!p1)
|
||||
return -1;
|
||||
len = p1 - p;
|
||||
p1++;
|
||||
if (buf_size > 0) {
|
||||
if (len > buf_size - 1)
|
||||
len = buf_size - 1;
|
||||
memcpy(buf, p, len);
|
||||
buf[len] = '\0';
|
||||
}
|
||||
*pp = p1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
// Set up port forwarding for slirp
|
||||
static void slirp_add_redirs()
|
||||
{
|
||||
int index = 0;
|
||||
const char *str;
|
||||
while ((str = PrefsFindString("redir", index++)) != NULL) {
|
||||
slirp_add_redir(str);
|
||||
}
|
||||
}
|
||||
|
||||
// Add a port forward/redirection for slirp
|
||||
static int slirp_add_redir(const char *redir_str)
|
||||
{
|
||||
// code adapted from qemu source
|
||||
struct in_addr guest_addr = {0};
|
||||
int host_port, guest_port;
|
||||
const char *p;
|
||||
char buf[256];
|
||||
int is_udp;
|
||||
char *end;
|
||||
char str[256];
|
||||
|
||||
p = redir_str;
|
||||
if (!p || get_str_sep(buf, sizeof(buf), &p, ':') < 0) {
|
||||
goto fail_syntax;
|
||||
}
|
||||
if (!strcmp(buf, "tcp") || buf[0] == '\0') {
|
||||
is_udp = 0;
|
||||
} else if (!strcmp(buf, "udp")) {
|
||||
is_udp = 1;
|
||||
} else {
|
||||
goto fail_syntax;
|
||||
}
|
||||
|
||||
if (get_str_sep(buf, sizeof(buf), &p, ':') < 0) {
|
||||
goto fail_syntax;
|
||||
}
|
||||
host_port = strtol(buf, &end, 0);
|
||||
if (*end != '\0' || host_port < 1 || host_port > 65535) {
|
||||
goto fail_syntax;
|
||||
}
|
||||
|
||||
if (get_str_sep(buf, sizeof(buf), &p, ':') < 0) {
|
||||
goto fail_syntax;
|
||||
}
|
||||
// 0.0.0.0 doesn't seem to work, so default to a client address
|
||||
// if none is specified
|
||||
if (buf[0] == '\0' ?
|
||||
!inet_pton(AF_INET, CTL_LOCAL, &guest_addr) :
|
||||
!inet_pton(AF_INET, buf, &guest_addr)) {
|
||||
goto fail_syntax;
|
||||
}
|
||||
|
||||
guest_port = strtol(p, &end, 0);
|
||||
if (*end != '\0' || guest_port < 1 || guest_port > 65535) {
|
||||
goto fail_syntax;
|
||||
}
|
||||
|
||||
if (slirp_redir(is_udp, host_port, guest_addr, guest_port) < 0) {
|
||||
sprintf(str, "could not set up host forwarding rule '%s'", redir_str);
|
||||
WarningAlert(str);
|
||||
return -1;
|
||||
}
|
||||
return 0;
|
||||
|
||||
fail_syntax:
|
||||
sprintf(str, "invalid host forwarding rule '%s'", redir_str);
|
||||
WarningAlert(str);
|
||||
return -1;
|
||||
}
|
||||
#if DEBUG
|
||||
#pragma optimize("",on)
|
||||
#endif
|
||||
|
103
BasiliskII/src/Windows/main_windows.cpp
Executable file → Normal file
103
BasiliskII/src/Windows/main_windows.cpp
Executable file → Normal file
@ -61,6 +61,11 @@ extern void flush_icache_range(uint8 *start, uint32 size); // from compemu_suppo
|
||||
#define DEBUG 0
|
||||
#include "debug.h"
|
||||
|
||||
#if !SDL_VERSION_ATLEAST(3, 0, 0)
|
||||
#define SDL_Mutex SDL_mutex
|
||||
#define SDL_EVENT_KEY_UP SDL_KEYUP
|
||||
#define SDL_EVENT_KEY_DOWN SDL_KEYDOWN
|
||||
#endif
|
||||
|
||||
// Constants
|
||||
const TCHAR ROM_FILE_NAME[] = TEXT("ROM");
|
||||
@ -86,7 +91,7 @@ static bool tick_thread_active = false; // Flag: 60Hz thread installed
|
||||
static volatile bool tick_thread_cancel = false; // Flag: Cancel 60Hz thread
|
||||
static SDL_Thread *tick_thread; // 60Hz thread
|
||||
|
||||
static SDL_mutex *intflag_lock = NULL; // Mutex to protect InterruptFlags
|
||||
static SDL_Mutex *intflag_lock = NULL; // Mutex to protect InterruptFlags
|
||||
#define LOCK_INTFLAGS SDL_LockMutex(intflag_lock)
|
||||
#define UNLOCK_INTFLAGS SDL_UnlockMutex(intflag_lock)
|
||||
|
||||
@ -98,11 +103,14 @@ uint8 *ScratchMem = NULL; // Scratch memory for Mac ROM writes
|
||||
static bool lm_area_mapped = false; // Flag: Low Memory area mmap()ped
|
||||
#endif
|
||||
|
||||
static HHOOK keyboard_hook; // Hook for intercepting windows key events
|
||||
|
||||
|
||||
// Prototypes
|
||||
static int xpram_func(void *arg);
|
||||
static int tick_func(void *arg);
|
||||
static void one_tick(...);
|
||||
static LRESULT CALLBACK low_level_keyboard_hook(int nCode, WPARAM wParam, LPARAM lParam);
|
||||
|
||||
|
||||
/*
|
||||
@ -187,6 +195,16 @@ static void sigsegv_dump_state(sigsegv_info_t *sip)
|
||||
#endif
|
||||
}
|
||||
|
||||
uint16 emulated_ticks;
|
||||
void cpu_do_check_ticks(void)
|
||||
{
|
||||
static int delay = -1;
|
||||
if (delay < 0)
|
||||
delay = PrefsFindInt32("delay");
|
||||
if (delay)
|
||||
usleep(delay);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Main program
|
||||
@ -204,6 +222,7 @@ static void usage(const char *prg_name)
|
||||
);
|
||||
LoadPrefs(NULL); // read the prefs file so PrefsPrintUsage() will print the correct default values
|
||||
PrefsPrintUsage();
|
||||
printf("\nBuild Date: %s\n", __DATE__);
|
||||
exit(0);
|
||||
}
|
||||
|
||||
@ -283,6 +302,12 @@ int main(int argc, char **argv)
|
||||
QuitEmulator();
|
||||
#endif
|
||||
|
||||
// Install keyboard hook to block Windows key if enabled in prefs
|
||||
if (PrefsFindBool("reservewindowskey"))
|
||||
{
|
||||
keyboard_hook = SetWindowsHookEx(WH_KEYBOARD_LL, low_level_keyboard_hook, GetModuleHandle(NULL), 0);
|
||||
}
|
||||
|
||||
// Initialize SDL system
|
||||
int sdl_flags = 0;
|
||||
#ifdef USE_SDL_VIDEO
|
||||
@ -361,10 +386,10 @@ int main(int argc, char **argv)
|
||||
D(bug("Mac ROM starts at %p (%08x)\n", ROMBaseHost, ROMBaseMac));
|
||||
|
||||
// Get rom file path from preferences
|
||||
auto rom_path = tstr(PrefsFindString("rom"));
|
||||
const char* rom_path = PrefsFindString("rom");
|
||||
|
||||
// Load Mac ROM
|
||||
HANDLE rom_fh = CreateFile(rom_path ? rom_path.get() : ROM_FILE_NAME,
|
||||
HANDLE rom_fh = CreateFile((rom_path != NULL) ? rom_path : ROM_FILE_NAME,
|
||||
GENERIC_READ,
|
||||
FILE_SHARE_READ, NULL,
|
||||
OPEN_EXISTING,
|
||||
@ -500,7 +525,7 @@ void FlushCodeCache(void *start, uint32 size)
|
||||
struct B2_mutex {
|
||||
B2_mutex() { m = SDL_CreateMutex(); }
|
||||
~B2_mutex() { if (m) SDL_DestroyMutex(m); }
|
||||
SDL_mutex *m;
|
||||
SDL_Mutex *m;
|
||||
};
|
||||
|
||||
B2_mutex *B2_create_mutex(void)
|
||||
@ -598,13 +623,15 @@ static void one_tick(...)
|
||||
}
|
||||
}
|
||||
|
||||
bool tick_inhibit;
|
||||
static int tick_func(void *arg)
|
||||
{
|
||||
uint64 start = GetTicks_usec();
|
||||
int64 ticks = 0;
|
||||
uint64 next = GetTicks_usec();
|
||||
while (!tick_thread_cancel) {
|
||||
one_tick();
|
||||
if (!tick_inhibit)
|
||||
one_tick();
|
||||
next += 16625;
|
||||
int64 delay = next - GetTicks_usec();
|
||||
if (delay > 0)
|
||||
@ -624,22 +651,25 @@ static int tick_func(void *arg)
|
||||
*/
|
||||
|
||||
#ifdef USE_SDL_VIDEO
|
||||
#if SDL_VERSION_ATLEAST(3, 0, 0)
|
||||
#include <SDL_video.h>
|
||||
#else
|
||||
#include <SDL_syswm.h>
|
||||
#endif
|
||||
extern SDL_Window *sdl_window;
|
||||
HWND GetMainWindowHandle(void)
|
||||
{
|
||||
SDL_SysWMinfo wmInfo;
|
||||
SDL_VERSION(&wmInfo.version);
|
||||
if (!sdl_window) {
|
||||
return NULL;
|
||||
}
|
||||
if (!SDL_GetWindowWMInfo(sdl_window, &wmInfo)) {
|
||||
return NULL;
|
||||
}
|
||||
if (wmInfo.subsystem != SDL_SYSWM_WINDOWS) {
|
||||
return NULL;
|
||||
}
|
||||
return wmInfo.info.win.window;
|
||||
#if SDL_VERSION_ATLEAST(3, 0, 0)
|
||||
SDL_PropertiesID props = SDL_GetWindowProperties(sdl_window);
|
||||
return (HWND)SDL_GetPointerProperty(props, "SDL.window.cocoa.window", NULL);
|
||||
#else
|
||||
SDL_SysWMinfo wmInfo;
|
||||
SDL_VERSION(&wmInfo.version);
|
||||
return SDL_GetWindowWMInfo(sdl_window, &wmInfo) ? wmInfo.info.win.window : NULL;
|
||||
#endif
|
||||
}
|
||||
#endif
|
||||
|
||||
@ -711,3 +741,48 @@ bool ChoiceAlert(const char *text, const char *pos, const char *neg)
|
||||
printf(GetString(STR_SHELL_WARNING_PREFIX), text);
|
||||
return false; //!!
|
||||
}
|
||||
|
||||
/*
|
||||
* Low level keyboard hook allowing us to intercept events involving the Windows key
|
||||
*/
|
||||
static LRESULT CALLBACK low_level_keyboard_hook(int nCode, WPARAM wParam, LPARAM lParam)
|
||||
{
|
||||
// Not a relevant event, immediately pass it on
|
||||
if (nCode != HC_ACTION)
|
||||
return CallNextHookEx(keyboard_hook, nCode, wParam, lParam);
|
||||
|
||||
KBDLLHOOKSTRUCT *p = (KBDLLHOOKSTRUCT *)lParam;
|
||||
switch (wParam) {
|
||||
case WM_KEYDOWN:
|
||||
case WM_KEYUP:
|
||||
// Intercept left/right windows keys when we have keyboard focus so Windows doesn't handle them
|
||||
if (p->vkCode == VK_LWIN || p->vkCode == VK_RWIN) {
|
||||
bool intercept_event = false;
|
||||
#ifdef USE_SDL_VIDEO
|
||||
if (sdl_window && (SDL_GetWindowFlags(sdl_window) & SDL_WINDOW_INPUT_FOCUS)) {
|
||||
intercept_event = true;
|
||||
}
|
||||
#endif
|
||||
|
||||
// If we've determined we should intercept the event, intercept it. But pass the event onto SDL so Basilisk handles it.
|
||||
if (intercept_event) {
|
||||
SDL_Event e;
|
||||
memset(&e, 0, sizeof(e));
|
||||
e.type = (wParam == WM_KEYDOWN) ? SDL_EVENT_KEY_DOWN : SDL_EVENT_KEY_UP;
|
||||
#if SDL_VERSION_ATLEAST(3, 0, 0)
|
||||
e.key.key = (p->vkCode == VK_LWIN) ? SDLK_LGUI : SDLK_RGUI;
|
||||
e.key.scancode = (p->vkCode == VK_LWIN) ? SDL_SCANCODE_LGUI : SDL_SCANCODE_RGUI;
|
||||
#else
|
||||
e.key.keysym.sym = (p->vkCode == VK_LWIN) ? SDLK_LGUI : SDLK_RGUI;
|
||||
e.key.keysym.scancode = (p->vkCode == VK_LWIN) ? SDL_SCANCODE_LGUI : SDL_SCANCODE_RGUI;
|
||||
#endif
|
||||
SDL_PushEvent(&e);
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
// If we fall here, we weren't supposed to intercept it.
|
||||
return CallNextHookEx(keyboard_hook, nCode, wParam, lParam);
|
||||
}
|
||||
|
@ -392,14 +392,23 @@ void init_posix_emu(void)
|
||||
int fd = my_creat( custom_icon_name, 0 );
|
||||
if(fd >= 0) {
|
||||
my_close(fd);
|
||||
struct my_stat custom_icon_stat;
|
||||
int stat_result = my_stat( custom_icon_name, &custom_icon_stat );
|
||||
fd = open_rfork( custom_icon_name, O_RDWR|O_CREAT );
|
||||
if(fd >= 0) {
|
||||
my_write( fd, my_comp_icon, sizeof(my_comp_icon) );
|
||||
my_close(fd);
|
||||
static uint8 host_finfo[SIZEOF_FInfo];
|
||||
// need room for the things from around the finfo that set_finfo reads
|
||||
static uint8 custom_icon_hfile[ioFlXFndrInfo + SIZEOF_FXInfo];
|
||||
memset(custom_icon_hfile, 0, ioFlXFndrInfo + SIZEOF_FXInfo);
|
||||
static uint8 * host_finfo = custom_icon_hfile + ioFlFndrInfo;
|
||||
uint32 finfo = Host2MacAddr(host_finfo);
|
||||
get_finfo(custom_icon_name, finfo, 0, false);
|
||||
WriteMacInt16(finfo + fdFlags, kIsInvisible);
|
||||
if (stat_result == 0) {
|
||||
WriteMacInt32(finfo - ioFlFndrInfo + ioFlCrDat, TimeToMacTime(custom_icon_stat.st_ctime));
|
||||
WriteMacInt32(finfo - ioFlFndrInfo + ioFlMdDat, TimeToMacTime(custom_icon_stat.st_mtime));
|
||||
}
|
||||
set_finfo(custom_icon_name, finfo, 0, false);
|
||||
get_finfo(my_computer, finfo, 0, true);
|
||||
WriteMacInt16(finfo + fdFlags, ReadMacInt16(finfo + fdFlags) | kHasCustomIcon);
|
||||
@ -1126,6 +1135,11 @@ int my_write( int fd, const void *buffer, unsigned int count )
|
||||
|
||||
static FILETIME get_file_time(time_t time) {
|
||||
FILETIME ft;
|
||||
if (time == -1) {
|
||||
ft.dwHighDateTime = 0;
|
||||
ft.dwLowDateTime = 0;
|
||||
return ft;
|
||||
}
|
||||
unsigned long long result = 11644473600LL;
|
||||
result += time;
|
||||
result *= 10000000LL;
|
||||
@ -1140,9 +1154,9 @@ int my_utime( const char *path, struct my_utimbuf * my_times )
|
||||
LPCTSTR p = MRP(tpath.get());
|
||||
HANDLE f = CreateFile(p, FILE_WRITE_ATTRIBUTES, FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
|
||||
if (f != INVALID_HANDLE_VALUE) {
|
||||
FILETIME crTime = get_file_time(my_times->actime);
|
||||
FILETIME acTime = get_file_time(my_times->actime);
|
||||
FILETIME modTime = get_file_time(my_times->modtime);
|
||||
SetFileTime(f, &crTime, NULL, &modTime);
|
||||
SetFileTime(f, NULL, &acTime, &modTime);
|
||||
CloseHandle(f);
|
||||
return 0;
|
||||
}
|
||||
|
@ -79,24 +79,33 @@ extern int my_errno;
|
||||
|
||||
// must hook all other functions that manipulate file names
|
||||
#ifndef NO_POSIX_API_HOOK
|
||||
#define stat my_stat
|
||||
#define fstat my_fstat
|
||||
#define open my_open
|
||||
#define rename my_rename
|
||||
#define access my_access
|
||||
#define mkdir my_mkdir
|
||||
#define remove my_remove
|
||||
#define creat my_creat
|
||||
#define close my_close
|
||||
#define lseek my_lseek
|
||||
#define read my_read
|
||||
#define write my_write
|
||||
#define ftruncate my_chsize
|
||||
#define locking my_locking
|
||||
#define utime my_utime
|
||||
# ifdef stat
|
||||
# undef stat
|
||||
# endif
|
||||
# define stat my_stat
|
||||
# ifdef fstat
|
||||
# undef fstat
|
||||
# endif
|
||||
# define fstat my_fstat
|
||||
# define open my_open
|
||||
# define rename my_rename
|
||||
# define access my_access
|
||||
# define mkdir my_mkdir
|
||||
# define remove my_remove
|
||||
# define creat my_creat
|
||||
# define close my_close
|
||||
# ifdef lseek
|
||||
# undef lseek
|
||||
# endif
|
||||
# define lseek my_lseek
|
||||
# define read my_read
|
||||
# define write my_write
|
||||
# define ftruncate my_chsize
|
||||
# define locking my_locking
|
||||
# define utime my_utime
|
||||
|
||||
#undef errno
|
||||
#define errno my_errno
|
||||
# undef errno
|
||||
# define errno my_errno
|
||||
#endif //!NO_POSIX_API_HOOK
|
||||
|
||||
#ifndef S_ISDIR
|
||||
@ -125,6 +134,6 @@ struct my_utimbuf
|
||||
};
|
||||
|
||||
// Your compiler may have different "struct stat" -> edit "struct my_stat"
|
||||
#define validate_stat_struct ( sizeof(struct my_stat) == sizeof(struct stat) )
|
||||
#define validate_stat_struct ( sizeof(struct my_stat) == sizeof(struct _stat) )
|
||||
|
||||
#define st_crtime st_ctime
|
||||
|
@ -26,6 +26,10 @@
|
||||
#include <sys/stat.h>
|
||||
#include <gtk/gtk.h>
|
||||
|
||||
#include <shellapi.h>
|
||||
|
||||
#include <fstream>
|
||||
|
||||
#include "user_strings.h"
|
||||
#include "version.h"
|
||||
#include "cdrom.h"
|
||||
@ -51,6 +55,9 @@ static void create_ethernet_pane(GtkWidget *top);
|
||||
static void create_memory_pane(GtkWidget *top);
|
||||
static void create_jit_pane(GtkWidget *top);
|
||||
static void read_settings(void);
|
||||
static void add_volume_entry_with_type(const char * filename, bool cdrom);
|
||||
static void add_volume_entry_guessed(const char * filename);
|
||||
static bool volume_in_list(const char * filename);
|
||||
|
||||
|
||||
/*
|
||||
@ -76,9 +83,33 @@ enum {
|
||||
* Utility functions
|
||||
*/
|
||||
|
||||
gchar * tchar_to_g_utf8(const TCHAR * str) {
|
||||
gchar * out;
|
||||
if (str == NULL)
|
||||
return NULL;
|
||||
int len = _tcslen(str) + 1;
|
||||
#ifdef _UNICODE
|
||||
/* First call just to find what the output size will be */
|
||||
int size = WideCharToMultiByte(CP_UTF8, 0, str, len, NULL, 0, NULL, NULL);
|
||||
if (size == 0)
|
||||
return NULL;
|
||||
out = (gchar *) g_malloc(size);
|
||||
if (out == NULL)
|
||||
return NULL;
|
||||
WideCharToMultiByte(CP_UTF8, 0, str, len, out, size, NULL, NULL);
|
||||
#else /* _UNICODE */
|
||||
out = g_locale_to_utf8(str, -1, NULL, NULL, NULL);
|
||||
#endif /* _UNICODE */
|
||||
return out;
|
||||
}
|
||||
|
||||
|
||||
struct opt_desc {
|
||||
opt_desc(int l, GCallback f, GtkWidget **s=NULL) : label_id(l), func(f), save_ref(s) {}
|
||||
|
||||
int label_id;
|
||||
GtkSignalFunc func;
|
||||
GtkWidget ** save_ref;
|
||||
};
|
||||
|
||||
struct combo_desc {
|
||||
@ -165,6 +196,9 @@ static GtkWidget *make_button_box(GtkWidget *top, int border, const opt_desc *bu
|
||||
gtk_widget_show(button);
|
||||
gtk_signal_connect_object(GTK_OBJECT(button), "clicked", buttons->func, NULL);
|
||||
gtk_box_pack_start(GTK_BOX(bb), button, TRUE, TRUE, 0);
|
||||
if (buttons->save_ref) {
|
||||
*(buttons->save_ref) = button;
|
||||
}
|
||||
buttons++;
|
||||
}
|
||||
return bb;
|
||||
@ -373,6 +407,7 @@ static GtkWidget *make_combobox(GtkWidget *top, int label_id, const char *defaul
|
||||
// Window closed
|
||||
static gint window_closed(void)
|
||||
{
|
||||
start_clicked = false;
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
@ -483,6 +518,7 @@ bool PrefsEditor(void)
|
||||
{
|
||||
// Create window
|
||||
win = gtk_window_new(GTK_WINDOW_TOPLEVEL);
|
||||
gtk_window_set_default_size(GTK_WINDOW(win), 640, 480); // a little bigger than the default
|
||||
gtk_window_set_title(GTK_WINDOW(win), GetString(STR_PREFS_TITLE));
|
||||
gtk_signal_connect(GTK_OBJECT(win), "delete_event", GTK_SIGNAL_FUNC(window_closed), NULL);
|
||||
gtk_signal_connect(GTK_OBJECT(win), "destroy", GTK_SIGNAL_FUNC(window_destroyed), NULL);
|
||||
@ -541,7 +577,8 @@ bool PrefsEditor(void)
|
||||
|
||||
static GtkWidget *w_enableextfs, *w_extdrives, *w_cdrom_drive;
|
||||
static GtkWidget *volume_list;
|
||||
static int selected_volume;
|
||||
static GtkListStore *volume_list_model;
|
||||
static GtkWidget *volume_remove_button;
|
||||
|
||||
// Set sensitivity of widgets
|
||||
static void set_volumes_sensitive(void)
|
||||
@ -552,10 +589,39 @@ static void set_volumes_sensitive(void)
|
||||
gtk_widget_set_sensitive(w_cdrom_drive, !no_cdrom);
|
||||
}
|
||||
|
||||
// Volume in list selected
|
||||
static void cl_selected(GtkWidget *list, int row, int column)
|
||||
// Volume list selection changed
|
||||
static void cl_selected(GtkTreeSelection * selection, gpointer user_data) {
|
||||
if (selection) {
|
||||
bool have_selection = gtk_tree_selection_get_selected(selection, NULL, NULL);
|
||||
|
||||
gtk_widget_set_sensitive(GTK_WIDGET(volume_remove_button), have_selection);
|
||||
}
|
||||
}
|
||||
|
||||
// Process proposed drop
|
||||
gboolean volume_list_drag_motion (GtkWidget *widget, GdkDragContext *drag_context, gint x, gint y, guint time,
|
||||
gpointer user_data)
|
||||
{
|
||||
selected_volume = row;
|
||||
GtkTreePath *path;
|
||||
GtkTreeViewDropPosition pos;
|
||||
// Don't allow tree-style drops onto, only list-style drops between
|
||||
if (gtk_tree_view_get_dest_row_at_pos(GTK_TREE_VIEW(volume_list), x,y, &path, &pos)) {
|
||||
switch (pos) {
|
||||
case GTK_TREE_VIEW_DROP_INTO_OR_AFTER:
|
||||
gtk_tree_view_set_drag_dest_row(GTK_TREE_VIEW(volume_list), path, GTK_TREE_VIEW_DROP_AFTER);
|
||||
break;
|
||||
case GTK_TREE_VIEW_DROP_INTO_OR_BEFORE:
|
||||
gtk_tree_view_set_drag_dest_row(GTK_TREE_VIEW(volume_list), path, GTK_TREE_VIEW_DROP_BEFORE);
|
||||
break;
|
||||
case GTK_TREE_VIEW_DROP_BEFORE:
|
||||
case GTK_TREE_VIEW_DROP_AFTER:
|
||||
// these are ok, no change
|
||||
break;
|
||||
}
|
||||
gdk_drag_status(drag_context, drag_context->suggested_action, time);
|
||||
return TRUE;
|
||||
}
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
// Something dropped on volume list
|
||||
@ -575,7 +641,36 @@ static void drag_data_received(GtkWidget *list, GdkDragContext *drag_context, gi
|
||||
|
||||
gchar * filename = g_filename_from_uri(*uri, NULL, NULL);
|
||||
if (filename) {
|
||||
gtk_clist_append(GTK_CLIST(volume_list), &filename);
|
||||
add_volume_entry_guessed(filename);
|
||||
|
||||
// figure out where in the list they dropped
|
||||
GtkTreePath *path;
|
||||
GtkTreeViewDropPosition pos;
|
||||
if (gtk_tree_view_get_dest_row_at_pos(GTK_TREE_VIEW(volume_list), x,y, &path, &pos)) {
|
||||
GtkTreeIter dest_iter;
|
||||
if (gtk_tree_model_get_iter(GTK_TREE_MODEL(volume_list_model), &dest_iter, path)) {
|
||||
|
||||
// Find the item we just added and put it in place
|
||||
GtkTreeIter last;
|
||||
GtkTreeIter cur;
|
||||
if (gtk_tree_model_get_iter_first(GTK_TREE_MODEL(volume_list_model), &cur)) {
|
||||
do {
|
||||
last = cur;
|
||||
} while (gtk_tree_model_iter_next(GTK_TREE_MODEL(volume_list_model), &cur));
|
||||
}
|
||||
switch (pos) {
|
||||
case GTK_TREE_VIEW_DROP_AFTER:
|
||||
case GTK_TREE_VIEW_DROP_INTO_OR_AFTER:
|
||||
gtk_list_store_move_after(volume_list_model, &last, &dest_iter);
|
||||
break;
|
||||
case GTK_TREE_VIEW_DROP_BEFORE:
|
||||
case GTK_TREE_VIEW_DROP_INTO_OR_BEFORE:
|
||||
gtk_list_store_move_before(volume_list_model, &last, &dest_iter);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
g_free(filename);
|
||||
}
|
||||
}
|
||||
@ -586,7 +681,7 @@ static void drag_data_received(GtkWidget *list, GdkDragContext *drag_context, gi
|
||||
static void add_volume_ok(GtkWidget *button, file_req_assoc *assoc)
|
||||
{
|
||||
gchar *file = (gchar *)gtk_file_selection_get_filename(GTK_FILE_SELECTION(assoc->req));
|
||||
gtk_clist_append(GTK_CLIST(volume_list), &file);
|
||||
add_volume_entry_guessed(file);
|
||||
gtk_widget_destroy(assoc->req);
|
||||
delete assoc;
|
||||
}
|
||||
@ -601,9 +696,14 @@ static void create_volume_ok(GtkWidget *button, file_req_assoc *assoc)
|
||||
|
||||
int fd = _open(file, _O_WRONLY | _O_CREAT | _O_BINARY | _O_TRUNC, _S_IREAD | _S_IWRITE);
|
||||
if (fd >= 0) {
|
||||
bool created_ok = false;
|
||||
if (_chsize(fd, size) == 0)
|
||||
gtk_clist_append(GTK_CLIST(volume_list), &file);
|
||||
created_ok = true;
|
||||
_close(fd);
|
||||
if (created_ok) {
|
||||
// A created empty volume is always a new disk
|
||||
add_volume_entry_with_type(file, false);
|
||||
}
|
||||
}
|
||||
gtk_widget_destroy(GTK_WIDGET(assoc->req));
|
||||
delete assoc;
|
||||
@ -646,7 +746,13 @@ static void cb_create_volume(...)
|
||||
// "Remove Volume" button clicked
|
||||
static void cb_remove_volume(...)
|
||||
{
|
||||
gtk_clist_remove(GTK_CLIST(volume_list), selected_volume);
|
||||
GtkTreeSelection *sel = gtk_tree_view_get_selection(GTK_TREE_VIEW(volume_list));
|
||||
if (sel) {
|
||||
GtkTreeIter row;
|
||||
if (gtk_tree_selection_get_selected(sel, NULL, &row)) {
|
||||
gtk_list_store_remove(volume_list_model, &row);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// "Boot From" selected
|
||||
@ -672,11 +778,11 @@ static GList *add_cdrom_names(void)
|
||||
{
|
||||
GList *glist = NULL;
|
||||
|
||||
char rootdir[4] = "X:\\";
|
||||
for (char letter = 'C'; letter <= 'Z'; letter++) {
|
||||
TCHAR rootdir[4] = TEXT("X:\\");
|
||||
for (TCHAR letter = TEXT('C'); letter <= TEXT('Z'); letter++) {
|
||||
rootdir[0] = letter;
|
||||
if (GetDriveType(rootdir) == DRIVE_CDROM)
|
||||
glist = g_list_append(glist, strdup(rootdir));
|
||||
glist = g_list_append(glist, _tcsdup(rootdir));
|
||||
}
|
||||
|
||||
return glist;
|
||||
@ -688,64 +794,261 @@ static void tb_pollmedia(GtkWidget *widget)
|
||||
PrefsReplaceBool("pollmedia", GTK_TOGGLE_BUTTON(widget)->active);
|
||||
}
|
||||
|
||||
// Data source for the volumes list
|
||||
enum {
|
||||
VOLUME_LIST_FILENAME = 0,
|
||||
VOLUME_LIST_CDROM,
|
||||
VOLUME_LIST_SIZE_DESC,
|
||||
NUM_VOLUME_LIST_FIELDS
|
||||
};
|
||||
|
||||
static void init_volume_model() {
|
||||
volume_list_model = gtk_list_store_new(NUM_VOLUME_LIST_FIELDS,
|
||||
G_TYPE_STRING, // filename
|
||||
G_TYPE_BOOLEAN, // is CD-ROM
|
||||
G_TYPE_STRING // size desc
|
||||
);
|
||||
}
|
||||
|
||||
static void toggle_cdrom_val(GtkTreeIter *row) {
|
||||
gboolean cdrom;
|
||||
gtk_tree_model_get(GTK_TREE_MODEL(volume_list_model), row,
|
||||
VOLUME_LIST_CDROM, &cdrom,
|
||||
-1);
|
||||
|
||||
cdrom = !cdrom;
|
||||
|
||||
gtk_list_store_set(volume_list_model, row,
|
||||
VOLUME_LIST_CDROM, cdrom,
|
||||
-1);
|
||||
}
|
||||
|
||||
// Read settings from widgets and set preferences
|
||||
static void read_volumes_settings(void)
|
||||
{
|
||||
while (PrefsFindString("disk"))
|
||||
PrefsRemoveItem("disk");
|
||||
while (PrefsFindString("cdrom"))
|
||||
PrefsRemoveItem("cdrom");
|
||||
|
||||
for (int i=0; i<GTK_CLIST(volume_list)->rows; i++) {
|
||||
char *str;
|
||||
gtk_clist_get_text(GTK_CLIST(volume_list), i, 0, &str);
|
||||
PrefsAddString("disk", str);
|
||||
GtkTreeModel * m = GTK_TREE_MODEL(volume_list_model);
|
||||
|
||||
GtkTreeIter row;
|
||||
if (gtk_tree_model_get_iter_first(m, &row)) {
|
||||
do {
|
||||
GValue filename = G_VALUE_INIT, is_cdrom = G_VALUE_INIT;
|
||||
|
||||
gtk_tree_model_get_value(m, &row, VOLUME_LIST_FILENAME, &filename);
|
||||
gtk_tree_model_get_value(m, &row, VOLUME_LIST_CDROM, &is_cdrom);
|
||||
|
||||
//D(bug("handling %d: %s\n", g_value_get_boolean(&is_cdrom), g_value_get_string(&filename)));
|
||||
|
||||
const char * pref_name = g_value_get_boolean(&is_cdrom) ? "cdrom": "disk";
|
||||
PrefsAddString(pref_name, g_value_get_string(&filename));
|
||||
|
||||
g_value_unset(&filename);
|
||||
g_value_unset(&is_cdrom);
|
||||
|
||||
} while (gtk_tree_model_iter_next(GTK_TREE_MODEL(volume_list_model), &row));
|
||||
}
|
||||
|
||||
const char *str = gtk_entry_get_text(GTK_ENTRY(GTK_COMBO(w_cdrom_drive)->entry));
|
||||
if (str && strlen(str))
|
||||
PrefsReplaceString("cdrom", str);
|
||||
else
|
||||
PrefsRemoveItem("cdrom");
|
||||
|
||||
PrefsReplaceString("extdrives", get_file_entry_path(w_extdrives));
|
||||
|
||||
// Add one more cdrom entry if present in the combo
|
||||
const char *str = gtk_entry_get_text(GTK_ENTRY(GTK_COMBO(w_cdrom_drive)->entry));
|
||||
if (str && strlen(str) && !volume_in_list(str))
|
||||
PrefsAddString("cdrom", str);
|
||||
}
|
||||
|
||||
|
||||
// Gets the size of the volume as a pretty string
|
||||
static const char* get_file_size_str (const char * filename)
|
||||
{
|
||||
if (strlen(filename) == 3 && filename[1] == ':' && filename[2] == '\\') {
|
||||
// e.g. real CD-ROM drive
|
||||
return "";
|
||||
}
|
||||
std::ifstream in(filename, std::ifstream::ate | std::ifstream::binary);
|
||||
if (in.is_open()) {
|
||||
uint64_t size = in.tellg();
|
||||
in.close();
|
||||
char *sizestr = g_format_size_full(size, G_FORMAT_SIZE_IEC_UNITS);
|
||||
return sizestr;
|
||||
}
|
||||
else
|
||||
{
|
||||
return "Not Found";
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static bool volume_in_list(const char * filename) {
|
||||
bool found = false;
|
||||
|
||||
GtkTreeModel * m = GTK_TREE_MODEL(volume_list_model);
|
||||
|
||||
GtkTreeIter row;
|
||||
if (gtk_tree_model_get_iter_first(m, &row)) {
|
||||
do {
|
||||
GValue cur_filename = G_VALUE_INIT;
|
||||
|
||||
gtk_tree_model_get_value(m, &row, VOLUME_LIST_FILENAME, &cur_filename);
|
||||
|
||||
if (strcmp(g_value_get_string(&cur_filename), filename) == 0) {
|
||||
found = true;
|
||||
}
|
||||
|
||||
g_value_unset(&cur_filename);
|
||||
|
||||
if (found) break;
|
||||
} while (gtk_tree_model_iter_next(GTK_TREE_MODEL(volume_list_model), &row));
|
||||
}
|
||||
|
||||
return found;
|
||||
}
|
||||
|
||||
|
||||
// Add a volume file as the given type
|
||||
static void add_volume_entry_with_type(const char * filename, bool cdrom) {
|
||||
if (volume_in_list(filename)) return;
|
||||
|
||||
GtkTreeIter row;
|
||||
gtk_list_store_append(GTK_LIST_STORE(volume_list_model), &row);
|
||||
// set the values for the new row
|
||||
gtk_list_store_set(GTK_LIST_STORE(volume_list_model), &row,
|
||||
VOLUME_LIST_FILENAME, filename,
|
||||
VOLUME_LIST_CDROM, cdrom,
|
||||
VOLUME_LIST_SIZE_DESC, get_file_size_str(filename),
|
||||
-1);
|
||||
}
|
||||
|
||||
static bool has_file_ext (const char * str, const char *ext)
|
||||
{
|
||||
char *file_ext = g_utf8_strrchr(str, 255, '.');
|
||||
if (!file_ext)
|
||||
return 0;
|
||||
return (g_strcmp0(file_ext, ext) == 0);
|
||||
}
|
||||
|
||||
static bool guess_if_file_is_cdrom(const char * volume) {
|
||||
return has_file_ext(volume, ".iso") ||
|
||||
#ifdef BINCUE
|
||||
has_file_ext(volume, ".cue") ||
|
||||
#endif
|
||||
has_file_ext(volume, ".toast");
|
||||
}
|
||||
|
||||
// Add a volume file and guess the type
|
||||
static void add_volume_entry_guessed(const char * filename) {
|
||||
add_volume_entry_with_type(filename, guess_if_file_is_cdrom(filename));
|
||||
}
|
||||
|
||||
// CD-ROM checkbox changed
|
||||
static void cb_cdrom (GtkCellRendererToggle *cell, char *path_str, gpointer data)
|
||||
{
|
||||
GtkTreeIter iter;
|
||||
GtkTreePath *path = gtk_tree_path_new_from_string (path_str);
|
||||
if (gtk_tree_model_get_iter (GTK_TREE_MODEL(volume_list_model), &iter, path)) {
|
||||
toggle_cdrom_val(&iter);
|
||||
}
|
||||
gtk_tree_path_free (path);
|
||||
}
|
||||
|
||||
static void cb_cdrom_add(...) {
|
||||
const char *str = gtk_entry_get_text(GTK_ENTRY(GTK_COMBO(w_cdrom_drive)->entry));
|
||||
if (str && strcmp(str, "") != 0) {
|
||||
if (volume_in_list(str)) return;
|
||||
add_volume_entry_with_type(str, true);
|
||||
|
||||
gtk_entry_set_text(GTK_ENTRY(GTK_COMBO(w_cdrom_drive)->entry), "");
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
// Create "Volumes" pane
|
||||
static void create_volumes_pane(GtkWidget *top)
|
||||
{
|
||||
GtkWidget *box, *scroll, *menu;
|
||||
GtkTreeViewColumn *column;
|
||||
GtkCellRenderer *renderer;
|
||||
|
||||
box = make_pane(top, STR_VOLUMES_PANE_TITLE);
|
||||
|
||||
scroll = gtk_scrolled_window_new(NULL, NULL);
|
||||
gtk_widget_show(scroll);
|
||||
gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(scroll), GTK_POLICY_AUTOMATIC, GTK_POLICY_AUTOMATIC);
|
||||
volume_list = gtk_clist_new(1);
|
||||
|
||||
init_volume_model();
|
||||
|
||||
volume_list = gtk_tree_view_new();
|
||||
gtk_tree_view_set_model(GTK_TREE_VIEW(volume_list), GTK_TREE_MODEL(volume_list_model));
|
||||
gtk_widget_show(volume_list);
|
||||
gtk_clist_set_selection_mode(GTK_CLIST(volume_list), GTK_SELECTION_SINGLE);
|
||||
gtk_clist_set_shadow_type(GTK_CLIST(volume_list), GTK_SHADOW_NONE);
|
||||
gtk_clist_set_reorderable(GTK_CLIST(volume_list), true);
|
||||
gtk_signal_connect(GTK_OBJECT(volume_list), "select_row", GTK_SIGNAL_FUNC(cl_selected), NULL);
|
||||
|
||||
gtk_tree_view_set_reorderable(GTK_TREE_VIEW(volume_list), true);
|
||||
|
||||
column = gtk_tree_view_column_new();
|
||||
gtk_tree_view_column_set_title(column, GetString(STR_VOL_HEADING_LOCATION));
|
||||
gtk_tree_view_column_set_expand(column, true);
|
||||
gtk_tree_view_append_column(GTK_TREE_VIEW(volume_list), column);
|
||||
renderer = gtk_cell_renderer_text_new();
|
||||
gtk_tree_view_column_pack_start(column, renderer, TRUE);
|
||||
// connect tree column to model field
|
||||
gtk_tree_view_column_add_attribute(column, renderer, "text", VOLUME_LIST_FILENAME);
|
||||
|
||||
column = gtk_tree_view_column_new();
|
||||
gtk_tree_view_column_set_title(column, GetString(STR_VOL_HEADING_CDROM));
|
||||
gtk_tree_view_append_column(GTK_TREE_VIEW(volume_list), column);
|
||||
renderer = gtk_cell_renderer_toggle_new();
|
||||
g_signal_connect (renderer, "toggled",
|
||||
G_CALLBACK (cb_cdrom), NULL);
|
||||
gtk_tree_view_column_set_alignment(column, 0.5);
|
||||
|
||||
gtk_tree_view_column_pack_start(column, renderer, TRUE);
|
||||
// connect tree column to model field
|
||||
gtk_tree_view_column_add_attribute(column, renderer, "active", VOLUME_LIST_CDROM);
|
||||
|
||||
column = gtk_tree_view_column_new();
|
||||
gtk_tree_view_column_set_title(column, GetString(STR_VOL_HEADING_SIZE));
|
||||
gtk_tree_view_append_column(GTK_TREE_VIEW(volume_list), column);
|
||||
renderer = gtk_cell_renderer_text_new();
|
||||
gtk_tree_view_column_pack_start(column, renderer, FALSE);
|
||||
// connect tree column to model field
|
||||
gtk_tree_view_column_add_attribute(column, renderer, "text", VOLUME_LIST_SIZE_DESC);
|
||||
|
||||
GtkTreeSelection *sel = gtk_tree_view_get_selection(GTK_TREE_VIEW(volume_list));
|
||||
g_signal_connect(sel, "changed", G_CALLBACK(cl_selected), NULL);
|
||||
gtk_tree_selection_set_mode(sel, GTK_SELECTION_SINGLE);
|
||||
|
||||
// also support volume files dragged onto the list from outside
|
||||
gtk_drag_dest_add_uri_targets(volume_list);
|
||||
// add a drop handler to get dropped files; don't supersede the drop handler for reordering
|
||||
gtk_signal_connect_after(GTK_OBJECT(volume_list), "drag_data_received", GTK_SIGNAL_FUNC(drag_data_received), NULL);
|
||||
// process proposed drops to limit drop locations
|
||||
gtk_signal_connect(GTK_OBJECT(volume_list), "drag-motion", GTK_SIGNAL_FUNC(volume_list_drag_motion), NULL);
|
||||
|
||||
char *str;
|
||||
int32 index = 0;
|
||||
while ((str = const_cast<char *>(PrefsFindString("disk", index++))) != NULL)
|
||||
gtk_clist_append(GTK_CLIST(volume_list), &str);
|
||||
gtk_scrolled_window_add_with_viewport(GTK_SCROLLED_WINDOW(scroll), volume_list);
|
||||
int32 index;
|
||||
const char * types[] = {"disk", "cdrom", NULL};
|
||||
for (const char ** type = types; *type != NULL; type++) {
|
||||
index = 0;
|
||||
while ((str = const_cast<char *>(PrefsFindString(*type, index))) != NULL) {
|
||||
bool is_cdrom = strcmp(*type, "cdrom") == 0;
|
||||
add_volume_entry_with_type(str, is_cdrom);
|
||||
index++;
|
||||
}
|
||||
}
|
||||
gtk_container_add(GTK_CONTAINER(scroll), volume_list);
|
||||
gtk_box_pack_start(GTK_BOX(box), scroll, TRUE, TRUE, 0);
|
||||
selected_volume = 0;
|
||||
|
||||
static const opt_desc buttons[] = {
|
||||
{STR_ADD_VOLUME_BUTTON, GTK_SIGNAL_FUNC(cb_add_volume)},
|
||||
{STR_CREATE_VOLUME_BUTTON, GTK_SIGNAL_FUNC(cb_create_volume)},
|
||||
{STR_REMOVE_VOLUME_BUTTON, GTK_SIGNAL_FUNC(cb_remove_volume)},
|
||||
{STR_REMOVE_VOLUME_BUTTON, G_CALLBACK(cb_remove_volume), &volume_remove_button},
|
||||
{0, NULL},
|
||||
};
|
||||
make_button_box(box, 0, buttons);
|
||||
gtk_widget_set_sensitive(volume_remove_button, FALSE);
|
||||
make_separator(box);
|
||||
|
||||
static const opt_desc options[] = {
|
||||
@ -763,11 +1066,17 @@ static void create_volumes_pane(GtkWidget *top)
|
||||
make_checkbox(box, STR_NOCDROM_CTRL, "nocdrom", GTK_SIGNAL_FUNC(tb_nocdrom));
|
||||
|
||||
GList *glist = add_cdrom_names();
|
||||
str = const_cast<char *>(PrefsFindString("cdrom"));
|
||||
if (str == NULL)
|
||||
//str = const_cast<char *>(PrefsFindString("cdrom"));
|
||||
//if (str == NULL)
|
||||
str = "";
|
||||
w_cdrom_drive = make_combobox(box, STR_CDROM_DRIVE_CTRL, str, glist);
|
||||
|
||||
GtkWidget * cdrom_hbox = gtk_widget_get_parent(w_cdrom_drive);
|
||||
GtkWidget * cdrom_add_button = gtk_button_new_with_label("Add");
|
||||
gtk_widget_show(cdrom_add_button);
|
||||
gtk_signal_connect_object(GTK_OBJECT(cdrom_add_button), "clicked", GTK_SIGNAL_FUNC(cb_cdrom_add), NULL);
|
||||
gtk_box_pack_start(GTK_BOX(cdrom_hbox), cdrom_add_button, FALSE, TRUE, 0);
|
||||
|
||||
make_checkbox(box, STR_POLLMEDIA_CTRL, "pollmedia", GTK_SIGNAL_FUNC(tb_pollmedia));
|
||||
|
||||
make_separator(box);
|
||||
@ -887,11 +1196,12 @@ static void create_jit_pane(GtkWidget *top)
|
||||
#endif
|
||||
|
||||
set_jit_sensitive();
|
||||
#endif
|
||||
|
||||
#ifdef SHEEPSHAVER
|
||||
make_checkbox(box, STR_JIT_68K_CTRL, "jit68k", GTK_SIGNAL_FUNC(tb_jit_68k));
|
||||
#endif
|
||||
|
||||
#endif
|
||||
}
|
||||
|
||||
/*
|
||||
@ -951,30 +1261,14 @@ static int dis_width, dis_height;
|
||||
// Hide/show graphics widgets
|
||||
static void hide_show_graphics_widgets(void)
|
||||
{
|
||||
switch (display_type) {
|
||||
case DISPLAY_WINDOW:
|
||||
gtk_widget_show(w_frameskip); gtk_widget_show(l_frameskip);
|
||||
break;
|
||||
case DISPLAY_SCREEN:
|
||||
gtk_widget_hide(w_frameskip); gtk_widget_hide(l_frameskip);
|
||||
break;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
// "Window" video type selected
|
||||
static void mn_window(...)
|
||||
{
|
||||
display_type = DISPLAY_WINDOW;
|
||||
hide_show_graphics_widgets();
|
||||
}
|
||||
static void mn_window(...) {display_type = DISPLAY_WINDOW;}
|
||||
|
||||
// "Fullscreen" video type selected
|
||||
static void mn_fullscreen(...)
|
||||
{
|
||||
display_type = DISPLAY_SCREEN;
|
||||
hide_show_graphics_widgets();
|
||||
PrefsReplaceInt32("frameskip", 1);
|
||||
}
|
||||
static void mn_fullscreen(...) {display_type = DISPLAY_SCREEN;}
|
||||
|
||||
// "5 Hz".."60Hz" selected
|
||||
static void mn_5hz(...) {PrefsReplaceInt32("frameskip", 12);}
|
||||
@ -1006,6 +1300,33 @@ static void tb_nosound(GtkWidget *widget)
|
||||
set_graphics_sensitive();
|
||||
}
|
||||
|
||||
// SDL Graphics
|
||||
#ifdef USE_SDL_VIDEO
|
||||
// SDL Renderer Render Driver
|
||||
enum {
|
||||
RENDER_SOFTWARE = 0,
|
||||
RENDER_OPENGL = 1,
|
||||
RENDER_DIRECT3D = 2
|
||||
};
|
||||
|
||||
GtkWidget *w_render_driver;
|
||||
GtkWidget *l_render_driver;
|
||||
static int render_driver;
|
||||
static int sdl_vsync;
|
||||
|
||||
// Render Driver selected
|
||||
static void mn_sdl_software(...) {render_driver = RENDER_SOFTWARE;}
|
||||
static void mn_sdl_opengl(...) {render_driver = RENDER_OPENGL;}
|
||||
static void mn_sdl_direct3d(...) {render_driver = RENDER_DIRECT3D;}
|
||||
|
||||
// SDL Renderer Vertical Sync
|
||||
static void tb_sdl_vsync(GtkWidget *widget)
|
||||
{
|
||||
PrefsReplaceBool("sdl_vsync", GTK_TOGGLE_BUTTON(widget)->active);
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
// Read graphics preferences
|
||||
static void parse_graphics_prefs(void)
|
||||
{
|
||||
@ -1025,6 +1346,40 @@ static void parse_graphics_prefs(void)
|
||||
else if (sscanf(str, "dga/%d/%d", &dis_width, &dis_height) == 2)
|
||||
display_type = DISPLAY_SCREEN;
|
||||
}
|
||||
|
||||
#ifdef USE_SDL_VIDEO
|
||||
render_driver = RENDER_SOFTWARE;
|
||||
|
||||
const char *drv = PrefsFindString("sdlrender");
|
||||
if (drv && drv[0]) {
|
||||
if (strcmp(drv, "software") == 0)
|
||||
render_driver = RENDER_SOFTWARE;
|
||||
else if (strcmp(drv, "opengl") == 0)
|
||||
render_driver = RENDER_OPENGL;
|
||||
else if (strcmp(drv, "direct3d") == 0)
|
||||
render_driver = RENDER_DIRECT3D;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
static void read_SDL_graphics_settings(void)
|
||||
{
|
||||
const char *rpref;
|
||||
switch (render_driver) {
|
||||
case RENDER_SOFTWARE:
|
||||
rpref = "software";
|
||||
break;
|
||||
case RENDER_OPENGL:
|
||||
rpref = "opengl";
|
||||
break;
|
||||
case RENDER_DIRECT3D:
|
||||
rpref = "direct3d";
|
||||
break;
|
||||
default:
|
||||
PrefsRemoveItem("sdlrender");
|
||||
return;
|
||||
}
|
||||
PrefsReplaceString("sdlrender", rpref);
|
||||
}
|
||||
|
||||
// Read settings from widgets and set preferences
|
||||
@ -1051,6 +1406,10 @@ static void read_graphics_settings(void)
|
||||
return;
|
||||
}
|
||||
PrefsReplaceString("screen", pref);
|
||||
|
||||
#ifdef USE_SDL_VIDEO
|
||||
read_SDL_graphics_settings();
|
||||
#endif
|
||||
}
|
||||
|
||||
// Create "Graphics/Sound" pane
|
||||
@ -1160,6 +1519,39 @@ static void create_graphics_pane(GtkWidget *top)
|
||||
make_checkbox(box, STR_GFXACCEL_CTRL, "gfxaccel", GTK_SIGNAL_FUNC(tb_gfxaccel));
|
||||
#endif
|
||||
|
||||
#ifdef USE_SDL_VIDEO
|
||||
make_separator(box);
|
||||
|
||||
table = make_table(box, 2, 5);
|
||||
|
||||
l_render_driver = gtk_label_new(GetString(STR_GRAPHICS_SDL_RENDER_DRIVER_CTRL));
|
||||
gtk_widget_show(l_render_driver);
|
||||
gtk_table_attach(GTK_TABLE(table), l_render_driver, 0, 1, 0, 1, (GtkAttachOptions)0, (GtkAttachOptions)0, 4, 4);
|
||||
|
||||
w_render_driver = gtk_option_menu_new();
|
||||
gtk_widget_show(w_render_driver);
|
||||
menu = gtk_menu_new();
|
||||
|
||||
add_menu_item(menu, STR_SOFTWARE_LAB, GTK_SIGNAL_FUNC(mn_sdl_software));
|
||||
add_menu_item(menu, STR_OPENGL_LAB, GTK_SIGNAL_FUNC(mn_sdl_opengl));
|
||||
add_menu_item(menu, STR_DIRECT3D_LAB, GTK_SIGNAL_FUNC(mn_sdl_direct3d));
|
||||
switch (render_driver) {
|
||||
case RENDER_SOFTWARE:
|
||||
gtk_menu_set_active(GTK_MENU(menu), 0);
|
||||
break;
|
||||
case RENDER_OPENGL:
|
||||
gtk_menu_set_active(GTK_MENU(menu), 1);
|
||||
break;
|
||||
case RENDER_DIRECT3D:
|
||||
gtk_menu_set_active(GTK_MENU(menu), 2);
|
||||
break;
|
||||
}
|
||||
gtk_option_menu_set_menu(GTK_OPTION_MENU(w_render_driver), menu);
|
||||
gtk_table_attach(GTK_TABLE(table), w_render_driver, 1, 2, 0, 1, (GtkAttachOptions)GTK_FILL, (GtkAttachOptions)0, 4, 4);
|
||||
|
||||
opt = make_checkbox(box, STR_GRAPHICS_SDL_VSYNC_CTRL, "sdl_vsync", GTK_SIGNAL_FUNC(tb_sdl_vsync));
|
||||
#endif
|
||||
|
||||
make_separator(box);
|
||||
make_checkbox(box, STR_NOSOUND_CTRL, "nosound", GTK_SIGNAL_FUNC(tb_nosound));
|
||||
|
||||
@ -1192,6 +1584,12 @@ static void tb_keycodes(GtkWidget *widget)
|
||||
set_input_sensitive();
|
||||
}
|
||||
|
||||
// "Reserve Windows Key" button toggled
|
||||
static void tb_reservewindowskey(GtkWidget *widget)
|
||||
{
|
||||
PrefsReplaceBool("reservewindowskey", GTK_TOGGLE_BUTTON(widget)->active);
|
||||
}
|
||||
|
||||
// "Mouse Wheel Mode" selected
|
||||
static void mn_wheel_page(...) {PrefsReplaceInt32("mousewheelmode", 0); set_input_sensitive();}
|
||||
static void mn_wheel_cursor(...) {PrefsReplaceInt32("mousewheelmode", 1); set_input_sensitive();}
|
||||
@ -1239,6 +1637,8 @@ static void create_input_pane(GtkWidget *top)
|
||||
gtk_box_pack_start(GTK_BOX(hbox), button, FALSE, FALSE, 0);
|
||||
g_object_set_data(G_OBJECT(w_keycode_file), "chooser_button", button);
|
||||
|
||||
make_checkbox(box, STR_RESERVE_WINDOWS_KEY_CTRL, "reservewindowskey", GTK_SIGNAL_FUNC(tb_reservewindowskey));
|
||||
|
||||
make_separator(box);
|
||||
|
||||
static const opt_desc options[] = {
|
||||
@ -1466,24 +1866,25 @@ static int create_ether_menu(GtkWidget *menu)
|
||||
n_items++;
|
||||
|
||||
// Basilisk II Ethernet Adapter
|
||||
PacketOpenAdapter("", 0);
|
||||
PacketOpenAdapter(TEXT(""), 0);
|
||||
{
|
||||
ULONG sz;
|
||||
char names[1024];
|
||||
TCHAR names[1024];
|
||||
sz = sizeof(names);
|
||||
if (PacketGetAdapterNames(NULL, names, &sz) == ERROR_SUCCESS) {
|
||||
char *p = names;
|
||||
TCHAR *p = names;
|
||||
while (*p) {
|
||||
const char DEVICE_HEADER[] = "\\Device\\B2ether_";
|
||||
if (strnicmp(p, DEVICE_HEADER, sizeof(DEVICE_HEADER) - 1) == 0) {
|
||||
const TCHAR DEVICE_HEADER[] = TEXT("\\Device\\B2ether_");
|
||||
if (_tcsnicmp(p, DEVICE_HEADER, sizeof(DEVICE_HEADER) - 1) == 0) {
|
||||
LPADAPTER fd = PacketOpenAdapter(p + sizeof(DEVICE_HEADER) - 1, 0);
|
||||
if (fd) {
|
||||
char guid[256];
|
||||
sprintf(guid, "%s", p + sizeof(DEVICE_HEADER) - 1);
|
||||
const char *name = ether_guid_to_name(guid);
|
||||
if (name && (name = g_locale_to_utf8(name, -1, NULL, NULL, NULL))) {
|
||||
add_menu_item(menu, name, (GtkSignalFunc)mn_ether_b2ether, strdup(guid));
|
||||
if (etherguid && strcmp(guid, etherguid) == 0 &&
|
||||
TCHAR guid[256];
|
||||
_stprintf(guid, TEXT("%s"), p + sizeof(DEVICE_HEADER) - 1);
|
||||
const gchar *name = tchar_to_g_utf8(ether_guid_to_name(guid));
|
||||
if (name) {
|
||||
std::string str_guid = to_string(guid);
|
||||
add_menu_item(menu, name, (GtkSignalFunc)mn_ether_b2ether, strdup(str_guid.c_str()));
|
||||
if (etherguid && to_tstring(guid).compare(to_tstring(etherguid)) == 0 &&
|
||||
ether && strcmp(ether, "b2ether") == 0)
|
||||
active = n_items;
|
||||
n_items++;
|
||||
@ -1491,26 +1892,27 @@ static int create_ether_menu(GtkWidget *menu)
|
||||
PacketCloseAdapter(fd);
|
||||
}
|
||||
}
|
||||
p += strlen(p) + 1;
|
||||
p += _tcslen(p) + 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
PacketCloseAdapter(NULL);
|
||||
|
||||
// TAP-Win32
|
||||
const char *tap_devices;
|
||||
const TCHAR *tap_devices;
|
||||
if ((tap_devices = ether_tap_devices()) != NULL) {
|
||||
const char *guid = tap_devices;
|
||||
const TCHAR *guid = tap_devices;
|
||||
while (*guid) {
|
||||
const char *name = ether_guid_to_name(guid);
|
||||
if (name && (name = g_locale_to_utf8(name, -1, NULL, NULL, NULL))) {
|
||||
add_menu_item(menu, name, (GtkSignalFunc)mn_ether_tap, strdup(guid));
|
||||
if (etherguid && strcmp(guid, etherguid) == 0 &&
|
||||
const gchar *name = tchar_to_g_utf8(ether_guid_to_name(guid));
|
||||
if (name) {
|
||||
std::string str_guid = to_string(guid);
|
||||
add_menu_item(menu, name, (GtkSignalFunc)mn_ether_tap, strdup(str_guid.c_str()));
|
||||
if (etherguid && to_tstring(guid).compare(to_tstring(etherguid)) == 0 &&
|
||||
ether && strcmp(ether, "tap") == 0)
|
||||
active = n_items;
|
||||
n_items++;
|
||||
}
|
||||
guid += strlen(guid) + 1;
|
||||
guid += _tcslen(guid) + 1;
|
||||
}
|
||||
free((char *)tap_devices);
|
||||
}
|
||||
@ -1734,21 +2136,66 @@ void SysAddSerialPrefs(void)
|
||||
* Display alerts
|
||||
*/
|
||||
|
||||
static HWND GetMainWindowHandle() {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static void display_alert(int title_id, const char *text, int flags)
|
||||
{
|
||||
MessageBox(NULL, text, GetString(title_id), MB_OK | flags);
|
||||
HWND hMainWnd = GetMainWindowHandle();
|
||||
MessageBoxA(hMainWnd, text, GetString(title_id), MB_OK | flags);
|
||||
}
|
||||
#ifdef _UNICODE
|
||||
static void display_alert(int title_id, const wchar_t *text, int flags)
|
||||
{
|
||||
HWND hMainWnd = GetMainWindowHandle();
|
||||
MessageBoxW(hMainWnd, text, GetStringW(title_id).get(), MB_OK | flags);
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
/*
|
||||
* Display error alert
|
||||
*/
|
||||
|
||||
void ErrorAlert(const char *text)
|
||||
{
|
||||
if (PrefsFindBool("nogui"))
|
||||
return;
|
||||
|
||||
display_alert(STR_ERROR_ALERT_TITLE, text, MB_ICONSTOP);
|
||||
}
|
||||
#ifdef _UNICODE
|
||||
void ErrorAlert(const wchar_t *text)
|
||||
{
|
||||
if (PrefsFindBool("nogui"))
|
||||
return;
|
||||
|
||||
display_alert(STR_ERROR_ALERT_TITLE, text, MB_ICONSTOP);
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
/*
|
||||
* Display warning alert
|
||||
*/
|
||||
|
||||
void WarningAlert(const char *text)
|
||||
{
|
||||
if (PrefsFindBool("nogui"))
|
||||
return;
|
||||
|
||||
display_alert(STR_WARNING_ALERT_TITLE, text, MB_ICONSTOP);
|
||||
}
|
||||
#ifdef _UNICODE
|
||||
void WarningAlert(const wchar_t *text)
|
||||
{
|
||||
if (PrefsFindBool("nogui"))
|
||||
return;
|
||||
|
||||
display_alert(STR_WARNING_ALERT_TITLE, text, MB_ICONSTOP);
|
||||
}
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Start standalone GUI
|
||||
@ -1774,23 +2221,23 @@ int main(int argc, char *argv[])
|
||||
|
||||
// Transfer control to the executable
|
||||
if (start) {
|
||||
char path[_MAX_PATH];
|
||||
TCHAR path[_MAX_PATH];
|
||||
bool ok = GetModuleFileName(NULL, path, sizeof(path)) != 0;
|
||||
if (ok) {
|
||||
char b2_path[_MAX_PATH];
|
||||
char *p = strrchr(path, '\\');
|
||||
*++p = '\0';
|
||||
TCHAR b2_path[_MAX_PATH];
|
||||
TCHAR *p = _tcsrchr(path, TEXT('\\'));
|
||||
*++p = TEXT('\0');
|
||||
SetCurrentDirectory(path);
|
||||
strcpy(b2_path, path);
|
||||
strcat(b2_path, PROGRAM_NAME);
|
||||
strcat(b2_path, ".exe");
|
||||
HINSTANCE h = ShellExecute(GetDesktopWindow(), "open",
|
||||
b2_path, "", path, SW_SHOWNORMAL);
|
||||
_tcscpy(b2_path, path);
|
||||
_tcscat(b2_path, TEXT(PROGRAM_NAME));
|
||||
_tcscat(b2_path, TEXT(".exe"));
|
||||
HINSTANCE h = ShellExecute(GetDesktopWindow(), TEXT("open"),
|
||||
b2_path, TEXT(""), path, SW_SHOWNORMAL);
|
||||
if ((int)h <= 32)
|
||||
ok = false;
|
||||
}
|
||||
if (!ok) {
|
||||
ErrorAlert("Coult not start " PROGRAM_NAME " executable");
|
||||
ErrorAlert(TEXT("Could not start ") TEXT(PROGRAM_NAME) TEXT(" executable"));
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
|
@ -35,9 +35,6 @@ prefs_desc platform_prefs_items[] = {
|
||||
{"keycodefile", TYPE_STRING, false, "path of keycode translation file"},
|
||||
{"mousewheelmode", TYPE_INT32, false, "mouse wheel support mode (0=page up/down, 1=cursor up/down)"},
|
||||
{"mousewheellines", TYPE_INT32, false, "number of lines to scroll in mouse wheel mode 1"},
|
||||
#ifdef HAVE_SIGSEGV_SKIP_INSTRUCTION
|
||||
{"ignoresegv", TYPE_BOOLEAN, false, "ignore illegal memory accesses"},
|
||||
#endif
|
||||
{"idlewait", TYPE_BOOLEAN, false, "sleep when idle"},
|
||||
{"enableextfs", TYPE_BOOLEAN, false, "enable extfs system"},
|
||||
{"debugextfs", TYPE_BOOLEAN, false, "debug extfs system"},
|
||||
@ -52,6 +49,12 @@ prefs_desc platform_prefs_items[] = {
|
||||
{"tcp_port", TYPE_STRING, false, "TCP ports list"},
|
||||
{"portfile0", TYPE_STRING, false, "output file for serial port 0"},
|
||||
{"portfile1", TYPE_STRING, false, "output file for serial port 1"},
|
||||
#ifdef USE_SDL_VIDEO
|
||||
{"sdlrender", TYPE_STRING, false, "SDL_Renderer driver (\"auto\", \"software\" (may be faster), etc.)"},
|
||||
{"sdl_vsync", TYPE_BOOLEAN, false, "Make SDL_Renderer vertical sync frames to host (eg. with software renderer)"},
|
||||
#endif
|
||||
{"reservewindowskey", TYPE_BOOLEAN, false, "block Windows key from activating start menu"},
|
||||
|
||||
|
||||
{NULL, TYPE_END, false, NULL} // End of list
|
||||
};
|
||||
@ -123,9 +126,6 @@ void AddPlatformPrefsDefaults(void)
|
||||
PrefsReplaceString("extdrives", "CDEFGHIJKLMNOPQRSTUVWXYZ");
|
||||
PrefsReplaceInt32("mousewheelmode", 1);
|
||||
PrefsReplaceInt32("mousewheellines", 3);
|
||||
#ifdef HAVE_SIGSEGV_SKIP_INSTRUCTION
|
||||
PrefsAddBool("ignoresegv", false);
|
||||
#endif
|
||||
PrefsAddBool("idlewait", true);
|
||||
PrefsReplaceBool("etherpermanentaddress", true);
|
||||
PrefsReplaceInt32("ethermulticastmode", 0);
|
||||
@ -134,4 +134,9 @@ void AddPlatformPrefsDefaults(void)
|
||||
PrefsReplaceString("serialb", "COM2");
|
||||
PrefsReplaceString("portfile0", "C:\\B2TEMP0.OUT");
|
||||
PrefsReplaceString("portfile1", "C:\\B2TEMP1.OUT");
|
||||
#ifdef USE_SDL_VIDEO
|
||||
PrefsReplaceString("sdlrender", "software");
|
||||
PrefsReplaceBool("sdl_vsync", false);
|
||||
#endif
|
||||
PrefsAddBool("reservewindowskey", false);
|
||||
}
|
||||
|
@ -40,6 +40,10 @@ using std::min;
|
||||
#include "cdenable/cache.h"
|
||||
#include "cdenable/eject_nt.h"
|
||||
|
||||
#if defined(BINCUE)
|
||||
#include "bincue.h"
|
||||
#endif
|
||||
|
||||
#define DEBUG 0
|
||||
#include "debug.h"
|
||||
|
||||
@ -56,6 +60,23 @@ struct file_handle {
|
||||
loff_t file_size; // Size of file data (only valid if is_file is true)
|
||||
cachetype cache;
|
||||
bool is_media_present;
|
||||
bool is_tray_locked;
|
||||
HANDLE storage_ejection_handle; // Handle used for storage ejection prevention
|
||||
|
||||
#if defined(BINCUE)
|
||||
bool is_bincue; // Flag: BIN CUE file
|
||||
void *bincue_fd;
|
||||
#endif
|
||||
file_handle() {
|
||||
// Since our PreventRemovalOfVolume implementaion on Windows increments a lock counter,
|
||||
// let's have our own safeguard to prevent incrementing it more than once.
|
||||
is_tray_locked = false;
|
||||
storage_ejection_handle = NULL;
|
||||
#if defined(BINCUE)
|
||||
is_bincue = false; // default bincue false
|
||||
#endif
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
// Open file handles
|
||||
@ -74,7 +95,7 @@ static char *sector_buffer = NULL;
|
||||
|
||||
// Prototypes
|
||||
static bool is_cdrom_readable(file_handle *fh);
|
||||
|
||||
static DWORD file_offset_read(HANDLE fh, loff_t offset, int count, char *buf);
|
||||
|
||||
/*
|
||||
* Initialization
|
||||
@ -256,12 +277,42 @@ void SysAddSerialPrefs(void)
|
||||
* Can't give too much however, would be annoying, this is difficult..
|
||||
*/
|
||||
|
||||
static inline int cd_read_with_retry(file_handle *fh, ULONG LBA, int count, char *buf )
|
||||
static inline int cd_read_with_retry(file_handle *fh, ULONG offset, int count, char *buf )
|
||||
{
|
||||
if (!fh || !fh->fh)
|
||||
return 0;
|
||||
|
||||
return CdenableSysReadCdBytes(fh->fh, LBA, count, buf);
|
||||
DWORD bytes_read = CdenableSysReadCdBytes(fh->fh, offset, count, buf);
|
||||
|
||||
if (bytes_read == 0) {
|
||||
// fall back to logical volume handle read in the case where there's no cdenable
|
||||
bytes_read = file_offset_read(fh->fh, offset, count, buf);
|
||||
}
|
||||
|
||||
return bytes_read;
|
||||
}
|
||||
|
||||
/*
|
||||
* Generic offset read function for a file or a device that behaves like one
|
||||
*/
|
||||
|
||||
static DWORD file_offset_read(HANDLE fh, loff_t offset, int count, char *buf)
|
||||
{
|
||||
// Seek to position
|
||||
LONG lo = (LONG)offset;
|
||||
LONG hi = (LONG)(offset >> 32);
|
||||
DWORD r = SetFilePointer(fh, lo, &hi, FILE_BEGIN);
|
||||
if (r == INVALID_SET_FILE_POINTER && GetLastError() != NO_ERROR) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
DWORD bytes_read;
|
||||
|
||||
// Read data
|
||||
if (ReadFile(fh, buf, count, &bytes_read, NULL) == 0)
|
||||
bytes_read = 0;
|
||||
|
||||
return bytes_read;
|
||||
}
|
||||
|
||||
static int cd_read(file_handle *fh, cachetype *cptr, ULONG LBA, int count, char *buf)
|
||||
@ -406,7 +457,7 @@ static bool is_read_only_path(const TCHAR *name)
|
||||
* Open file/device, create new file handle (returns NULL on error)
|
||||
*/
|
||||
|
||||
void *Sys_open(const char *path_name, bool read_only)
|
||||
void *Sys_open(const char *path_name, bool read_only, bool is_cdrom)
|
||||
{
|
||||
file_handle * fh = NULL;
|
||||
|
||||
@ -462,6 +513,11 @@ void *Sys_open(const char *path_name, bool read_only)
|
||||
read_only = true;
|
||||
|
||||
// Open file
|
||||
|
||||
#if defined(BINCUE)
|
||||
void *binfd = open_bincue(name); // check if bincue
|
||||
#endif
|
||||
|
||||
HANDLE h = CreateFile(
|
||||
name,
|
||||
read_only ? GENERIC_READ : GENERIC_READ | GENERIC_WRITE,
|
||||
@ -486,6 +542,16 @@ void *Sys_open(const char *path_name, bool read_only)
|
||||
fh->is_floppy = false;
|
||||
fh->is_cdrom = false;
|
||||
|
||||
#if defined(BINCUE)
|
||||
if (binfd) {
|
||||
fh->bincue_fd = binfd;
|
||||
fh->is_bincue = true;
|
||||
fh->is_media_present = true;
|
||||
sys_add_file_handle(fh);
|
||||
return fh;
|
||||
}
|
||||
#endif
|
||||
|
||||
// Detect disk image file layout
|
||||
loff_t size = GetFileSize(h, NULL);
|
||||
DWORD bytes_read;
|
||||
@ -517,10 +583,19 @@ void Sys_close(void *arg)
|
||||
|
||||
sys_remove_file_handle(fh);
|
||||
|
||||
#if defined(BINCUE)
|
||||
if (fh->is_bincue)
|
||||
close_bincue(fh->bincue_fd);
|
||||
#endif
|
||||
|
||||
if (fh->is_cdrom) {
|
||||
cache_final(&fh->cache);
|
||||
SysAllowRemoval((void *)fh);
|
||||
}
|
||||
if (fh->storage_ejection_handle != NULL) {
|
||||
CloseHandle(fh->storage_ejection_handle);
|
||||
fh->storage_ejection_handle = NULL;
|
||||
}
|
||||
if (fh->fh != NULL) {
|
||||
CloseHandle(fh->fh);
|
||||
fh->fh = NULL;
|
||||
@ -543,19 +618,15 @@ size_t Sys_read(void *arg, void *buffer, loff_t offset, size_t length)
|
||||
if (!fh)
|
||||
return 0;
|
||||
|
||||
#if defined(BINCUE)
|
||||
if (fh->is_bincue)
|
||||
return read_bincue(fh->bincue_fd, buffer, offset, length);
|
||||
#endif
|
||||
|
||||
DWORD bytes_read = 0;
|
||||
|
||||
if (fh->is_file) {
|
||||
// Seek to position
|
||||
LONG lo = (LONG)offset;
|
||||
LONG hi = (LONG)(offset >> 32);
|
||||
DWORD r = SetFilePointer(fh->fh, lo, &hi, FILE_BEGIN);
|
||||
if (r == INVALID_SET_FILE_POINTER && GetLastError() != NO_ERROR)
|
||||
return 0;
|
||||
|
||||
// Read data
|
||||
if (ReadFile(fh->fh, buffer, length, &bytes_read, NULL) == 0)
|
||||
bytes_read = 0;
|
||||
bytes_read = file_offset_read(fh->fh, offset, length, (char *)buffer);
|
||||
}
|
||||
else if (fh->is_cdrom) {
|
||||
int bytes_left, try_bytes, got_bytes;
|
||||
@ -623,6 +694,11 @@ loff_t SysGetFileSize(void *arg)
|
||||
if (!fh)
|
||||
return true;
|
||||
|
||||
#if defined(BINCUE)
|
||||
if (fh->is_bincue)
|
||||
return size_bincue(fh->bincue_fd);
|
||||
#endif
|
||||
|
||||
if (fh->is_file)
|
||||
return fh->file_size;
|
||||
else if (fh->is_cdrom)
|
||||
@ -633,6 +709,35 @@ loff_t SysGetFileSize(void *arg)
|
||||
}
|
||||
}
|
||||
|
||||
static void PreventRemovalCommon(file_handle * fh, bool val) {
|
||||
D(bug("PreventRemovalCommon %p %d\n", fh, val));
|
||||
if (!fh) return;
|
||||
if (!fh->is_cdrom) return;
|
||||
if (!fh->name) return;
|
||||
D(bug(" seems ok to do\n"));
|
||||
|
||||
if (fh->storage_ejection_handle == NULL) {
|
||||
// we need a device handle with just FILE_READ_ATTRIBUTES
|
||||
TCHAR device_name[MAX_PATH];
|
||||
_sntprintf(device_name, lengthof(device_name), TEXT("\\\\.\\%c:"), fh->name[0]);
|
||||
|
||||
// Open device
|
||||
HANDLE h = CreateFile(
|
||||
device_name,
|
||||
FILE_READ_ATTRIBUTES,
|
||||
0, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
|
||||
|
||||
if (h == INVALID_HANDLE_VALUE) {
|
||||
D(bug(" failed to get suitable handle\n"));
|
||||
return;
|
||||
}
|
||||
|
||||
fh->storage_ejection_handle = h;
|
||||
}
|
||||
|
||||
PreventRemovalOfVolume(fh->storage_ejection_handle, val);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Eject volume (if applicable)
|
||||
@ -644,15 +749,22 @@ void SysEject(void *arg)
|
||||
if (!fh)
|
||||
return;
|
||||
|
||||
#if defined(BINCUE)
|
||||
if (fh->is_bincue) {
|
||||
fh->is_media_present = false;
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
|
||||
if (fh->is_cdrom && fh->fh) {
|
||||
fh->is_media_present = false;
|
||||
// Commented out because there was some problems, but can't remember
|
||||
// exactly ... need to find out
|
||||
// EjectVolume(toupper(*fh->name),false);
|
||||
|
||||
// Preventing is cumulative, try to make sure it's indeed released now
|
||||
for (int i = 0; i < 10; i++)
|
||||
PreventRemovalOfVolume(fh->fh, false);
|
||||
D(bug("SysEject disabling PreventRemoval\n"));
|
||||
PreventRemovalCommon(fh, false);
|
||||
fh->is_tray_locked = false;
|
||||
|
||||
if (!PrefsFindBool("nocdrom")) {
|
||||
DWORD dummy;
|
||||
@ -751,12 +863,16 @@ bool SysIsDiskInserted(void *arg)
|
||||
|
||||
void SysPreventRemoval(void *arg)
|
||||
{
|
||||
D(bug("SysPreventRemoval %p\n", arg));
|
||||
file_handle *fh = (file_handle *)arg;
|
||||
if (!fh)
|
||||
return;
|
||||
|
||||
if (fh->is_cdrom && fh->fh)
|
||||
PreventRemovalOfVolume(fh->fh, true);
|
||||
if (fh->is_cdrom && fh->fh && !fh->is_tray_locked) {
|
||||
D(bug(" doing prevent removal\n"));
|
||||
PreventRemovalCommon(fh, true);
|
||||
fh->is_tray_locked = true;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -766,12 +882,16 @@ void SysPreventRemoval(void *arg)
|
||||
|
||||
void SysAllowRemoval(void *arg)
|
||||
{
|
||||
D(bug("SysAllowRemoval %p\n", arg));
|
||||
file_handle *fh = (file_handle *)arg;
|
||||
if (!fh)
|
||||
return;
|
||||
|
||||
if (fh->is_cdrom && fh->fh)
|
||||
PreventRemovalOfVolume(fh->fh, false);
|
||||
if (fh->is_cdrom && fh->fh) {
|
||||
D(bug(" doing allow removal\n"));
|
||||
PreventRemovalCommon(fh, false);
|
||||
fh->is_tray_locked = false;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -782,16 +902,26 @@ void SysAllowRemoval(void *arg)
|
||||
bool SysCDReadTOC(void *arg, uint8 *toc)
|
||||
{
|
||||
file_handle *fh = (file_handle *)arg;
|
||||
if (!fh || !fh->fh || !fh->is_cdrom)
|
||||
if (!fh)
|
||||
return false;
|
||||
|
||||
DWORD dummy;
|
||||
return DeviceIoControl(fh->fh,
|
||||
IOCTL_CDROM_READ_TOC,
|
||||
NULL, 0,
|
||||
toc, min((int)sizeof(CDROM_TOC), 804),
|
||||
&dummy,
|
||||
NULL) != FALSE;
|
||||
#if defined(BINCUE)
|
||||
if (fh->is_bincue)
|
||||
return readtoc_bincue(fh->bincue_fd, toc);
|
||||
#endif
|
||||
|
||||
if (fh->is_cdrom) {
|
||||
|
||||
DWORD dummy;
|
||||
return DeviceIoControl(fh->fh,
|
||||
IOCTL_CDROM_READ_TOC,
|
||||
NULL, 0,
|
||||
toc, min((int)sizeof(CDROM_TOC), 804),
|
||||
&dummy,
|
||||
NULL) != FALSE;
|
||||
|
||||
} else
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
@ -802,26 +932,34 @@ bool SysCDReadTOC(void *arg, uint8 *toc)
|
||||
bool SysCDGetPosition(void *arg, uint8 *pos)
|
||||
{
|
||||
file_handle *fh = (file_handle *)arg;
|
||||
if (!fh || !fh->fh || !fh->is_cdrom)
|
||||
if (!fh)
|
||||
return false;
|
||||
|
||||
SUB_Q_CHANNEL_DATA q_data;
|
||||
#if defined(BINCUE)
|
||||
if (fh->is_bincue)
|
||||
return GetPosition_bincue(fh->bincue_fd, pos);
|
||||
#endif
|
||||
|
||||
CDROM_SUB_Q_DATA_FORMAT q_format;
|
||||
q_format.Format = IOCTL_CDROM_CURRENT_POSITION;
|
||||
q_format.Track = 0; // used only by ISRC reads
|
||||
if (fh->is_cdrom) {
|
||||
SUB_Q_CHANNEL_DATA q_data;
|
||||
|
||||
DWORD dwBytesReturned = 0;
|
||||
bool ok = DeviceIoControl(fh->fh,
|
||||
IOCTL_CDROM_READ_Q_CHANNEL,
|
||||
&q_format, sizeof(CDROM_SUB_Q_DATA_FORMAT),
|
||||
&q_data, sizeof(SUB_Q_CHANNEL_DATA),
|
||||
&dwBytesReturned,
|
||||
NULL) != FALSE;
|
||||
if (ok)
|
||||
memcpy(pos, &q_data.CurrentPosition, sizeof(SUB_Q_CURRENT_POSITION));
|
||||
CDROM_SUB_Q_DATA_FORMAT q_format;
|
||||
q_format.Format = IOCTL_CDROM_CURRENT_POSITION;
|
||||
q_format.Track = 0; // used only by ISRC reads
|
||||
|
||||
return ok;
|
||||
DWORD dwBytesReturned = 0;
|
||||
bool ok = DeviceIoControl(fh->fh,
|
||||
IOCTL_CDROM_READ_Q_CHANNEL,
|
||||
&q_format, sizeof(CDROM_SUB_Q_DATA_FORMAT),
|
||||
&q_data, sizeof(SUB_Q_CHANNEL_DATA),
|
||||
&dwBytesReturned,
|
||||
NULL) != FALSE;
|
||||
if (ok)
|
||||
memcpy(pos, &q_data.CurrentPosition, sizeof(SUB_Q_CURRENT_POSITION));
|
||||
|
||||
return ok;
|
||||
} else
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
@ -832,24 +970,32 @@ bool SysCDGetPosition(void *arg, uint8 *pos)
|
||||
bool SysCDPlay(void *arg, uint8 start_m, uint8 start_s, uint8 start_f, uint8 end_m, uint8 end_s, uint8 end_f)
|
||||
{
|
||||
file_handle *fh = (file_handle *)arg;
|
||||
if (!fh || !fh->fh || !fh->is_cdrom)
|
||||
if (!fh)
|
||||
return false;
|
||||
|
||||
CDROM_PLAY_AUDIO_MSF msf;
|
||||
msf.StartingM = start_m;
|
||||
msf.StartingS = start_s;
|
||||
msf.StartingF = start_f;
|
||||
msf.EndingM = end_m;
|
||||
msf.EndingS = end_s;
|
||||
msf.EndingF = end_f;
|
||||
#if defined(BINCUE)
|
||||
if (fh->is_bincue)
|
||||
return CDPlay_bincue(fh->bincue_fd, start_m, start_s, start_f, end_m, end_s, end_f);
|
||||
#endif
|
||||
|
||||
DWORD dwBytesReturned = 0;
|
||||
return DeviceIoControl(fh->fh,
|
||||
IOCTL_CDROM_PLAY_AUDIO_MSF,
|
||||
&msf, sizeof(CDROM_PLAY_AUDIO_MSF),
|
||||
NULL, 0,
|
||||
&dwBytesReturned,
|
||||
NULL) != FALSE;
|
||||
if (fh->is_cdrom) {
|
||||
CDROM_PLAY_AUDIO_MSF msf;
|
||||
msf.StartingM = start_m;
|
||||
msf.StartingS = start_s;
|
||||
msf.StartingF = start_f;
|
||||
msf.EndingM = end_m;
|
||||
msf.EndingS = end_s;
|
||||
msf.EndingF = end_f;
|
||||
|
||||
DWORD dwBytesReturned = 0;
|
||||
return DeviceIoControl(fh->fh,
|
||||
IOCTL_CDROM_PLAY_AUDIO_MSF,
|
||||
&msf, sizeof(CDROM_PLAY_AUDIO_MSF),
|
||||
NULL, 0,
|
||||
&dwBytesReturned,
|
||||
NULL) != FALSE;
|
||||
} else
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
@ -860,16 +1006,24 @@ bool SysCDPlay(void *arg, uint8 start_m, uint8 start_s, uint8 start_f, uint8 end
|
||||
bool SysCDPause(void *arg)
|
||||
{
|
||||
file_handle *fh = (file_handle *)arg;
|
||||
if (!fh || !fh->fh || !fh->is_cdrom)
|
||||
if (!fh)
|
||||
return false;
|
||||
|
||||
DWORD dwBytesReturned = 0;
|
||||
return DeviceIoControl(fh->fh,
|
||||
IOCTL_CDROM_PAUSE_AUDIO,
|
||||
NULL, 0,
|
||||
NULL, 0,
|
||||
&dwBytesReturned,
|
||||
NULL) != FALSE;
|
||||
#if defined(BINCUE)
|
||||
if (fh->is_bincue)
|
||||
return CDPause_bincue(fh->bincue_fd);
|
||||
#endif
|
||||
|
||||
if (fh->is_cdrom) {
|
||||
DWORD dwBytesReturned = 0;
|
||||
return DeviceIoControl(fh->fh,
|
||||
IOCTL_CDROM_PAUSE_AUDIO,
|
||||
NULL, 0,
|
||||
NULL, 0,
|
||||
&dwBytesReturned,
|
||||
NULL) != FALSE;
|
||||
} else
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
@ -880,15 +1034,23 @@ bool SysCDPause(void *arg)
|
||||
bool SysCDResume(void *arg)
|
||||
{
|
||||
file_handle *fh = (file_handle *)arg;
|
||||
if (!fh || !fh->fh || !fh->is_cdrom)
|
||||
if (!fh)
|
||||
return false;
|
||||
|
||||
DWORD dwBytesReturned = 0;
|
||||
return DeviceIoControl(fh->fh,
|
||||
IOCTL_CDROM_RESUME_AUDIO,
|
||||
NULL, 0,
|
||||
NULL, 0,
|
||||
&dwBytesReturned, NULL) != FALSE;
|
||||
#if defined(BINCUE)
|
||||
if (fh->is_bincue)
|
||||
return CDResume_bincue(fh->bincue_fd);
|
||||
#endif
|
||||
|
||||
if (fh->is_cdrom) {
|
||||
DWORD dwBytesReturned = 0;
|
||||
return DeviceIoControl(fh->fh,
|
||||
IOCTL_CDROM_RESUME_AUDIO,
|
||||
NULL, 0,
|
||||
NULL, 0,
|
||||
&dwBytesReturned, NULL) != FALSE;
|
||||
} else
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
@ -899,16 +1061,24 @@ bool SysCDResume(void *arg)
|
||||
bool SysCDStop(void *arg, uint8 lead_out_m, uint8 lead_out_s, uint8 lead_out_f)
|
||||
{
|
||||
file_handle *fh = (file_handle *)arg;
|
||||
if (!fh || !fh->fh || !fh->is_cdrom)
|
||||
if (!fh)
|
||||
return false;
|
||||
|
||||
DWORD dwBytesReturned = 0;
|
||||
return DeviceIoControl(fh->fh,
|
||||
IOCTL_CDROM_STOP_AUDIO,
|
||||
NULL, 0,
|
||||
NULL, 0,
|
||||
&dwBytesReturned,
|
||||
NULL) != FALSE;
|
||||
#if defined(BINCUE)
|
||||
if (fh->is_bincue)
|
||||
return CDStop_bincue(fh->bincue_fd);
|
||||
#endif
|
||||
|
||||
if (fh->is_cdrom) {
|
||||
DWORD dwBytesReturned = 0;
|
||||
return DeviceIoControl(fh->fh,
|
||||
IOCTL_CDROM_STOP_AUDIO,
|
||||
NULL, 0,
|
||||
NULL, 0,
|
||||
&dwBytesReturned,
|
||||
NULL) != FALSE;
|
||||
} else
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
@ -919,21 +1089,30 @@ bool SysCDStop(void *arg, uint8 lead_out_m, uint8 lead_out_s, uint8 lead_out_f)
|
||||
bool SysCDScan(void *arg, uint8 start_m, uint8 start_s, uint8 start_f, bool reverse)
|
||||
{
|
||||
file_handle *fh = (file_handle *)arg;
|
||||
if (!fh || !fh->fh || !fh->is_cdrom)
|
||||
if (!fh)
|
||||
return false;
|
||||
|
||||
CDROM_SEEK_AUDIO_MSF msf;
|
||||
msf.M = start_m;
|
||||
msf.S = start_s;
|
||||
msf.F = start_f;
|
||||
#if defined(BINCUE)
|
||||
if (fh->is_bincue)
|
||||
return CDScan_bincue(fh->bincue_fd,start_m,start_s,start_f,reverse);
|
||||
#endif
|
||||
|
||||
DWORD dwBytesReturned = 0;
|
||||
return DeviceIoControl(fh->fh,
|
||||
IOCTL_CDROM_SEEK_AUDIO_MSF,
|
||||
&msf, sizeof(CDROM_SEEK_AUDIO_MSF),
|
||||
NULL, 0,
|
||||
&dwBytesReturned,
|
||||
NULL) != FALSE;
|
||||
if (fh->is_cdrom) {
|
||||
|
||||
CDROM_SEEK_AUDIO_MSF msf;
|
||||
msf.M = start_m;
|
||||
msf.S = start_s;
|
||||
msf.F = start_f;
|
||||
|
||||
DWORD dwBytesReturned = 0;
|
||||
return DeviceIoControl(fh->fh,
|
||||
IOCTL_CDROM_SEEK_AUDIO_MSF,
|
||||
&msf, sizeof(CDROM_SEEK_AUDIO_MSF),
|
||||
NULL, 0,
|
||||
&dwBytesReturned,
|
||||
NULL) != FALSE;
|
||||
} else
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
@ -944,22 +1123,30 @@ bool SysCDScan(void *arg, uint8 start_m, uint8 start_s, uint8 start_f, bool reve
|
||||
void SysCDSetVolume(void *arg, uint8 left, uint8 right)
|
||||
{
|
||||
file_handle *fh = (file_handle *)arg;
|
||||
if (!fh || !fh->fh || !fh->is_cdrom)
|
||||
if (!fh)
|
||||
return;
|
||||
|
||||
VOLUME_CONTROL vc;
|
||||
vc.PortVolume[0] = left;
|
||||
vc.PortVolume[1] = right;
|
||||
vc.PortVolume[2] = left;
|
||||
vc.PortVolume[3] = right;
|
||||
#if defined(BINCUE)
|
||||
if (fh->is_bincue)
|
||||
CDSetVol_bincue(fh->bincue_fd,left,right);
|
||||
#endif
|
||||
|
||||
DWORD dwBytesReturned = 0;
|
||||
DeviceIoControl(fh->fh,
|
||||
IOCTL_CDROM_SET_VOLUME,
|
||||
&vc, sizeof(VOLUME_CONTROL),
|
||||
NULL, 0,
|
||||
&dwBytesReturned,
|
||||
NULL);
|
||||
if (fh->is_cdrom) {
|
||||
|
||||
VOLUME_CONTROL vc;
|
||||
vc.PortVolume[0] = left;
|
||||
vc.PortVolume[1] = right;
|
||||
vc.PortVolume[2] = left;
|
||||
vc.PortVolume[3] = right;
|
||||
|
||||
DWORD dwBytesReturned = 0;
|
||||
DeviceIoControl(fh->fh,
|
||||
IOCTL_CDROM_SET_VOLUME,
|
||||
&vc, sizeof(VOLUME_CONTROL),
|
||||
NULL, 0,
|
||||
&dwBytesReturned,
|
||||
NULL);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -974,21 +1161,27 @@ void SysCDGetVolume(void *arg, uint8 &left, uint8 &right)
|
||||
return;
|
||||
|
||||
left = right = 0;
|
||||
if (!fh->fh || !fh->is_cdrom)
|
||||
return;
|
||||
|
||||
VOLUME_CONTROL vc;
|
||||
memset(&vc, 0, sizeof(vc));
|
||||
#if defined(BINCUE)
|
||||
if (fh->is_bincue)
|
||||
CDGetVol_bincue(fh->bincue_fd,&left,&right);
|
||||
#endif
|
||||
|
||||
if (fh->is_cdrom) {
|
||||
|
||||
DWORD dwBytesReturned = 0;
|
||||
if (DeviceIoControl(fh->fh,
|
||||
IOCTL_CDROM_GET_VOLUME,
|
||||
NULL, 0,
|
||||
&vc, sizeof(VOLUME_CONTROL),
|
||||
&dwBytesReturned,
|
||||
NULL))
|
||||
{
|
||||
left = vc.PortVolume[0];
|
||||
right = vc.PortVolume[1];
|
||||
VOLUME_CONTROL vc;
|
||||
memset(&vc, 0, sizeof(vc));
|
||||
|
||||
DWORD dwBytesReturned = 0;
|
||||
if (DeviceIoControl(fh->fh,
|
||||
IOCTL_CDROM_GET_VOLUME,
|
||||
NULL, 0,
|
||||
&vc, sizeof(VOLUME_CONTROL),
|
||||
&dwBytesReturned,
|
||||
NULL))
|
||||
{
|
||||
left = vc.PortVolume[0];
|
||||
right = vc.PortVolume[1];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -21,10 +21,6 @@
|
||||
#ifndef SYSDEPS_H
|
||||
#define SYSDEPS_H
|
||||
|
||||
#ifdef __MINGW32__
|
||||
#define _UNICODE
|
||||
#endif
|
||||
|
||||
#if !defined _MSC_VER && !defined __STDC__
|
||||
#error "Your compiler is not ANSI. Get a real one."
|
||||
#endif
|
||||
@ -32,9 +28,9 @@
|
||||
#include "config.h"
|
||||
#include "user_strings_windows.h"
|
||||
|
||||
#ifndef STDC_HEADERS
|
||||
#error "You don't have ANSI C header files."
|
||||
#endif
|
||||
//#ifndef STDC_HEADERS
|
||||
//#error "You don't have ANSI C header files."
|
||||
//#endif
|
||||
|
||||
#ifndef WIN32
|
||||
#define WIN32
|
||||
|
@ -20,7 +20,7 @@
|
||||
|
||||
#include "sysdeps.h"
|
||||
#include "user_strings.h"
|
||||
|
||||
#include "util_windows.h"
|
||||
|
||||
// Platform-specific string definitions
|
||||
user_string_def platform_strings[] = {
|
||||
@ -56,6 +56,7 @@ user_string_def platform_strings[] = {
|
||||
{STR_INPUT_PANE_TITLE, "Keyboard/Mouse"},
|
||||
{STR_KEYCODES_CTRL, "Use Raw Keycodes"},
|
||||
{STR_KEYCODE_FILE_CTRL, "Keycode Translation File"},
|
||||
{STR_RESERVE_WINDOWS_KEY_CTRL, "Reserve Windows Key"},
|
||||
{STR_MOUSEWHEELMODE_CTRL, "Mouse Wheel Function"},
|
||||
{STR_MOUSEWHEELMODE_PAGE_LAB, "Page Up/Down"},
|
||||
{STR_MOUSEWHEELMODE_CURSOR_LAB, "Cursor Up/Down"},
|
||||
@ -81,7 +82,11 @@ static const char *get_volume_name(void)
|
||||
HKEY hHelpKey;
|
||||
DWORD key_type, cbData;
|
||||
|
||||
static char volume[256];
|
||||
#ifdef _UNICODE
|
||||
static char out_volume[256];
|
||||
#endif
|
||||
|
||||
static TCHAR volume[256];
|
||||
memset(volume, 0, sizeof(volume));
|
||||
|
||||
// Try Windows 2000 key first
|
||||
@ -118,14 +123,20 @@ static const char *get_volume_name(void)
|
||||
}
|
||||
|
||||
// Fix the error that some "tweak" apps do.
|
||||
if (_stricmp(volume, "%USERNAME% on %COMPUTER%") == 0)
|
||||
volume[0] = '\0';
|
||||
if (_tcsicmp(volume, TEXT("%USERNAME% on %COMPUTER%")) == 0)
|
||||
volume[0] = TEXT('\0');
|
||||
|
||||
// No volume name found, default to "My Computer"
|
||||
if (volume[0] == 0)
|
||||
strcpy(volume, "My Computer");
|
||||
_tcscpy(volume, TEXT("My Computer"));
|
||||
|
||||
|
||||
#ifdef _UNICODE
|
||||
strlcpy(out_volume, volume, 256);
|
||||
return out_volume;
|
||||
#else
|
||||
return volume;
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
|
@ -58,6 +58,7 @@ enum {
|
||||
STR_INPUT_PANE_TITLE,
|
||||
STR_KEYCODES_CTRL,
|
||||
STR_KEYCODE_FILE_CTRL,
|
||||
STR_RESERVE_WINDOWS_KEY_CTRL,
|
||||
STR_MOUSEWHEELMODE_CTRL,
|
||||
STR_MOUSEWHEELMODE_PAGE_LAB,
|
||||
STR_MOUSEWHEELMODE_CURSOR_LAB,
|
||||
|
@ -401,7 +401,7 @@ const TCHAR *ether_guid_to_name(const TCHAR *guid)
|
||||
|
||||
#define ADAPTER_KEY TEXT("SYSTEM\\CurrentControlSet\\Control\\Class\\{4D36E972-E325-11CE-BFC1-08002BE10318}")
|
||||
|
||||
const _TCHAR * tap_component_ids[] = { TEXT("tap0801"), TEXT("tap0901"), 0 };
|
||||
const _TCHAR * tap_component_ids[] = { TEXT("root\\tap0801"), TEXT("root\\tap0901"), 0 };
|
||||
|
||||
const TCHAR *ether_tap_devices(void)
|
||||
{
|
||||
|
@ -57,6 +57,11 @@ const int KEY_BUFFER_SIZE = 16;
|
||||
static uint8 key_buffer[KEY_BUFFER_SIZE];
|
||||
static unsigned int key_read_ptr = 0, key_write_ptr = 0;
|
||||
|
||||
// O2S: Button event buffer (Mac button with up/down flag) -> avoid to loose tap on a trackpad
|
||||
const int BUTTON_BUFFER_SIZE = 32;
|
||||
static uint8 button_buffer[BUTTON_BUFFER_SIZE];
|
||||
static unsigned int button_read_ptr = 0, button_write_ptr = 0;
|
||||
|
||||
static uint8 mouse_reg_3[2] = {0x63, 0x01}; // Mouse ADB register 3
|
||||
|
||||
static uint8 key_reg_2[2] = {0xff, 0xff}; // Keyboard ADB register 2
|
||||
@ -245,13 +250,17 @@ void ADBMouseMoved(int x, int y)
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
/*
|
||||
* Mouse button pressed
|
||||
*/
|
||||
|
||||
void ADBMouseDown(int button)
|
||||
{
|
||||
mouse_button[button] = true;
|
||||
// O2S: Add button to buffer
|
||||
button_buffer[button_write_ptr] = button;
|
||||
button_write_ptr = (button_write_ptr + 1) % BUTTON_BUFFER_SIZE;
|
||||
|
||||
// O2S: mouse_button[button] = true;
|
||||
SetInterruptFlag(INTFLAG_ADB);
|
||||
TriggerInterrupt();
|
||||
}
|
||||
@ -263,7 +272,11 @@ void ADBMouseDown(int button)
|
||||
|
||||
void ADBMouseUp(int button)
|
||||
{
|
||||
mouse_button[button] = false;
|
||||
// O2S: Add button to buffer
|
||||
button_buffer[button_write_ptr] = button | 0x80;
|
||||
button_write_ptr = (button_write_ptr + 1) % BUTTON_BUFFER_SIZE;
|
||||
|
||||
// O2S: mouse_button[button] = false;
|
||||
SetInterruptFlag(INTFLAG_ADB);
|
||||
TriggerInterrupt();
|
||||
}
|
||||
@ -278,7 +291,7 @@ void ADBSetRelMouseMode(bool relative)
|
||||
if (relative_mouse != relative) {
|
||||
relative_mouse = relative;
|
||||
mouse_x = mouse_y = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -340,41 +353,45 @@ void ADBInterrupt(void)
|
||||
int my = mouse_y;
|
||||
if (relative_mouse)
|
||||
mouse_x = mouse_y = 0;
|
||||
bool mb[3] = {mouse_button[0], mouse_button[1], mouse_button[2]};
|
||||
B2_unlock_mutex(mouse_lock);
|
||||
|
||||
uint32 key_base = adb_base + 4;
|
||||
uint32 mouse_base = adb_base + 16;
|
||||
|
||||
if (relative_mouse) {
|
||||
while (mx != 0 || my != 0 || button_read_ptr != button_write_ptr) {
|
||||
if (button_read_ptr != button_write_ptr) {
|
||||
// Read button event
|
||||
uint8 button = button_buffer[button_read_ptr];
|
||||
button_read_ptr = (button_read_ptr + 1) % BUTTON_BUFFER_SIZE;
|
||||
mouse_button[button & 0x3] = (button & 0x80) ? false : true;
|
||||
}
|
||||
// Call mouse ADB handler
|
||||
if (mouse_reg_3[1] == 4) {
|
||||
// Extended mouse protocol
|
||||
WriteMacInt8(tmp_data, 3);
|
||||
WriteMacInt8(tmp_data + 1, (my & 0x7f) | (mouse_button[0] ? 0 : 0x80));
|
||||
WriteMacInt8(tmp_data + 2, (mx & 0x7f) | (mouse_button[1] ? 0 : 0x80));
|
||||
WriteMacInt8(tmp_data + 3, ((my >> 3) & 0x70) | ((mx >> 7) & 0x07) | (mouse_button[2] ? 0x08 : 0x88));
|
||||
} else {
|
||||
// 100/200 dpi mode
|
||||
WriteMacInt8(tmp_data, 2);
|
||||
WriteMacInt8(tmp_data + 1, (my & 0x7f) | (mouse_button[0] ? 0 : 0x80));
|
||||
WriteMacInt8(tmp_data + 2, (mx & 0x7f) | (mouse_button[1] ? 0 : 0x80));
|
||||
}
|
||||
r.a[0] = tmp_data;
|
||||
r.a[1] = ReadMacInt32(mouse_base);
|
||||
r.a[2] = ReadMacInt32(mouse_base + 4);
|
||||
r.a[3] = adb_base;
|
||||
r.d[0] = (mouse_reg_3[0] << 4) | 0x0c; // Talk 0
|
||||
Execute68k(r.a[1], &r);
|
||||
|
||||
// Mouse movement (relative) and buttons
|
||||
if (mx != 0 || my != 0 || mb[0] != old_mouse_button[0] || mb[1] != old_mouse_button[1] || mb[2] != old_mouse_button[2]) {
|
||||
|
||||
// Call mouse ADB handler
|
||||
if (mouse_reg_3[1] == 4) {
|
||||
// Extended mouse protocol
|
||||
WriteMacInt8(tmp_data, 3);
|
||||
WriteMacInt8(tmp_data + 1, (my & 0x7f) | (mb[0] ? 0 : 0x80));
|
||||
WriteMacInt8(tmp_data + 2, (mx & 0x7f) | (mb[1] ? 0 : 0x80));
|
||||
WriteMacInt8(tmp_data + 3, ((my >> 3) & 0x70) | ((mx >> 7) & 0x07) | (mb[2] ? 0x08 : 0x88));
|
||||
} else {
|
||||
// 100/200 dpi mode
|
||||
WriteMacInt8(tmp_data, 2);
|
||||
WriteMacInt8(tmp_data + 1, (my & 0x7f) | (mb[0] ? 0 : 0x80));
|
||||
WriteMacInt8(tmp_data + 2, (mx & 0x7f) | (mb[1] ? 0 : 0x80));
|
||||
}
|
||||
r.a[0] = tmp_data;
|
||||
r.a[1] = ReadMacInt32(mouse_base);
|
||||
r.a[2] = ReadMacInt32(mouse_base + 4);
|
||||
r.a[3] = adb_base;
|
||||
r.d[0] = (mouse_reg_3[0] << 4) | 0x0c; // Talk 0
|
||||
Execute68k(r.a[1], &r);
|
||||
|
||||
old_mouse_button[0] = mb[0];
|
||||
old_mouse_button[1] = mb[1];
|
||||
old_mouse_button[2] = mb[2];
|
||||
}
|
||||
old_mouse_button[0] = mouse_button[0];
|
||||
old_mouse_button[1] = mouse_button[1];
|
||||
old_mouse_button[2] = mouse_button[2];
|
||||
mx = 0;
|
||||
my = 0;
|
||||
}
|
||||
|
||||
} else {
|
||||
|
||||
@ -405,34 +422,42 @@ void ADBInterrupt(void)
|
||||
old_mouse_y = my;
|
||||
}
|
||||
|
||||
// Send mouse button events
|
||||
if (mb[0] != old_mouse_button[0] || mb[1] != old_mouse_button[1] || mb[2] != old_mouse_button[2]) {
|
||||
uint32 mouse_base = adb_base + 16;
|
||||
// O2S: Process accumulated button events
|
||||
while (button_read_ptr != button_write_ptr) {
|
||||
// Read button event
|
||||
uint8 button = button_buffer[button_read_ptr];
|
||||
button_read_ptr = (button_read_ptr + 1) % BUTTON_BUFFER_SIZE;
|
||||
mouse_button[button & 0x3] = (button & 0x80) ? false : true;
|
||||
|
||||
// Call mouse ADB handler
|
||||
if (mouse_reg_3[1] == 4) {
|
||||
// Extended mouse protocol
|
||||
WriteMacInt8(tmp_data, 3);
|
||||
WriteMacInt8(tmp_data + 1, mb[0] ? 0 : 0x80);
|
||||
WriteMacInt8(tmp_data + 2, mb[1] ? 0 : 0x80);
|
||||
WriteMacInt8(tmp_data + 3, mb[2] ? 0x08 : 0x88);
|
||||
} else {
|
||||
// 100/200 dpi mode
|
||||
WriteMacInt8(tmp_data, 2);
|
||||
WriteMacInt8(tmp_data + 1, mb[0] ? 0 : 0x80);
|
||||
WriteMacInt8(tmp_data + 2, mb[1] ? 0 : 0x80);
|
||||
}
|
||||
r.a[0] = tmp_data;
|
||||
r.a[1] = ReadMacInt32(mouse_base);
|
||||
r.a[2] = ReadMacInt32(mouse_base + 4);
|
||||
r.a[3] = adb_base;
|
||||
r.d[0] = (mouse_reg_3[0] << 4) | 0x0c; // Talk 0
|
||||
Execute68k(r.a[1], &r);
|
||||
if (mouse_button[0] != old_mouse_button[0] || mouse_button[1] != old_mouse_button[1] || mouse_button[2] != old_mouse_button[2]) {
|
||||
uint32 mouse_base = adb_base + 16;
|
||||
|
||||
// Call mouse ADB handler
|
||||
if (mouse_reg_3[1] == 4) {
|
||||
// Extended mouse protocol
|
||||
WriteMacInt8(tmp_data, 3);
|
||||
WriteMacInt8(tmp_data + 1, mouse_button[0] ? 0 : 0x80);
|
||||
WriteMacInt8(tmp_data + 2, mouse_button[1] ? 0 : 0x80);
|
||||
WriteMacInt8(tmp_data + 3, mouse_button[2] ? 0x08 : 0x88);
|
||||
} else {
|
||||
// 100/200 dpi mode
|
||||
WriteMacInt8(tmp_data, 2);
|
||||
WriteMacInt8(tmp_data + 1, mouse_button[0] ? 0 : 0x80);
|
||||
WriteMacInt8(tmp_data + 2, mouse_button[1] ? 0 : 0x80);
|
||||
}
|
||||
r.a[0] = tmp_data;
|
||||
r.a[1] = ReadMacInt32(mouse_base);
|
||||
r.a[2] = ReadMacInt32(mouse_base + 4);
|
||||
r.a[3] = adb_base;
|
||||
r.d[0] = (mouse_reg_3[0] << 4) | 0x0c; // Talk 0
|
||||
Execute68k(r.a[1], &r);
|
||||
|
||||
old_mouse_button[0] = mouse_button[0];
|
||||
old_mouse_button[1] = mouse_button[1];
|
||||
old_mouse_button[2] = mouse_button[2];
|
||||
}
|
||||
}
|
||||
|
||||
old_mouse_button[0] = mb[0];
|
||||
old_mouse_button[1] = mb[1];
|
||||
old_mouse_button[2] = mb[2];
|
||||
}
|
||||
}
|
||||
|
||||
// Process accumulated keyboard events
|
||||
|
@ -31,6 +31,8 @@
|
||||
#include "main.h"
|
||||
#include "audio.h"
|
||||
#include "audio_defs.h"
|
||||
#include "user_strings.h"
|
||||
#include "cdrom.h"
|
||||
|
||||
#define DEBUG 0
|
||||
#include "debug.h"
|
||||
@ -51,6 +53,9 @@ static int open_count = 0; // Open/close nesting count
|
||||
|
||||
bool AudioAvailable = false; // Flag: audio output available (from the software point of view)
|
||||
|
||||
int SoundInSource = 2;
|
||||
int SoundInPlaythrough = 7;
|
||||
int SoundInGain = 65536; // FIXED 4-byte from 0.5 to 1.5; this is middle value (1) as int
|
||||
|
||||
/*
|
||||
* Reset audio emulation
|
||||
@ -406,8 +411,8 @@ adat_error: printf("FATAL: audio component data block initialization error\n");
|
||||
// Close Apple Mixer
|
||||
r.a[0] = AudioStatus.mixer;
|
||||
Execute68k(audio_data + adatCloseMixer, &r);
|
||||
D(bug(" CloseMixer() returns %08lx, mixer %08lx\n", r.d[0], AudioStatus.mixer));
|
||||
AudioStatus.mixer = 0;
|
||||
return r.d[0];
|
||||
}
|
||||
r.a[0] = audio_data;
|
||||
Execute68kTrap(0xa01f, &r); // DisposePtr()
|
||||
@ -533,7 +538,7 @@ delegate: // Delegate call to Apple Mixer
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// not currently using these functions
|
||||
/*
|
||||
* Sound input driver Open() routine
|
||||
*/
|
||||
@ -553,7 +558,20 @@ int16 SoundInPrime(uint32 pb, uint32 dce)
|
||||
{
|
||||
D(bug("SoundInPrime\n"));
|
||||
//!!
|
||||
return paramErr;
|
||||
|
||||
uint16 code = ReadMacInt16(pb + csCode);
|
||||
D(bug("SoundInControl %d\n", code));
|
||||
|
||||
if (code == 1) {
|
||||
D(bug(" SoundInKillIO\n"));
|
||||
//!!
|
||||
return noErr;
|
||||
}
|
||||
|
||||
if (code != 2)
|
||||
return -231; // siUnknownInfoType
|
||||
|
||||
return noErr;
|
||||
}
|
||||
|
||||
|
||||
@ -574,12 +592,39 @@ int16 SoundInControl(uint32 pb, uint32 dce)
|
||||
|
||||
if (code != 2)
|
||||
return -231; // siUnknownInfoType
|
||||
|
||||
uint32 *param = (uint32 *)Mac2HostAddr(pb + csParam);
|
||||
uint32 selector = param[0];
|
||||
D(bug(" selector %c%c%c%c\n", selector >> 24, selector >> 16, selector >> 8, selector));
|
||||
|
||||
uint32 selector = ReadMacInt32(pb + csParam); // 4-byte selector (should match via FOURCC above)
|
||||
|
||||
switch (selector) {
|
||||
case siInitializeDriver: {
|
||||
// If possible, the driver initializes the device to a sampling rate of 22 kHz, a sample size of 8 bits, mono recording, no compression, automatic gain control on, and all other features off.
|
||||
return noErr;
|
||||
}
|
||||
|
||||
case siCloseDriver: {
|
||||
// The sound input device driver should stop any recording in progress, deallocate the input hardware, and initialize local variables to default settings.
|
||||
return noErr;
|
||||
}
|
||||
|
||||
case siInputSource: {
|
||||
SoundInSource = ReadMacInt16(pb + csParam + 4);
|
||||
return noErr;
|
||||
}
|
||||
|
||||
case siPlayThruOnOff: {
|
||||
SoundInPlaythrough = ReadMacInt16(pb + csParam + 4);
|
||||
return noErr;
|
||||
}
|
||||
|
||||
case siOptionsDialog: {
|
||||
return noErr;
|
||||
}
|
||||
|
||||
case siInputGain: {
|
||||
SoundInGain = ReadMacInt32(pb + csParam + 4);
|
||||
return noErr;
|
||||
}
|
||||
|
||||
default:
|
||||
return -231; // siUnknownInfoType
|
||||
}
|
||||
@ -590,58 +635,187 @@ int16 SoundInControl(uint32 pb, uint32 dce)
|
||||
* Sound input driver Status() routine
|
||||
*/
|
||||
|
||||
int16 SoundInStatus(uint32 pb, uint32 dce)
|
||||
int16 SoundInStatus(uint32 pb, uint32 dce) // A0 points to Device Manager parameter block (pb) and A1 to device control entry (dce)
|
||||
{
|
||||
uint16 code = ReadMacInt16(pb + csCode);
|
||||
D(bug("SoundInStatus %d\n", code));
|
||||
if (code != 2)
|
||||
return -231; // siUnknownInfoType
|
||||
|
||||
// two choices on return
|
||||
// 1: if under 18 bytes, place # of bytes at (pb+csParam) and write from (pb+csParam+4) on
|
||||
// 2: if over 18 bytes, place 0 at (pb+csParam) and directly write into address pointed to by (pb+csParam+4)
|
||||
uint32 selector = ReadMacInt32(pb + csParam); // 4-byte selector (should match via FOURCC above)
|
||||
uint32 bufferptr = ReadMacInt32(pb + csParam + 4); // 4-byte address to the buffer in vm memory
|
||||
|
||||
uint32 *param = (uint32 *)Mac2HostAddr(pb + csParam);
|
||||
uint32 selector = param[0];
|
||||
D(bug(" selector %c%c%c%c\n", selector >> 24, selector >> 16, selector >> 8, selector));
|
||||
switch (selector) {
|
||||
#if 0
|
||||
case siDeviceName: {
|
||||
const char *str = GetString(STR_SOUND_IN_NAME);
|
||||
param[0] = 0;
|
||||
memcpy((void *)param[1], str, strlen(str));
|
||||
case siDeviceName: { // return name in STR255 format
|
||||
const uint8 str[] = { // size 9
|
||||
0x08, // 1-byte length
|
||||
0x42, 0x75, // Bu
|
||||
0x69, 0x6c, // il
|
||||
0x74, 0x2d, // t-
|
||||
0x69, 0x6e // in
|
||||
};
|
||||
// const uint8 str[] = { // size 12
|
||||
// 0x0b, // 1-byte length
|
||||
// 0x53, 0x68, // Sh
|
||||
// 0x65, 0x65, // ee
|
||||
// 0x70, 0x73, // ps
|
||||
// 0x68, 0x61, // ha
|
||||
// 0x76, 0x65, // ve
|
||||
// 0x72 // r
|
||||
// };
|
||||
WriteMacInt32(pb + csParam, 0); // response will be written directly into buffer
|
||||
Host2Mac_memcpy(bufferptr, str, sizeof(str));
|
||||
|
||||
return noErr;
|
||||
}
|
||||
|
||||
case siDeviceIcon: {
|
||||
// todo: add soundin ICN, borrow from CD ROM for now
|
||||
WriteMacInt32(pb + csParam, 0);
|
||||
|
||||
M68kRegisters r;
|
||||
static const uint8 proc[] = {
|
||||
0x55, 0x8f, // subq.l #2,sp
|
||||
0xa9, 0x94, // CurResFile
|
||||
0x42, 0x67, // clr.w -(sp)
|
||||
0xa9, 0x98, // UseResFile
|
||||
0x59, 0x8f, // subq.l #4,sp
|
||||
0x48, 0x79, 0x49, 0x43, 0x4e, 0x23, // move.l #'ICN#',-(sp)
|
||||
0x3f, 0x3c, 0xbf, 0x76, // move.w #-16522,-(sp)
|
||||
0xa9, 0xa0, // GetResource
|
||||
0x24, 0x5f, // move.l (sp)+,a2
|
||||
0xa9, 0x98, // UseResFile
|
||||
0x20, 0x0a, // move.l a2,d0
|
||||
0x66, 0x04, // bne 1
|
||||
0x70, 0x00, // moveq #0,d0
|
||||
M68K_RTS >> 8, M68K_RTS & 0xff,
|
||||
0x2f, 0x0a, //1 move.l a2,-(sp)
|
||||
0xa9, 0x92, // DetachResource
|
||||
0x20, 0x4a, // move.l a2,a0
|
||||
0xa0, 0x4a, // HNoPurge
|
||||
0x70, 0x01, // moveq #1,d0
|
||||
M68K_RTS >> 8, M68K_RTS & 0xff
|
||||
};
|
||||
Execute68k(Host2MacAddr((uint8 *)proc), &r);
|
||||
if (r.d[0]) {
|
||||
param[0] = 4; // Length of returned data
|
||||
param[1] = r.a[2]; // Handle to icon suite
|
||||
return noErr;
|
||||
} else
|
||||
return -192; // resNotFound
|
||||
r.d[0] = sizeof(CDROMIcon);
|
||||
Execute68kTrap(0xa122, &r); // NewHandle()
|
||||
uint32 h = r.a[0];
|
||||
if (h == 0)
|
||||
return memFullErr;
|
||||
WriteMacInt32(bufferptr, h);
|
||||
uint32 sp = ReadMacInt32(h);
|
||||
Host2Mac_memcpy(sp, CDROMIcon, sizeof(CDROMIcon));
|
||||
|
||||
return noErr;
|
||||
|
||||
// 68k code causes crash in sheep and link error in basilisk
|
||||
// M68kRegisters r;
|
||||
// static const uint8 proc[] = {
|
||||
// 0x55, 0x8f, // subq.l #2,sp
|
||||
// 0xa9, 0x94, // CurResFile
|
||||
// 0x42, 0x67, // clr.w -(sp)
|
||||
// 0xa9, 0x98, // UseResFile
|
||||
// 0x59, 0x8f, // subq.l #4,sp
|
||||
// 0x48, 0x79, 0x49, 0x43, 0x4e, 0x23, // move.l #'ICN#',-(sp)
|
||||
// 0x3f, 0x3c, 0xbf, 0x76, // move.w #-16522,-(sp)
|
||||
// 0xa9, 0xa0, // GetResource
|
||||
// 0x24, 0x5f, // move.l (sp)+,a2
|
||||
// 0xa9, 0x98, // UseResFile
|
||||
// 0x20, 0x0a, // move.l a2,d0
|
||||
// 0x66, 0x04, // bne 1
|
||||
// 0x70, 0x00, // moveq #0,d0
|
||||
// M68K_RTS >> 8, M68K_RTS & 0xff,
|
||||
// 0x2f, 0x0a, //1 move.l a2,-(sp)
|
||||
// 0xa9, 0x92, // DetachResource
|
||||
// 0x20, 0x4a, // move.l a2,a0
|
||||
// 0xa0, 0x4a, // HNoPurge
|
||||
// 0x70, 0x01, // moveq #1,d0
|
||||
// M68K_RTS >> 8, M68K_RTS & 0xff
|
||||
// };
|
||||
// Execute68k(Host2MacAddr((uint8 *)proc), &r);
|
||||
// if (r.d[0]) {
|
||||
// WriteMacInt32(pb + csParam, 4); // Length of returned data
|
||||
// WriteMacInt32(pb + csParam + 4, r.a[2]); // Handle to icon suite
|
||||
// return noErr;
|
||||
// } else
|
||||
// return -192; // resNotFound
|
||||
}
|
||||
#endif
|
||||
|
||||
case siInputSource: {
|
||||
// return -231 if only 1 or index of current source if more
|
||||
|
||||
WriteMacInt32(pb + csParam, 2);
|
||||
WriteMacInt16(pb + csParam + 4, SoundInSource); // index of selected source
|
||||
return noErr;
|
||||
}
|
||||
|
||||
case siInputSourceNames: {
|
||||
// return -231 if only 1 or handle to STR# resource if more
|
||||
|
||||
const uint8 str[] = {
|
||||
0x00, 0x02, // 2-byte count of #strings
|
||||
// byte size indicator (up to 255 length supported)
|
||||
0x0a, // size is 10
|
||||
0x4d, 0x69, // Mi
|
||||
0x63, 0x72, // cr
|
||||
0x6f, 0x70, // op
|
||||
0x68, 0x6f, // ho
|
||||
0x6e, 0x65, // ne
|
||||
0x0b, // size is 11
|
||||
0x49, 0x6e, // start of string in ASCII, In
|
||||
0x74, 0x65, // te
|
||||
0x72, 0x6e, // rn
|
||||
0x61, 0x6c, // al
|
||||
0x20, 0x43, // C
|
||||
0x44, // D
|
||||
};
|
||||
|
||||
WriteMacInt32(pb + csParam, 0);
|
||||
|
||||
M68kRegisters r;
|
||||
r.d[0] = sizeof(str);
|
||||
Execute68kTrap(0xa122, &r); // NewHandle()
|
||||
uint32 h = r.a[0];
|
||||
if (h == 0)
|
||||
return memFullErr;
|
||||
WriteMacInt32(bufferptr, h);
|
||||
uint32 sp = ReadMacInt32(h);
|
||||
Host2Mac_memcpy(sp, str, sizeof(str));
|
||||
|
||||
return noErr;
|
||||
}
|
||||
|
||||
case siOptionsDialog: {
|
||||
// 0 if no options box supported and 1 if so
|
||||
WriteMacInt32(pb + csParam, 2); // response not in buffer, need to copy integer
|
||||
WriteMacInt16(pb + csParam + 4, 1); // Integer data type
|
||||
return noErr;
|
||||
}
|
||||
|
||||
case siPlayThruOnOff: {
|
||||
// playthrough volume, 0 is off and 7 is max
|
||||
WriteMacInt32(pb + csParam, 2);
|
||||
WriteMacInt16(pb + csParam + 4, SoundInPlaythrough);
|
||||
return noErr;
|
||||
}
|
||||
|
||||
case siNumberChannels: {
|
||||
// 1 is mono and 2 is stereo
|
||||
WriteMacInt32(pb + csParam, 2);
|
||||
WriteMacInt16(pb + csParam + 4, 2);
|
||||
return noErr;
|
||||
}
|
||||
|
||||
case siSampleRate: {
|
||||
WriteMacInt32(pb + csParam, 0);
|
||||
WriteMacInt32(bufferptr, 0xac440000); // 44100.00000 Hz, of Fixed data type
|
||||
return noErr;
|
||||
}
|
||||
|
||||
case siSampleRateAvailable: {
|
||||
WriteMacInt32(pb + csParam, 0);
|
||||
|
||||
M68kRegisters r;
|
||||
r.d[0] = 4;
|
||||
Execute68kTrap(0xa122, &r); // NewHandle()
|
||||
uint32 h = r.a[0];
|
||||
if (h == 0)
|
||||
return memFullErr;
|
||||
WriteMacInt16(bufferptr, 1); // 1 sample rate available
|
||||
WriteMacInt32(bufferptr + 2, h); // handle to sample rate list
|
||||
uint32 sp = ReadMacInt32(h);
|
||||
WriteMacInt32(sp, 0xac440000); // 44100.00000 Hz, of Fixed data type
|
||||
|
||||
return noErr;
|
||||
}
|
||||
|
||||
case siInputGain: {
|
||||
WriteMacInt32(pb + csParam, 4);
|
||||
WriteMacInt32(pb + csParam + 4, SoundInGain);
|
||||
return noErr;
|
||||
}
|
||||
|
||||
|
||||
default:
|
||||
return -231; // siUnknownInfoType
|
||||
}
|
||||
|
1246
BasiliskII/src/bincue.cpp
Normal file
1246
BasiliskII/src/bincue.cpp
Normal file
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@ -49,6 +49,9 @@
|
||||
#define DEBUG 0
|
||||
#include "debug.h"
|
||||
|
||||
extern bool tick_inhibit;
|
||||
|
||||
void PlayStartupSound();
|
||||
|
||||
/*
|
||||
* Execute EMUL_OP opcode (called by 68k emulator or Illegal Instruction trap handler)
|
||||
@ -83,10 +86,14 @@ void EmulOp(uint16 opcode, M68kRegisters *r)
|
||||
|
||||
case M68K_EMUL_OP_RESET: { // MacOS reset
|
||||
D(bug("*** RESET ***\n"));
|
||||
tick_inhibit = true;
|
||||
CDROMRemount(); // for System 7.x
|
||||
TimerReset();
|
||||
EtherReset();
|
||||
AudioReset();
|
||||
|
||||
#ifdef USE_SDL_AUDIO
|
||||
PlayStartupSound();
|
||||
#endif
|
||||
// Create BootGlobs at top of memory
|
||||
Mac_memset(RAMBaseMac + RAMSize - 4096, 0, 4096);
|
||||
uint32 boot_globs = RAMBaseMac + RAMSize - 0x1c;
|
||||
@ -107,6 +114,7 @@ void EmulOp(uint16 opcode, M68kRegisters *r)
|
||||
r->a[1] = ROMBaseMac + UniversalInfo; // UniversalInfo
|
||||
r->a[6] = boot_globs; // BootGlobs
|
||||
r->a[7] = RAMBaseMac + 0x10000; // Boot stack
|
||||
tick_inhibit = false;
|
||||
break;
|
||||
}
|
||||
|
||||
@ -114,7 +122,7 @@ void EmulOp(uint16 opcode, M68kRegisters *r)
|
||||
bool is_read = (r->d[1] & 0x80) != 0;
|
||||
if ((r->d[1] & 0x78) == 0x38) {
|
||||
// XPRAM
|
||||
uint8 reg = (r->d[1] << 5) & 0xe0 | (r->d[1] >> 10) & 0x1f;
|
||||
uint8 reg = ((r->d[1] << 5) & 0xe0) | ((r->d[1] >> 10) & 0x1f);
|
||||
if (is_read) {
|
||||
r->d[2] = XPRAM[reg];
|
||||
bool localtalk = !(XPRAM[0xe0] || XPRAM[0xe1]); // LocalTalk enabled?
|
||||
@ -453,7 +461,9 @@ void EmulOp(uint16 opcode, M68kRegisters *r)
|
||||
if (HasMacStarted()) {
|
||||
|
||||
// Mac has started, execute all 60Hz interrupt functions
|
||||
#if !PRECISE_TIMING
|
||||
TimerInterrupt();
|
||||
#endif
|
||||
VideoInterrupt();
|
||||
|
||||
// Call DoVBLTask(0)
|
||||
@ -485,7 +495,12 @@ void EmulOp(uint16 opcode, M68kRegisters *r)
|
||||
ClearInterruptFlag(INTFLAG_ETHER);
|
||||
EtherInterrupt();
|
||||
}
|
||||
|
||||
#if PRECISE_TIMING
|
||||
if (InterruptFlags & INTFLAG_TIMER) {
|
||||
ClearInterruptFlag(INTFLAG_TIMER);
|
||||
TimerInterrupt();
|
||||
}
|
||||
#endif
|
||||
if (InterruptFlags & INTFLAG_AUDIO) {
|
||||
ClearInterruptFlag(INTFLAG_AUDIO);
|
||||
AudioInterrupt();
|
||||
|
@ -186,9 +186,13 @@ void EtherExit(void)
|
||||
* Reset
|
||||
*/
|
||||
|
||||
|
||||
void EtherResetCachedAllocation();
|
||||
|
||||
void EtherReset(void)
|
||||
{
|
||||
udp_protocols.clear();
|
||||
EtherResetCachedAllocation();
|
||||
ether_reset();
|
||||
}
|
||||
|
||||
@ -457,6 +461,10 @@ void ether_udp_read(uint32 packet, int length, struct sockaddr_in *from)
|
||||
static uint32 ether_packet = 0; // Ethernet packet (cached allocation)
|
||||
static uint32 n_ether_packets = 0; // Number of ethernet packets allocated so far (should be at most 1)
|
||||
|
||||
void EtherResetCachedAllocation() {
|
||||
ether_packet = 0;
|
||||
}
|
||||
|
||||
EthernetPacket::EthernetPacket()
|
||||
{
|
||||
++n_ether_packets;
|
||||
@ -485,4 +493,6 @@ EthernetPacket::~EthernetPacket()
|
||||
bug("WARNING: Nested allocation of ethernet packets!\n");
|
||||
}
|
||||
}
|
||||
#else
|
||||
void EtherResetCachedAllocation() { }
|
||||
#endif
|
||||
|
@ -72,14 +72,21 @@ const uint32 siHardwareMute = FOURCC('h','m','u','t'); // mute state of all ha
|
||||
const uint32 siHardwareVolume = FOURCC('h','v','o','l'); // volume level of all hardware
|
||||
const uint32 siHardwareVolumeSteps = FOURCC('h','s','t','p'); // number of volume steps for hardware
|
||||
const uint32 siHardwareBusy = FOURCC('h','w','b','s'); // sound hardware is in use
|
||||
const uint32 siHardwareFormat = FOURCC('h','w','f','m'); // hardware format
|
||||
const uint32 siHeadphoneMute = FOURCC('p','m','u','t'); // mute state of headphone
|
||||
const uint32 siHeadphoneVolume = FOURCC('p','v','o','l'); // volume level of headphone
|
||||
const uint32 siHeadphoneVolumeSteps = FOURCC('h','d','s','t'); // number of volume steps for headphone
|
||||
const uint32 siSpeakerMute = FOURCC('s','m','u','t'); // mute state of all built-in speakers
|
||||
const uint32 siSpeakerVolume = FOURCC('s','v','o','l'); // volume level of built-in speaker
|
||||
const uint32 siDeviceName = FOURCC('n','a','m','e');
|
||||
const uint32 siDeviceIcon = FOURCC('i','c','o','n');
|
||||
const uint32 siHardwareFormat = FOURCC('h','w','f','m');
|
||||
const uint32 siDeviceName = FOURCC('n','a','m','e'); // sound input name
|
||||
const uint32 siDeviceIcon = FOURCC('i','c','o','n'); // sound input icon resource location
|
||||
const uint32 siInputSourceNames = FOURCC('s','n','a','m'); // sound input source names
|
||||
const uint32 siInputSource = FOURCC('s','o','u','r'); // sound input source selector
|
||||
const uint32 siInputGain = FOURCC('g','a','i','n'); // sound input gain
|
||||
const uint32 siOptionsDialog = FOURCC('o','p','t','d'); // display options dialog box
|
||||
const uint32 siPlayThruOnOff = FOURCC('p','l','t','h'); // play-through state
|
||||
const uint32 siInitializeDriver = FOURCC('i','n','i','t'); // open sound input device
|
||||
const uint32 siCloseDriver = FOURCC('c','l','o','s'); // close sound input device
|
||||
|
||||
enum { // ComponentResource struct
|
||||
componentType = 0,
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* bincue_unix.h -- support for cdrom image files in bin/cue format
|
||||
* bincue.h -- support for cdrom image files in bin/cue format
|
||||
*
|
||||
* (C) 2010 Geoffrey Brown
|
||||
*
|
||||
@ -21,6 +21,9 @@
|
||||
#ifndef BINCUE_H
|
||||
#define BINCUE_H
|
||||
|
||||
extern void InitBinCue();
|
||||
extern void ExitBinCue();
|
||||
|
||||
extern void *open_bincue(const char *name);
|
||||
extern bool readtoc_bincue(void *, uint8 *);
|
||||
extern size_t read_bincue(void *, void *, loff_t, size_t);
|
||||
@ -34,10 +37,15 @@ extern bool CDPlay_bincue(void *, uint8, uint8,
|
||||
extern bool CDPause_bincue(void *);
|
||||
extern bool CDResume_bincue(void *);
|
||||
extern bool CDStop_bincue(void *);
|
||||
extern bool CDScan_bincue(void *, uint8, uint8, uint8, bool);
|
||||
extern void CDSetVol_bincue(void *, uint8, uint8);
|
||||
extern void CDGetVol_bincue(void *, uint8 *, uint8 *);
|
||||
|
||||
#ifdef USE_SDL_AUDIO
|
||||
extern void OpenAudio_bincue(int, int, int, uint8);
|
||||
extern void OpenAudio_bincue(int, int, int, uint8, int);
|
||||
extern bool HaveAudioToMix_bincue(void);
|
||||
extern void MixAudio_bincue(uint8 *, int);
|
||||
extern void CloseAudio_bincue(void);
|
||||
#endif
|
||||
|
||||
#endif
|
@ -40,4 +40,9 @@ extern int16 CDROMPrime(uint32 pb, uint32 dce);
|
||||
extern int16 CDROMControl(uint32 pb, uint32 dce);
|
||||
extern int16 CDROMStatus(uint32 pb, uint32 dce);
|
||||
|
||||
extern void CDROMOpenDone(void); // Called by CDROMOpen() once drives have been to the drive queue
|
||||
|
||||
void CDROMDrop(const char *path);
|
||||
void CDROMRemount();
|
||||
|
||||
#endif
|
||||
|
59
BasiliskII/src/include/color_scheme.h
Normal file
59
BasiliskII/src/include/color_scheme.h
Normal file
@ -0,0 +1,59 @@
|
||||
/* color_scheme.h - Change application theme based on D-Bus
|
||||
*
|
||||
* Copyright (C) 2022-2024 Rob Hall
|
||||
*
|
||||
* This program 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 Foundation, either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program 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 this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*
|
||||
* SPDX-License-Identifier: GPL-2.0-or-later
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <gtk/gtk.h>
|
||||
|
||||
G_BEGIN_DECLS
|
||||
|
||||
/*
|
||||
* An enum representing the color state requested by
|
||||
* the application. Before the color-scheme library is
|
||||
* set up, the application is effectively in the
|
||||
* APP_FORCES_LIGHT state.
|
||||
*/
|
||||
typedef enum {
|
||||
APP_PREFERS_LIGHT,
|
||||
APP_PREFERS_DARK,
|
||||
APP_FORCES_LIGHT,
|
||||
APP_FORCES_DARK
|
||||
} AppColorScheme;
|
||||
|
||||
/*
|
||||
* An enum representing the color state given by the
|
||||
* desktop portal. If the portal is not available, it
|
||||
* defaults to DESKTOP_NO_PREFERENCE.
|
||||
*/
|
||||
typedef enum {
|
||||
DESKTOP_NO_PREFERENCE,
|
||||
DESKTOP_PREFERS_DARK,
|
||||
DESKTOP_PREFERS_LIGHT
|
||||
} DesktopColorScheme;
|
||||
|
||||
gboolean color_scheme_set (AppColorScheme scheme);
|
||||
void color_scheme_set_async (AppColorScheme scheme);
|
||||
gboolean color_scheme_is_dark_theme (void);
|
||||
gboolean color_scheme_toggle (void);
|
||||
AppColorScheme color_scheme_get_app_scheme (void);
|
||||
DesktopColorScheme color_scheme_get_desktop_scheme (void);
|
||||
void color_scheme_disconnect (void);
|
||||
|
||||
G_END_DECLS
|
7
BasiliskII/src/include/g_resource.h
Normal file
7
BasiliskII/src/include/g_resource.h
Normal file
@ -0,0 +1,7 @@
|
||||
#ifndef __RESOURCE_basiliskii_H__
|
||||
#define __RESOURCE_basiliskii_H__
|
||||
|
||||
#include <gio/gio.h>
|
||||
|
||||
extern GResource *basiliskii_get_resource (void);
|
||||
#endif
|
@ -34,8 +34,15 @@ extern bool TwentyFourBitAddressing;
|
||||
// 68k register structure (for Execute68k())
|
||||
struct M68kRegisters {
|
||||
uint32 d[8];
|
||||
#ifdef UPDATE_UAE
|
||||
memptr a[8];
|
||||
uint16 sr;
|
||||
memptr usp, isp, msp;
|
||||
memptr pc;
|
||||
#else
|
||||
uint32 a[8];
|
||||
uint16 sr;
|
||||
#endif
|
||||
};
|
||||
|
||||
// General functions
|
||||
@ -74,6 +81,9 @@ extern uint32 InterruptFlags; // Currently pending interrupts
|
||||
extern void SetInterruptFlag(uint32 flag); // Set/clear interrupt flags
|
||||
extern void ClearInterruptFlag(uint32 flag);
|
||||
|
||||
// vde switch variable
|
||||
extern char* vde_sock;
|
||||
|
||||
// Array length
|
||||
#if __cplusplus >= 201103L || (_MSC_VER >= 1900 && defined __cplusplus)
|
||||
template <typename T, size_t size>
|
||||
|
@ -48,6 +48,7 @@ extern void PrefsReplaceBool(const char *name, bool b);
|
||||
extern void PrefsReplaceInt32(const char *name, int32 val);
|
||||
|
||||
extern const char *PrefsFindString(const char *name, int index = 0);
|
||||
extern "C" const char *PrefsFindStringC(const char *name, int index = 0);
|
||||
extern bool PrefsFindBool(const char *name);
|
||||
extern int32 PrefsFindInt32(const char *name);
|
||||
|
||||
|
@ -21,6 +21,27 @@
|
||||
#ifndef PREFS_EDITOR_H
|
||||
#define PREFS_EDITOR_H
|
||||
|
||||
#ifdef __BEOS__
|
||||
extern void PrefsEditor(uint32 msg);
|
||||
#else
|
||||
extern bool PrefsEditor(void);
|
||||
|
||||
#endif
|
||||
|
||||
#if defined(ENABLE_GTK) || defined(STANDALONE_GUI)
|
||||
|
||||
#include <gtk/gtk.h>
|
||||
|
||||
#if !GLIB_CHECK_VERSION(2, 24, 0)
|
||||
#define GVariant void
|
||||
#endif
|
||||
#if !GLIB_CHECK_VERSION(2, 28, 0)
|
||||
#define GSimpleAction void
|
||||
#endif
|
||||
|
||||
extern "C" {
|
||||
void dl_quit(GtkWidget *dialog);
|
||||
void cb_swap_opt_cmd (GtkWidget *widget);
|
||||
void cb_infobar_show (GtkWidget *widget);
|
||||
}
|
||||
#endif
|
||||
#endif
|
||||
|
@ -50,7 +50,7 @@ extern void SysAddSerialPrefs(void);
|
||||
* that is freed by Sys_close().
|
||||
*/
|
||||
|
||||
extern void *Sys_open(const char *name, bool read_only);
|
||||
extern void *Sys_open(const char *name, bool read_only, bool is_cdrom = false);
|
||||
extern void Sys_close(void *fh);
|
||||
extern size_t Sys_read(void *fh, void *buffer, loff_t offset, size_t length);
|
||||
extern size_t Sys_write(void *fh, void *buffer, loff_t offset, size_t length);
|
||||
|
@ -39,6 +39,12 @@ enum {
|
||||
STR_START_BUTTON,
|
||||
STR_QUIT_BUTTON,
|
||||
STR_CANCEL_BUTTON,
|
||||
STR_CONTINUE_BUTTON,
|
||||
STR_SELECT_BUTTON,
|
||||
STR_CREATE_BUTTON,
|
||||
STR_APP_NAME,
|
||||
STR_APP_DISPLAY_NAME,
|
||||
STR_APP_ID,
|
||||
|
||||
// Error messages
|
||||
STR_NO_MEM_ERR = 1000,
|
||||
@ -99,6 +105,9 @@ enum {
|
||||
STR_VOL_SIZE_CTRL,
|
||||
STR_VOL_BLOCKSIZE_CTRL,
|
||||
STR_VOL_FILE_CTRL,
|
||||
STR_VOL_HEADING_LOCATION,
|
||||
STR_VOL_HEADING_CDROM,
|
||||
STR_VOL_HEADING_SIZE,
|
||||
|
||||
STR_SCSI_PANE_TITLE = 3300, // SCSI pane
|
||||
STR_SCSI_ID_0 = 3301,
|
||||
@ -162,6 +171,16 @@ enum {
|
||||
STR_24_BIT_1600x1200_LAB,
|
||||
STR_SOUND_CTRL,
|
||||
STR_NOSOUND_CTRL,
|
||||
STR_GRAPHICS_SDL_RENDER_DRIVER_CTRL,
|
||||
STR_SOFTWARE_LAB,
|
||||
STR_OPENGL_LAB,
|
||||
STR_DIRECT3D_LAB,
|
||||
STR_GRAPHICS_SDL_VSYNC_CTRL,
|
||||
STR_DEFAULT_LAB,
|
||||
STR_SDL_SCALING,
|
||||
STR_SCALE_FACTOR,
|
||||
STR_SCALE_NEAREST,
|
||||
STR_SCALE_INTEGER,
|
||||
|
||||
STR_SERIAL_NETWORK_PANE_TITLE = 3500, // Serial/Networking pane
|
||||
STR_SERIALA_CTRL,
|
||||
@ -212,19 +231,20 @@ enum {
|
||||
|
||||
// Mac window
|
||||
STR_WINDOW_TITLE = 4000,
|
||||
STR_WINDOW_TITLE_FROZEN,
|
||||
STR_WINDOW_TITLE_GRABBED,
|
||||
STR_WINDOW_TITLE_GRABBED0,
|
||||
STR_WINDOW_TITLE_GRABBED_PRE,
|
||||
STR_WINDOW_TITLE_GRABBED1,
|
||||
STR_WINDOW_TITLE_GRABBED2,
|
||||
STR_WINDOW_TITLE_GRABBED3,
|
||||
STR_WINDOW_TITLE_GRABBED4,
|
||||
STR_WINDOW_TITLE_GRABBED_POST,
|
||||
STR_WINDOW_MENU = 4050,
|
||||
STR_WINDOW_ITEM_ABOUT,
|
||||
STR_WINDOW_ITEM_REFRESH,
|
||||
STR_WINDOW_ITEM_MOUNT,
|
||||
STR_SUSPEND_WINDOW_TITLE,
|
||||
|
||||
// Audio
|
||||
STR_SOUND_IN_NAME = 6000,
|
||||
|
||||
// External file system
|
||||
STR_EXTFS_NAME = 5000,
|
||||
STR_EXTFS_VOLUME_NAME
|
||||
|
@ -79,13 +79,13 @@ inline video_depth DepthModeForPixelDepth(int depth)
|
||||
// Returns the name of a video_depth, or an empty string if the depth is unknown
|
||||
const char * NameOfDepth(video_depth depth);
|
||||
|
||||
// Return a bytes-per-row value (assuming no padding) for the specified depth and pixel width
|
||||
// Return a bytes-per-row value (assuming enough bytes to fit the bits but no further padding) for the specified depth and pixel width
|
||||
inline uint32 TrivialBytesPerRow(uint32 width, video_depth depth)
|
||||
{
|
||||
switch (depth) {
|
||||
case VDEPTH_1BIT: return width / 8;
|
||||
case VDEPTH_2BIT: return width / 4;
|
||||
case VDEPTH_4BIT: return width / 2;
|
||||
case VDEPTH_1BIT: return (width + 7) / 8;
|
||||
case VDEPTH_2BIT: return (width + 3) / 4;
|
||||
case VDEPTH_4BIT: return (width + 1) / 2;
|
||||
case VDEPTH_8BIT: return width;
|
||||
case VDEPTH_16BIT: return width * 2;
|
||||
case VDEPTH_32BIT: return width * 4;
|
||||
@ -205,8 +205,8 @@ private:
|
||||
// Set palette to 50% gray
|
||||
void set_gray_palette(void);
|
||||
|
||||
// Load gamma-corrected black-to-white ramp to palette for direct-color mode
|
||||
void load_ramp_palette(void);
|
||||
// Load gamma-corrected black-to-white ramp
|
||||
void load_gamma_ramp(void);
|
||||
|
||||
// Allocate gamma table of specified size
|
||||
bool allocate_gamma_table(int size);
|
||||
@ -250,8 +250,10 @@ public:
|
||||
virtual void switch_to_current_mode(void) = 0;
|
||||
|
||||
// Called by the video driver to set the color palette (in indexed modes)
|
||||
// or the gamma table (in direct modes)
|
||||
virtual void set_palette(uint8 *pal, int num) = 0;
|
||||
|
||||
// Called by the video driver to set the gamma table
|
||||
virtual void set_gamma(uint8 *gamma, int num) = 0;
|
||||
};
|
||||
|
||||
// Vector of pointers to available monitor descriptions, filled by VideoInit()
|
||||
|
@ -133,6 +133,13 @@ uint32 TimeToMacTime(time_t t)
|
||||
// This code is taken from glibc 2.2
|
||||
|
||||
// Convert to number of seconds elapsed since 1-Jan-1904
|
||||
|
||||
#ifdef WIN32
|
||||
if (t == -1) {
|
||||
// failsafe as this will segfault
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
struct tm *local = localtime(&t);
|
||||
const int TM_EPOCH_YEAR = 1900;
|
||||
const int MAC_EPOCH_YEAR = 1904;
|
||||
@ -152,12 +159,83 @@ uint32 TimeToMacTime(time_t t)
|
||||
return local->tm_sec + 60 * (local->tm_min + 60 * (local->tm_hour + 24 * (days - dayofs)));
|
||||
}
|
||||
|
||||
#ifdef WIN32
|
||||
// mktime() here can't produce negative values so we have to start later
|
||||
#define MKTIME_START_LATER 1
|
||||
#else
|
||||
#define MKTIME_START_LATER 0
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Convert MacOS time to time_t (seconds since 1.1.1970)
|
||||
*/
|
||||
|
||||
time_t MacTimeToTime(uint32 t)
|
||||
{
|
||||
// simply subtract number of seconds between 1.1.1904 and 1.1.1970
|
||||
return t - 2082826800;
|
||||
time_t out;
|
||||
|
||||
// Find the time_t time of our local time starting point 1904-Jan-1 0:00 local time
|
||||
struct tm local;
|
||||
#if MKTIME_START_LATER
|
||||
// If we need to start later for mktime(),
|
||||
// first find 1971-Jan-1 0:00 local time
|
||||
local.tm_year = 71;
|
||||
#else
|
||||
local.tm_year = 4;
|
||||
#endif
|
||||
local.tm_mon = 0;
|
||||
local.tm_mday = 1;
|
||||
local.tm_hour = 0;
|
||||
local.tm_min = 0;
|
||||
local.tm_sec = 0;
|
||||
local.tm_isdst = -1;
|
||||
out = mktime(&local);
|
||||
if (out == -1) {
|
||||
D(bug("MacTimeToTime: mktime() can't convert local time starting point\n"));
|
||||
return -1;
|
||||
}
|
||||
|
||||
#if MKTIME_START_LATER
|
||||
// Then, if necessary, subtract from 1971 to go back to 1904
|
||||
out -= 2114380800; // Seconds between 1904 and 1971
|
||||
#endif
|
||||
|
||||
// Now we want the time t seconds after the starting point
|
||||
out += (time_t) t;
|
||||
|
||||
// Apply offset prefs
|
||||
int32 yearofs = PrefsFindInt32("yearofs");
|
||||
int32 dayofs = PrefsFindInt32("dayofs");
|
||||
if (dayofs != 0 || yearofs != 0) {
|
||||
#ifdef WIN32
|
||||
struct tm *out_tm = localtime(&out);
|
||||
#else
|
||||
struct tm result;
|
||||
localtime_r(&out, &result);
|
||||
struct tm *out_tm = &result;
|
||||
#endif
|
||||
if (out_tm) {
|
||||
out_tm->tm_year -= yearofs;
|
||||
out_tm->tm_mday -= dayofs;
|
||||
time_t offset_adjusted = mktime(out_tm);
|
||||
if (offset_adjusted != -1) {
|
||||
out = offset_adjusted;
|
||||
}
|
||||
} else {
|
||||
D(bug("MacTimeToTime: error applying offsets\n"));
|
||||
}
|
||||
}
|
||||
|
||||
#if DEBUG
|
||||
uint32 round_trip_val = TimeToMacTime(out);
|
||||
D(bug("MacTimeToTime: round trip %u -> %ld -> %u\n", t, out, round_trip_val));
|
||||
|
||||
struct tm * show = localtime(&out);
|
||||
D(bug(" %s", asctime(show)));
|
||||
if (t != round_trip_val) {
|
||||
D(bug("MacTimeToTime: Round-Trip Value Disagrees\n"));
|
||||
}
|
||||
#endif
|
||||
|
||||
return out;
|
||||
}
|
||||
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
x
Reference in New Issue
Block a user