Compare commits
1327 Commits
Author | SHA1 | Date |
---|---|---|
![]() |
7b5c19ff5e | |
![]() |
709237c79c | |
![]() |
b753f6eefa | |
![]() |
aaa6c15475 | |
![]() |
dccefede9b | |
![]() |
17652d9348 | |
![]() |
d9d4ea0ad4 | |
![]() |
d67ac42bbc | |
![]() |
60e07663d1 | |
![]() |
4c8740f309 | |
![]() |
acaeed8322 | |
![]() |
37e02b5a69 | |
![]() |
d4f3187ee0 | |
![]() |
122409e6f8 | |
![]() |
34e4439729 | |
![]() |
9b0c8c18de | |
![]() |
108478aaab | |
![]() |
175d578c07 | |
![]() |
0852d72dc9 | |
![]() |
e4b4b08c46 | |
![]() |
0197b406b8 | |
![]() |
727917773e | |
![]() |
d4b5cf6659 | |
![]() |
56a82682d5 | |
![]() |
0933f1ae66 | |
![]() |
6dfef64461 | |
![]() |
27b109b483 | |
![]() |
abb92327c0 | |
![]() |
682cdb0e28 | |
![]() |
146bec13ee | |
![]() |
13cf6aaacd | |
![]() |
f744e34687 | |
![]() |
ac64828880 | |
![]() |
f6b1d674db | |
![]() |
6fe0e61332 | |
![]() |
991a6b2447 | |
![]() |
ce37689720 | |
![]() |
18c1b44419 | |
![]() |
09679fb228 | |
![]() |
41fa2922f9 | |
![]() |
e787941351 | |
![]() |
f2164a9637 | |
![]() |
173a87f41b | |
![]() |
5e6ef2eaf7 | |
![]() |
51b8b06e91 | |
![]() |
f77ddc6fee | |
![]() |
6b982c8325 | |
![]() |
c9311529cb | |
![]() |
594380b2f9 | |
![]() |
c003a21362 | |
![]() |
ec8a8df269 | |
![]() |
3faee00fa7 | |
![]() |
02e0ff625b | |
![]() |
dded9debdb | |
![]() |
5d034cec3c | |
![]() |
d55b1aec0d | |
![]() |
01f8382c81 | |
![]() |
d7e9b98951 | |
![]() |
5ef3ebc287 | |
![]() |
14eb4226a5 | |
![]() |
56c18f57f9 | |
![]() |
d91cdcb1ec | |
![]() |
29a3f90648 | |
![]() |
323b6c9721 | |
![]() |
d577e0feeb | |
![]() |
3f70246896 | |
![]() |
0cb4de07f3 | |
![]() |
1c604d6dc2 | |
![]() |
357527370e | |
![]() |
7f3a4d34bb | |
![]() |
d4fd9292e1 | |
![]() |
bdaf399df1 | |
![]() |
78c77d0a9a | |
![]() |
18eeef3be6 | |
![]() |
03a9e858cd | |
![]() |
63bcb3e22f | |
![]() |
bca3892757 | |
![]() |
e0dc373741 | |
![]() |
005fa382cb | |
![]() |
0bc0843adc | |
![]() |
5bd4121064 | |
![]() |
ff4d7f2e9c | |
![]() |
b7ffc112de | |
![]() |
50ea6fd00f | |
![]() |
2dab3fab17 | |
![]() |
414b7947a6 | |
![]() |
df3ebd6fa9 | |
![]() |
1d43d19e36 | |
![]() |
9b631344bc | |
![]() |
50199cac48 | |
![]() |
98be025035 | |
![]() |
b5009a353a | |
![]() |
99fe920390 | |
![]() |
40a6427d25 | |
![]() |
5d27786116 | |
![]() |
5756641f2c | |
![]() |
a5c76df1b2 | |
![]() |
8e3cb19950 | |
![]() |
be04d30134 | |
![]() |
14b93e7b55 | |
![]() |
106413cd87 | |
![]() |
b9ffb761b0 | |
![]() |
8d5cd5d7b1 | |
![]() |
65b56d691a | |
![]() |
1b83ef98f3 | |
![]() |
6b944f258d | |
![]() |
e6aebaa736 | |
![]() |
2f4ce7668b | |
![]() |
17272af6a9 | |
![]() |
ce659c3cd7 | |
![]() |
ab36b0e725 | |
![]() |
20dd7ebeae | |
![]() |
4eb9319150 | |
![]() |
a3bd550cb3 | |
![]() |
9fa896354f | |
![]() |
0e3fc4f3a6 | |
![]() |
c01703ce1f | |
![]() |
e61efe6765 | |
![]() |
9bf342c998 | |
![]() |
cf8d751105 | |
![]() |
563c28dd66 | |
![]() |
417e37c51f | |
![]() |
412225bc04 | |
![]() |
14eac4bc62 | |
![]() |
507702ef25 | |
![]() |
f16c9b4c02 | |
![]() |
b4cb3c54a5 | |
![]() |
76dfe8563d | |
![]() |
74e25cb8e0 | |
![]() |
dd046c4f7c | |
![]() |
434ff28458 | |
![]() |
d8bad1efc7 | |
![]() |
c8ac92ee9f | |
![]() |
e48c8fbedb | |
![]() |
3be7e6e4a7 | |
![]() |
e4a665e7d2 | |
![]() |
7e8c868df7 | |
![]() |
5d68a1fd1c | |
![]() |
4b86397f9c | |
![]() |
24309542e4 | |
![]() |
e574566116 | |
![]() |
190c9c01b0 | |
![]() |
ba1b163f92 | |
![]() |
934fa282ba | |
![]() |
5ce96542cb | |
![]() |
2d83fc0a26 | |
![]() |
bf9515f34d | |
![]() |
4e546f1891 | |
![]() |
752219d4e2 | |
![]() |
428ef20a06 | |
![]() |
34a6b6979b | |
![]() |
54538fa46c | |
![]() |
d4423d40f8 | |
![]() |
a6d47814fd | |
![]() |
4773c53f8f | |
![]() |
151becc4fb | |
![]() |
86bb28d042 | |
![]() |
406f1e6956 | |
![]() |
c3b500ae61 | |
![]() |
7c97728895 | |
![]() |
b367744e0e | |
![]() |
986d631b7c | |
![]() |
75e54fd3ee | |
![]() |
52c51b525f | |
![]() |
9c54139460 | |
![]() |
f0e7b122e8 | |
![]() |
e47b2bb373 | |
![]() |
cfcec77e0b | |
![]() |
3e1bd09b0b | |
![]() |
7d5d19948e | |
![]() |
306ec76786 | |
![]() |
443a14a604 | |
![]() |
341f745684 | |
![]() |
e4e6878fdb | |
![]() |
d7a9ab4110 | |
![]() |
d2f5b74cdd | |
![]() |
32b8bbd32e | |
![]() |
39eb36083b | |
![]() |
b1e31ed032 | |
![]() |
8462cdf6cd | |
![]() |
b537b6d8a9 | |
![]() |
fde5414b24 | |
![]() |
cfaae11366 | |
![]() |
e529fb6690 | |
![]() |
ca3dea0155 | |
![]() |
2f239d90f9 | |
![]() |
0dc1431397 | |
![]() |
17c5d8a9a9 | |
![]() |
1a4d8c442f | |
![]() |
e34ea5c03e | |
![]() |
7a20a87715 | |
![]() |
01bdba70b0 | |
![]() |
1080723095 | |
![]() |
00337b1a3b | |
![]() |
6e24e500db | |
![]() |
86315bb0e4 | |
![]() |
f85d45e8bc | |
![]() |
f0b372ec3a | |
![]() |
68ad6eed1f | |
![]() |
0edc24856e | |
![]() |
3486e3087e | |
![]() |
bca8a9ff07 | |
![]() |
a39ca385ad | |
![]() |
523a812d84 | |
![]() |
9f80be42f2 | |
![]() |
f6e8ccc220 | |
![]() |
a1b7745904 | |
![]() |
a5f9f1d351 | |
![]() |
b29826ee93 | |
![]() |
732d4ea4e1 | |
![]() |
7d2b40672a | |
![]() |
3ad74cdeb9 | |
![]() |
fa4558526d | |
![]() |
0590819119 | |
![]() |
bd44bd2f8f | |
![]() |
dc6a88e61f | |
![]() |
7c4022c30c | |
![]() |
0f9be132e0 | |
![]() |
01f53cec6d | |
![]() |
436f9888a5 | |
![]() |
b38d9ad537 | |
![]() |
204ff51409 | |
![]() |
9be997a0f4 | |
![]() |
25d06c2770 | |
![]() |
923d32268a | |
![]() |
962bddae9b | |
![]() |
80c686fc62 | |
![]() |
15cb626994 | |
![]() |
ae9b558bc5 | |
![]() |
1fb7053411 | |
![]() |
4b80a12661 | |
![]() |
f4837ec174 | |
![]() |
64126610be | |
![]() |
3b018602e2 | |
![]() |
ccfe94d616 | |
![]() |
c8b38099e8 | |
![]() |
28caaa6cc0 | |
![]() |
f6beb2c39a | |
![]() |
6298093c3f | |
![]() |
45fe09d037 | |
![]() |
9d10519857 | |
![]() |
73de4a6258 | |
![]() |
bfe59b00b5 | |
![]() |
37a9c6587d | |
![]() |
0d99e2874b | |
![]() |
2755caaf0f | |
![]() |
d9ab573603 | |
![]() |
2b603a3776 | |
![]() |
78b671e20d | |
![]() |
69feb2fb08 | |
![]() |
0efa910af4 | |
![]() |
d19f9d88aa | |
![]() |
08098d89d4 | |
![]() |
75735c9d0b | |
![]() |
2d1cb7d24c | |
![]() |
13bb5d61bb | |
![]() |
dcaa48565d | |
![]() |
cfb9ebd91a | |
![]() |
cdb923628a | |
![]() |
9a0437aa2f | |
![]() |
fe8c0a0b66 | |
![]() |
3f72999e44 | |
![]() |
f891b9dd0a | |
![]() |
6008bdd48a | |
![]() |
a28c57f93d | |
![]() |
275e4a4f51 | |
![]() |
2beb93b28e | |
![]() |
156626fc1c | |
![]() |
82c975fbae | |
![]() |
f9cd1f0dc5 | |
![]() |
085e1737b3 | |
![]() |
8217b08128 | |
![]() |
5fd6e2328b | |
![]() |
cb80c00629 | |
![]() |
fdc1f106f8 | |
![]() |
7ea1cc650f | |
![]() |
4d67dcbaf7 | |
![]() |
5ec4915301 | |
![]() |
36f3f26ffa | |
![]() |
78ff25f0f9 | |
![]() |
43debd45d5 | |
![]() |
017a4d1444 | |
![]() |
45acce752d | |
![]() |
20f714c5d5 | |
![]() |
a0a0232f4d | |
![]() |
b57549e029 | |
![]() |
305ad0551a | |
![]() |
6920160d81 | |
![]() |
6e260274d9 | |
![]() |
5bf3dba8c9 | |
![]() |
4446232c6a | |
![]() |
55251c6507 | |
![]() |
18ff42d25f | |
![]() |
6d5235c1b8 | |
![]() |
01c5ac3a33 | |
![]() |
268f357b13 | |
![]() |
3db62a8f3b | |
![]() |
359f40028e | |
![]() |
1c3fcebc4b | |
![]() |
74855eee78 | |
![]() |
52fd4b8393 | |
![]() |
212b023ac8 | |
![]() |
1aee7b9246 | |
![]() |
d89b74b36c | |
![]() |
264dcf884b | |
![]() |
86f847115f | |
![]() |
08abd79850 | |
![]() |
5fc82a66b2 | |
![]() |
95d3be60f0 | |
![]() |
41abca8a29 | |
![]() |
822837aefd | |
![]() |
15cb66df0e | |
![]() |
580b86904b | |
![]() |
01a0941ffb | |
![]() |
c902f94e99 | |
![]() |
7f8a1f9e8a | |
![]() |
d87b7b793f | |
![]() |
a4e8a5e4b5 | |
![]() |
780edfe9bd | |
![]() |
8b79368b2e | |
![]() |
2365f65b2e | |
![]() |
02b204d1b9 | |
![]() |
e9dff90979 | |
![]() |
ba4184fc61 | |
![]() |
942e0659cf | |
![]() |
c44a7abe0a | |
![]() |
bca1f9e2a9 | |
![]() |
bb419a7c69 | |
![]() |
2252be4a86 | |
![]() |
2e2c870e38 | |
![]() |
157ce930ae | |
![]() |
87324ed3fa | |
![]() |
a729d207eb | |
![]() |
175756dd1f | |
![]() |
4e4bf34e62 | |
![]() |
08fa71141f | |
![]() |
eb8985762f | |
![]() |
5a48ed79c5 | |
![]() |
f2350d5d18 | |
![]() |
d7ab11d7d5 | |
![]() |
c315bd6655 | |
![]() |
0d0a5a1ddf | |
![]() |
81d6628bd8 | |
![]() |
c3d4c2c36d | |
![]() |
208aca7e9a | |
![]() |
d36a33098d | |
![]() |
43ff2cd1e2 | |
![]() |
6a4c4668e3 | |
![]() |
687d4ace0e | |
![]() |
201d7da936 | |
![]() |
dcde9bd35b | |
![]() |
85b9738b2a | |
![]() |
aaae28287f | |
![]() |
8aca3ce406 | |
![]() |
06581eb845 | |
![]() |
83c5920810 | |
![]() |
9e5da28a65 | |
![]() |
af7f02f0e9 | |
![]() |
3004121685 | |
![]() |
cd1dc3aea2 | |
![]() |
0a89640b44 | |
![]() |
e11f04fe51 | |
![]() |
972d3e2f0c | |
![]() |
7bd3bf6e39 | |
![]() |
066d948983 | |
![]() |
63543e825a | |
![]() |
2754edd176 | |
![]() |
140657c453 | |
![]() |
4c74e61039 | |
![]() |
ccecfe8717 | |
![]() |
5724632520 | |
![]() |
3d6cb7148f | |
![]() |
5bfa377b00 | |
![]() |
403d6859ea | |
![]() |
d8db5e869e | |
![]() |
7631123e1f | |
![]() |
f1688288d6 | |
![]() |
69969ab866 | |
![]() |
babef459b0 | |
![]() |
37bad6befc | |
![]() |
a8c75b5c5a | |
![]() |
236322c2cb | |
![]() |
6d8101454b | |
![]() |
5d72ba12f7 | |
![]() |
c1ca4db5da | |
![]() |
3ddcc22d10 | |
![]() |
4c19253805 | |
![]() |
b821415cc0 | |
![]() |
11607b69b4 | |
![]() |
3ad95c9ba2 | |
![]() |
e0523ddeeb | |
![]() |
ebb2467f38 | |
![]() |
ee1f0e2999 | |
![]() |
2b025249f5 | |
![]() |
27bf99717d | |
![]() |
5262d66216 | |
![]() |
c6e798b5a0 | |
![]() |
97587960fc | |
![]() |
044bffc806 | |
![]() |
f9d9a3aa68 | |
![]() |
c51d7be893 | |
![]() |
776acc4533 | |
![]() |
44056ef7b3 | |
![]() |
3f1d80deef | |
![]() |
839724cbae | |
![]() |
c0bc013505 | |
![]() |
90d667de43 | |
![]() |
8988df04c9 | |
![]() |
ae8d587f3b | |
![]() |
5c5a1e37bf | |
![]() |
fc34df3516 | |
![]() |
e7f15ba665 | |
![]() |
cc818ed9c5 | |
![]() |
32cbd2c38f | |
![]() |
991de73177 | |
![]() |
229c5ab1f7 | |
![]() |
ac1bbf7183 | |
![]() |
6acb7a6412 | |
![]() |
3782a4fe7e | |
![]() |
2202f58901 | |
![]() |
6b38bc3f5a | |
![]() |
56d6cb8926 | |
![]() |
8d8bea8525 | |
![]() |
5fb2cc8d8c | |
![]() |
868a3eeef3 | |
![]() |
aaa10ea414 | |
![]() |
7f9a595c22 | |
![]() |
beef0bd457 | |
![]() |
4e60a6b0db | |
![]() |
d8636f764b | |
![]() |
3714f634da | |
![]() |
4a74ea10fc | |
![]() |
08c4c68b74 | |
![]() |
e25c427557 | |
![]() |
0d8f62c996 | |
![]() |
6cff524e32 | |
![]() |
0fe232ffd3 | |
![]() |
26d0eb5c01 | |
![]() |
ded5074d11 | |
![]() |
db7fd59423 | |
![]() |
608ed4f748 | |
![]() |
95c49d764b | |
![]() |
abd4e5c8d9 | |
![]() |
868b2fd7cb | |
![]() |
9659a0a9af | |
![]() |
07cf16aa27 | |
![]() |
ef55d93525 | |
![]() |
f572ab0946 | |
![]() |
33cd6bf4f2 | |
![]() |
f0bd196372 | |
![]() |
479a077e0e | |
![]() |
9b65e6a2e4 | |
![]() |
d8ee31ec1f | |
![]() |
307b36b8c4 | |
![]() |
6c6eaed995 | |
![]() |
c10bc4d83e | |
![]() |
76eec054a6 | |
![]() |
3bcce2c481 | |
![]() |
7e20db0210 | |
![]() |
d0e066eb22 | |
![]() |
a3fa688819 | |
![]() |
aa38cb79b6 | |
![]() |
99cb62f6d3 | |
![]() |
197203e8f6 | |
![]() |
989fecc351 | |
![]() |
6726089791 | |
![]() |
7e41759b04 | |
![]() |
10b133c50f | |
![]() |
fe99919dd0 | |
![]() |
920d9ce91f | |
![]() |
55099ecbdd | |
![]() |
fc3b983080 | |
![]() |
3faefe7c46 | |
![]() |
492fce7645 | |
![]() |
22fd81aa7d | |
![]() |
3a389752bd | |
![]() |
bda42c3236 | |
![]() |
dd3d18ce8a | |
![]() |
f6087efe92 | |
![]() |
38d790b552 | |
![]() |
24942e2c20 | |
![]() |
38c45e0fee | |
![]() |
a3c862900d | |
![]() |
e7b0fcc45c | |
![]() |
4d8d30bd96 | |
![]() |
336a0bf22a | |
![]() |
e21a0400f4 | |
![]() |
1f2e9bbb28 | |
![]() |
74a3b42903 | |
![]() |
9c16cccdef | |
![]() |
8a4d629061 | |
![]() |
27f1968ef6 | |
![]() |
af526c0288 | |
![]() |
ada36cd3d7 | |
![]() |
db75df51b4 | |
![]() |
ec982482aa | |
![]() |
7779dea09b | |
![]() |
18afccf2b8 | |
![]() |
6e1bc4c77c | |
![]() |
c51b372a53 | |
![]() |
a0ee07fdc3 | |
![]() |
bdffdd7b9d | |
![]() |
ca59a8f3c8 | |
![]() |
e2fc5010bf | |
![]() |
61f8e202e7 | |
![]() |
1252d1da94 | |
![]() |
c81bdf642b | |
![]() |
d5f77514ab | |
![]() |
5efaebca76 | |
![]() |
200caa8423 | |
![]() |
3a5ec79227 | |
![]() |
c2a80ada0e | |
![]() |
ba5630e50b | |
![]() |
204a865da4 | |
![]() |
301f20889e | |
![]() |
217f52822d | |
![]() |
d428c6ac9a | |
![]() |
2dba71290d | |
![]() |
64ed418bb5 | |
![]() |
02d7b85fd9 | |
![]() |
eaca65d452 | |
![]() |
8637c11338 | |
![]() |
e407fd9d17 | |
![]() |
7c3200500e | |
![]() |
b382878d0e | |
![]() |
06699aafa0 | |
![]() |
e2534af4e8 | |
![]() |
50a2823da6 | |
![]() |
1966a9b805 | |
![]() |
8c7d8931f2 | |
![]() |
80d0db751f | |
![]() |
859dacdf63 | |
![]() |
bc12f241e5 | |
![]() |
262c2c18f7 | |
![]() |
fef3437579 | |
![]() |
8ca1fc5ad5 | |
![]() |
3e23e2f8bf | |
![]() |
2cdb52d1fa | |
![]() |
3370ca4afc | |
![]() |
e9efdbc3a1 | |
![]() |
f677acf273 | |
![]() |
e5bb3c9ff8 | |
![]() |
2efbca4ef8 | |
![]() |
6e86a2472f | |
![]() |
d02f06e6a3 | |
![]() |
746619a177 | |
![]() |
62ad70bed5 | |
![]() |
2761ffa793 | |
![]() |
36c0457cb3 | |
![]() |
380169f23c | |
![]() |
a0787d92da | |
![]() |
6293372122 | |
![]() |
05679d604e | |
![]() |
51f8d904d2 | |
![]() |
46f2b6aac0 | |
![]() |
1bbcd07da0 | |
![]() |
752b779699 | |
![]() |
ceb3ba9fd3 | |
![]() |
7febd63f99 | |
![]() |
06934fa8d0 | |
![]() |
4c09d07e07 | |
![]() |
2bfb885e87 | |
![]() |
75c6efbe9c | |
![]() |
9bf2373e71 | |
![]() |
4a62657cd3 | |
![]() |
62f48dc662 | |
![]() |
c48d878a20 | |
![]() |
78a6b00dde | |
![]() |
074c169c8c | |
![]() |
26610f44d9 | |
![]() |
5748de3833 | |
![]() |
4f39859c49 | |
![]() |
885b5e971a | |
![]() |
d8b2877649 | |
![]() |
3337086601 | |
![]() |
4302488754 | |
![]() |
f05aeb3e46 | |
![]() |
db185d326c | |
![]() |
65e4959a75 | |
![]() |
7914f4a1b3 | |
![]() |
ecfc678a18 | |
![]() |
38dc5173ec | |
![]() |
93df53e751 | |
![]() |
4ef65aa88b | |
![]() |
d6f1973688 | |
![]() |
963c7866dc | |
![]() |
f6762cb96d | |
![]() |
ae5b448478 | |
![]() |
75f93c566b | |
![]() |
2d7aa7cbb8 | |
![]() |
8ff021d1f8 | |
![]() |
dc888cf888 | |
![]() |
031eb78fd8 | |
![]() |
44161326ad | |
![]() |
7736d65c84 | |
![]() |
bd51fbdac5 | |
![]() |
7fd7f4df10 | |
![]() |
ae75b94f23 | |
![]() |
3ed08681ef | |
![]() |
c8192955b3 | |
![]() |
edc82b3888 | |
![]() |
27f84976da | |
![]() |
5f1d6ee028 | |
![]() |
13e74507cb | |
![]() |
9b62b15637 | |
![]() |
ce533245cf | |
![]() |
64bcd660b2 | |
![]() |
9406bc7c6b | |
![]() |
8682b5bda0 | |
![]() |
ad8e5eb3f7 | |
![]() |
2a6fdcdb3d | |
![]() |
7a39ca8b6e | |
![]() |
7655f7cd8a | |
![]() |
79efea994a | |
![]() |
d6acadc329 | |
![]() |
aebc097e95 | |
![]() |
72c6e69bf0 | |
![]() |
f98fef11db | |
![]() |
b927f214f3 | |
![]() |
d0c94e5e14 | |
![]() |
ce684daacc | |
![]() |
26d6f0db69 | |
![]() |
37f8a5595f | |
![]() |
af5272cff4 | |
![]() |
077366f34b | |
![]() |
2208460aee | |
![]() |
0330545769 | |
![]() |
67a55e5769 | |
![]() |
ca2542d3a1 | |
![]() |
8978295e84 | |
![]() |
397d7a003e | |
![]() |
a77569d1e5 | |
![]() |
35bebad0f8 | |
![]() |
40c77bba71 | |
![]() |
0d5bc7e7ac | |
![]() |
fb0736b2e0 | |
![]() |
4f1b1ab97e | |
![]() |
87eee88752 | |
![]() |
497cf09a98 | |
![]() |
cd147492be | |
![]() |
f753d47c71 | |
![]() |
6924a3d159 | |
![]() |
c7cac63a38 | |
![]() |
d54e7f34fe | |
![]() |
574b60588b | |
![]() |
287a035440 | |
![]() |
9b1238464e | |
![]() |
8e246e200c | |
![]() |
d0fad1091a | |
![]() |
74c0613147 | |
![]() |
02a8970bb6 | |
![]() |
5f0ded46ce | |
![]() |
371c369ae4 | |
![]() |
59c1b21b01 | |
![]() |
b8812d7b6b | |
![]() |
c8b3bd8ba0 | |
![]() |
99d81cc58c | |
![]() |
98b06cffc0 | |
![]() |
d6c1481d17 | |
![]() |
4b79864ccc | |
![]() |
21f1154c07 | |
![]() |
9179a5b1f0 | |
![]() |
2048c8f2a6 | |
![]() |
af50ea273c | |
![]() |
109d36a1c2 | |
![]() |
3e59afb4cf | |
![]() |
7f86868cbe | |
![]() |
84a63da5da | |
![]() |
85c6172224 | |
![]() |
72a4254272 | |
![]() |
4dfdc1b0f8 | |
![]() |
8063a3dacd | |
![]() |
17a29dec98 | |
![]() |
2a6adb536e | |
![]() |
a117ebd31e | |
![]() |
ec7d93b065 | |
![]() |
df59607b4d | |
![]() |
66dbd35807 | |
![]() |
4fdf485020 | |
![]() |
ded7982835 | |
![]() |
c3586060df | |
![]() |
53fd31408f | |
![]() |
2ae4cc49e4 | |
![]() |
2b37ae9ca6 | |
![]() |
0184fc34d2 | |
![]() |
1c42ef7ebb | |
![]() |
633735e085 | |
![]() |
b7722796a5 | |
![]() |
9a04d5275f | |
![]() |
83a7337bc5 | |
![]() |
cfaf737e92 | |
![]() |
7c5ab476da | |
![]() |
af728db149 | |
![]() |
241ee4803e | |
![]() |
7b7cf84594 | |
![]() |
93beb78754 | |
![]() |
a57ca5edc1 | |
![]() |
be5ea25619 | |
![]() |
bba721375d | |
![]() |
5598490601 | |
![]() |
81bc5188f5 | |
![]() |
a54163dbf7 | |
![]() |
576f1cb6fe | |
![]() |
c9ea1aa791 | |
![]() |
a9e63c1349 | |
![]() |
2998131b74 | |
![]() |
6d0cb6d458 | |
![]() |
ea84f0a194 | |
![]() |
1a309235b8 | |
![]() |
df2330989d | |
![]() |
82a5106b85 | |
![]() |
65c5498cda | |
![]() |
f2e465c969 | |
![]() |
7810b9f575 | |
![]() |
76659c10de | |
![]() |
4b73c9486c | |
![]() |
9355ac7fc9 | |
![]() |
eb1fe32c0a | |
![]() |
c648706e82 | |
![]() |
c43c6ad5be | |
![]() |
7590b9bad2 | |
![]() |
1883c5ab58 | |
![]() |
59fe1888c4 | |
![]() |
c9181e5add | |
![]() |
731432d676 | |
![]() |
70daa0868a | |
![]() |
999f9bfd5b | |
![]() |
25dd887283 | |
![]() |
6f5d4e3fff | |
![]() |
809119ff46 | |
![]() |
2697c7bd47 | |
![]() |
e88797253e | |
![]() |
0ef63d4b79 | |
![]() |
78e859725e | |
![]() |
5e4a8b66d3 | |
![]() |
a6746103ec | |
![]() |
87da2de653 | |
![]() |
bc5aaac936 | |
![]() |
ffec4ea576 | |
![]() |
2ca38d65bb | |
![]() |
a1f6194c53 | |
![]() |
b8527cd5ef | |
![]() |
5b736d13d9 | |
![]() |
84c391e17d | |
![]() |
526544e355 | |
![]() |
cd129decfc | |
![]() |
5b3c4eb2d1 | |
![]() |
a5d79817ef | |
![]() |
fd3915af18 | |
![]() |
4c243b6738 | |
![]() |
0a81ecc574 | |
![]() |
c7f4dacc69 | |
![]() |
e0c1aecfc3 | |
![]() |
358140dbf4 | |
![]() |
37c090d649 | |
![]() |
ec2b531f45 | |
![]() |
192897354d | |
![]() |
40206d8af8 | |
![]() |
70d15a5629 | |
![]() |
6a38fcef05 | |
![]() |
3521f60225 | |
![]() |
93f6635ea8 | |
![]() |
32e726b5f4 | |
![]() |
6b003a8cd6 | |
![]() |
fd9fdfd47e | |
![]() |
94836cda4d | |
![]() |
70f70c21bb | |
![]() |
cb892a91bf | |
![]() |
20ca8efd1f | |
![]() |
a84e89eb22 | |
![]() |
4926a912ff | |
![]() |
2b2e47db34 | |
![]() |
600e593040 | |
![]() |
879d9b2722 | |
![]() |
96c06f9c30 | |
![]() |
129df6a057 | |
![]() |
16fa171e95 | |
![]() |
8b1371e830 | |
![]() |
88b2d9ad84 | |
![]() |
19b7fd33a8 | |
![]() |
e9887146ad | |
![]() |
77afcc4de6 | |
![]() |
7102ec1823 | |
![]() |
cbb61a3ee4 | |
![]() |
2309ed2eae | |
![]() |
3baf404873 | |
![]() |
0503927ec1 | |
![]() |
96ff09b86a | |
![]() |
dfa9ffbea6 | |
![]() |
3a03da20e6 | |
![]() |
783bebb658 | |
![]() |
556f8d9492 | |
![]() |
9fdce554ce | |
![]() |
2f585b1ae5 | |
![]() |
c159d1f9e7 | |
![]() |
9bd3a0a601 | |
![]() |
749bf98ad2 | |
![]() |
53fe13be97 | |
![]() |
9571811236 | |
![]() |
9f01010020 | |
![]() |
ab78968b20 | |
![]() |
3600aa96f1 | |
![]() |
8dbbba4026 | |
![]() |
36def4682a | |
![]() |
e4edfcc8ad | |
![]() |
b2f4cac901 | |
![]() |
cf77fd5116 | |
![]() |
ff1703bd1c | |
![]() |
25a8ed7e8c | |
![]() |
e18be00776 | |
![]() |
6aa81dbdda | |
![]() |
2656cdcdff | |
![]() |
343a6a0924 | |
![]() |
712d7046d3 | |
![]() |
75fa3eb438 | |
![]() |
75b4d5b362 | |
![]() |
15863b10b6 | |
![]() |
819f000fb7 | |
![]() |
df90ece66d | |
![]() |
5f2b621ebb | |
![]() |
9274cb8f8c | |
![]() |
20bac793dd | |
![]() |
97487cdaef | |
![]() |
fcc5fbf439 | |
![]() |
4e17fc28ab | |
![]() |
d74d6c3c61 | |
![]() |
6fbf4c3bb3 | |
![]() |
3d358fb814 | |
![]() |
dd1f9326a3 | |
![]() |
5fae122479 | |
![]() |
f742dd7688 | |
![]() |
728c7409f3 | |
![]() |
224de3184f | |
![]() |
54dc514ec3 | |
![]() |
4df3c17c3c | |
![]() |
e787bb3e2b | |
![]() |
63d46d0291 | |
![]() |
018b956ede | |
![]() |
844f52bd5a | |
![]() |
3ee56801f6 | |
![]() |
b078aff86d | |
![]() |
a24d3e67bc | |
![]() |
d7cc995164 | |
![]() |
bd5ec219fa | |
![]() |
c008a9cf84 | |
![]() |
40c5c46c38 | |
![]() |
2541184c93 | |
![]() |
77931d203d | |
![]() |
875a42dd0f | |
![]() |
26367296b0 | |
![]() |
f3099a90c9 | |
![]() |
26104ab685 | |
![]() |
240cbe2c06 | |
![]() |
6ecdde356f | |
![]() |
4334e28171 | |
![]() |
e55390cb6a | |
![]() |
e95f2fdbe0 | |
![]() |
da75f11860 | |
![]() |
2e624d5312 | |
![]() |
2b43161fa1 | |
![]() |
5df0159c96 | |
![]() |
4580be954c | |
![]() |
ca31a22b47 | |
![]() |
2b5e658db0 | |
![]() |
d22618d491 | |
![]() |
40440f38dc | |
![]() |
619fbbded1 | |
![]() |
a49f628c57 | |
![]() |
2f8f72a729 | |
![]() |
a4fa651575 | |
![]() |
8c3da1ce93 | |
![]() |
8e0ff82fe1 | |
![]() |
9b62cd5282 | |
![]() |
ae8ebea664 | |
![]() |
5d425f7e3e | |
![]() |
b02128fd38 | |
![]() |
b6d9acaee6 | |
![]() |
8f694762ca | |
![]() |
fb889bc15c | |
![]() |
7b031ee121 | |
![]() |
024e3717b1 | |
![]() |
8bc8b6fb0b | |
![]() |
7b87f237b3 | |
![]() |
d4b2137462 | |
![]() |
a71a67455b | |
![]() |
d9bb0c3ee6 | |
![]() |
cf1bca29ad | |
![]() |
f0d375bb77 | |
![]() |
11fb04aef2 | |
![]() |
b3195762a3 | |
![]() |
b8a1793f23 | |
![]() |
07d94887ee | |
![]() |
06b5d78496 | |
![]() |
fc41fbc02f | |
![]() |
0084942f18 | |
![]() |
3a6ce6ced1 | |
![]() |
6ecdadcf7b | |
![]() |
1d49959db1 | |
![]() |
d6986852df | |
![]() |
b422f7f782 | |
![]() |
c767485700 | |
![]() |
5f55c86f50 | |
![]() |
de1a97c94e | |
![]() |
830a34d745 | |
![]() |
ce3fdec7c1 | |
![]() |
096f2434c0 | |
![]() |
d0def4a56f | |
![]() |
9158d4346a | |
![]() |
5b2a365d2a | |
![]() |
97e55f8a63 | |
![]() |
069768e18c | |
![]() |
a6f9c33ded | |
![]() |
05449510fb | |
![]() |
e710da1e0c | |
![]() |
4628f711b8 | |
![]() |
cdf62286ec | |
![]() |
b072a5d9f8 | |
![]() |
40284f3b63 | |
![]() |
227702c6bc | |
![]() |
b08c277995 | |
![]() |
6e3e2890bf | |
![]() |
5e6f488675 | |
![]() |
59f46aea97 | |
![]() |
7c3dd3f2aa | |
![]() |
0c9a0f2216 | |
![]() |
c6c9cc957e | |
![]() |
d901b987aa | |
![]() |
dff6fe7ef8 | |
![]() |
fb605dde5c | |
![]() |
bf1a383504 | |
![]() |
a11639fbbe | |
![]() |
a59126aa30 | |
![]() |
525c812073 | |
![]() |
1d55abbe5e | |
![]() |
d0892bdcce | |
![]() |
20082fbec8 | |
![]() |
bebb1aca28 | |
![]() |
db4630127b | |
![]() |
a061f8af10 | |
![]() |
9ed02758fc | |
![]() |
2b36a827ac | |
![]() |
124ee44d39 | |
![]() |
f1c8f7b2b6 | |
![]() |
15c50bf4b5 | |
![]() |
369a5dfc16 | |
![]() |
41f7d70990 | |
![]() |
764f6bc1b9 | |
![]() |
e2576c1f99 | |
![]() |
27507fc4a4 | |
![]() |
21dace2015 | |
![]() |
4871650e65 | |
![]() |
1a6a79fb2e | |
![]() |
8ae39732ec | |
![]() |
3b0d259833 | |
![]() |
158536722b | |
![]() |
73b79cae7d | |
![]() |
81eba12884 | |
![]() |
47e3bd5ffe | |
![]() |
cda621f217 | |
![]() |
49693b2d12 | |
![]() |
945f7effc7 | |
![]() |
3e034ff854 | |
![]() |
13235e298b | |
![]() |
0a6560b47f | |
![]() |
59f8b8c16d | |
![]() |
e7b89da825 | |
![]() |
b819b6102a | |
![]() |
c94c525816 | |
![]() |
6d5a3c9d22 | |
![]() |
7056d2df10 | |
![]() |
5b6bc5e707 | |
![]() |
d7f5148429 | |
![]() |
a3368b92f3 | |
![]() |
f0b3d1c0ba | |
![]() |
2458df8db9 | |
![]() |
3dab241fee | |
![]() |
5c35750d54 | |
![]() |
598938a249 | |
![]() |
b1ef197f89 | |
![]() |
4e6219db8e | |
![]() |
11dbf63db7 | |
![]() |
ddffa287eb | |
![]() |
639fb2a8b4 | |
![]() |
b588457045 | |
![]() |
66bd354e3e | |
![]() |
414a505b71 | |
![]() |
ff8a48f1b2 | |
![]() |
849923968d | |
![]() |
ecf7afea70 | |
![]() |
e4bb59a760 | |
![]() |
c8102fdce9 | |
![]() |
0dbb419c83 | |
![]() |
218452dc8d | |
![]() |
76d4043e6c | |
![]() |
0b66321bfc | |
![]() |
e681373d16 | |
![]() |
905135f3ce | |
![]() |
84b03e8b70 | |
![]() |
ff5735a3f0 | |
![]() |
2f06f8c86e | |
![]() |
6a48cbe64a | |
![]() |
0f20464445 | |
![]() |
6b894c803a | |
![]() |
c2e6392564 | |
![]() |
3930b7e5ca | |
![]() |
7b6adb986e | |
![]() |
77b8af771c | |
![]() |
76a2579e85 | |
![]() |
22646e2307 | |
![]() |
19f0ef5c10 | |
![]() |
f21add69a4 | |
![]() |
8aa358c2cf | |
![]() |
2555844cdc | |
![]() |
abe0d9cf8a | |
![]() |
ec6e9394ec | |
![]() |
f934b9e05e | |
![]() |
9b5f2782df | |
![]() |
4a585c788f | |
![]() |
a924dc6173 | |
![]() |
45672f3ee2 | |
![]() |
512f4ec43c | |
![]() |
735c17f832 | |
![]() |
ca03979556 | |
![]() |
9b02321025 | |
![]() |
3972a79cf6 | |
![]() |
397246eb71 | |
![]() |
ef2b91c7f6 | |
![]() |
3a90dd4558 | |
![]() |
47db1c9297 | |
![]() |
b1302e2cad | |
![]() |
f2423348b4 | |
![]() |
8adeaae8ce | |
![]() |
bd7f948d3a | |
![]() |
3f7cff8902 | |
![]() |
fda928912f | |
![]() |
c59368e118 | |
![]() |
605a155cf5 | |
![]() |
38449a9962 | |
![]() |
3394584aa8 | |
![]() |
a0338f92a8 | |
![]() |
3feb843a53 | |
![]() |
a6f749af41 | |
![]() |
9a518a53b9 | |
![]() |
5f1faf9cc7 | |
![]() |
9d9d18ca21 | |
![]() |
fbcb8dd09d | |
![]() |
8f81b59e88 | |
![]() |
e0564c0661 | |
![]() |
eafac57d1d | |
![]() |
2e4a20e914 | |
![]() |
69afdb7e90 | |
![]() |
63a5845964 | |
![]() |
eb1eceb685 | |
![]() |
bb479e5010 | |
![]() |
b0ed0f6568 | |
![]() |
a85562c01e | |
![]() |
0fe84ca24c | |
![]() |
2fc4ad7383 | |
![]() |
62bcb851bb | |
![]() |
6bf4a971f2 | |
![]() |
e38e6afa35 | |
![]() |
307bd279b4 | |
![]() |
8af0d8716a | |
![]() |
96217eeca5 | |
![]() |
bc437cee0c | |
![]() |
d28cc2144d | |
![]() |
9c2059b472 | |
![]() |
5e01adfc43 | |
![]() |
ec2d815ca3 | |
![]() |
0647dd855b | |
![]() |
9a0f8a1c73 | |
![]() |
2b8807c664 | |
![]() |
5287750dca | |
![]() |
50ae506764 | |
![]() |
ee294db395 | |
![]() |
80ce5f9ac9 | |
![]() |
b32b287f83 | |
![]() |
025b319181 | |
![]() |
0bb570a0dc | |
![]() |
16d870e067 | |
![]() |
0dd1d9b39f | |
![]() |
8cf708846c | |
![]() |
221dbbf652 | |
![]() |
949992f277 | |
![]() |
fb8bf85408 | |
![]() |
c4dd323807 | |
![]() |
d151c08f29 | |
![]() |
89e0cf960c | |
![]() |
33fde54f79 | |
![]() |
55f028a668 | |
![]() |
3f8acc1485 | |
![]() |
bbc6453213 | |
![]() |
f086056100 | |
![]() |
dc0021a015 | |
![]() |
826ae7d005 | |
![]() |
fc8d247093 | |
![]() |
0b4cde4b8c | |
![]() |
0c8a822bb4 | |
![]() |
fcbc70f516 | |
![]() |
68be66cc16 | |
![]() |
30e7b6fd33 | |
![]() |
bd30d5a4a6 | |
![]() |
592f2fbd8a | |
![]() |
3b6dba3b84 | |
![]() |
8bf7eb46e2 | |
![]() |
48ab233b87 | |
![]() |
b20cda468c | |
![]() |
8be62f44f3 | |
![]() |
306ef926f7 | |
![]() |
808195f2d2 | |
![]() |
e51364e2ab | |
![]() |
2fe085546c | |
![]() |
cbfb265c7c | |
![]() |
2de31f2f96 | |
![]() |
667efbe4dd | |
![]() |
6ac9f638a9 | |
![]() |
4e5afa177f | |
![]() |
1bba98aa65 | |
![]() |
6d08aa70fe | |
![]() |
c4e0884da5 | |
![]() |
4b0e7b3d19 | |
![]() |
ce75418893 | |
![]() |
ee385a8cf0 | |
![]() |
393a588aa9 | |
![]() |
d97a38a51f | |
![]() |
0495c975a4 | |
![]() |
0ee5b6681b | |
![]() |
2b522ca814 | |
![]() |
9bd225d280 | |
![]() |
58d8b684d5 | |
![]() |
db2081a2c6 | |
![]() |
466023fac3 | |
![]() |
126a9fd1ac | |
![]() |
b9b792418d | |
![]() |
43873a1d66 | |
![]() |
8344f78445 | |
![]() |
7dfebef26f | |
![]() |
2bf74e6ceb | |
![]() |
10eed9a28f | |
![]() |
2a44255a30 | |
![]() |
3d46f0b942 | |
![]() |
4d9b132835 | |
![]() |
b0e4d47a7f | |
![]() |
738f2d4a0e | |
![]() |
8d62336553 | |
![]() |
f059ea73e8 | |
![]() |
dbeeab064a | |
![]() |
2fa60f0bca | |
![]() |
2d8ef7f1b3 | |
![]() |
981b5c8fc3 | |
![]() |
0b5a3b9b36 | |
![]() |
c8193c3550 | |
![]() |
a844eb84af | |
![]() |
22819463f7 | |
![]() |
3ba95f3d67 | |
![]() |
4a1e511494 | |
![]() |
d14f67b19f | |
![]() |
d534e5cde2 | |
![]() |
334edbeff1 | |
![]() |
5dd0146d4d | |
![]() |
63b9024ce9 | |
![]() |
79dcbc2975 | |
![]() |
0b63decafc | |
![]() |
52958304c7 | |
![]() |
c98dd49594 | |
![]() |
f32e539bc0 | |
![]() |
f214f3697d | |
![]() |
8bd023f1a1 | |
![]() |
66233326b6 | |
![]() |
d7b34387bd | |
![]() |
0c22737e64 | |
![]() |
91786be2d9 | |
![]() |
1335dc3fd7 | |
![]() |
4bab5eee2e | |
![]() |
280eb13226 | |
![]() |
54c9097144 | |
![]() |
a872c8fb42 | |
![]() |
8d9ca0657a | |
![]() |
1e55231f3c | |
![]() |
059bacde34 | |
![]() |
eff25e007e | |
![]() |
47c6b66e51 | |
![]() |
4547077120 | |
![]() |
73139b6521 | |
![]() |
19f65a75ad | |
![]() |
e58c8e45dd | |
![]() |
b4772a4443 | |
![]() |
aadd10deeb | |
![]() |
ba5bbe6172 | |
![]() |
27182d2c46 | |
![]() |
2db390d8c0 | |
![]() |
7cea6ffa8b | |
![]() |
92d197e471 | |
![]() |
2aee4c161b | |
![]() |
2e66631587 | |
![]() |
d31a8fd938 | |
![]() |
44d2c78381 | |
![]() |
8ffc778214 | |
![]() |
0d8d7de170 | |
![]() |
d8c2cdf019 | |
![]() |
c7fbfb6d47 | |
![]() |
f98afa13cf | |
![]() |
61f5b1aa2a | |
![]() |
4578be499d | |
![]() |
6af8794113 | |
![]() |
381ba8f991 | |
![]() |
72f64dd84d | |
![]() |
c18034385e | |
![]() |
b9ff4e375b | |
![]() |
80ac696c43 | |
![]() |
11db027a0a | |
![]() |
9c1cd5117c | |
![]() |
e55bf475cf | |
![]() |
e02ec9870f | |
![]() |
6ac5dc9915 | |
![]() |
7afc53b081 | |
![]() |
8e4daf4b60 | |
![]() |
f8972dc11b | |
![]() |
4560da840b | |
![]() |
7583e5d655 | |
![]() |
14960f8115 | |
![]() |
49a25c7bde | |
![]() |
c7de953fdd | |
![]() |
525e781f3f | |
![]() |
b374fb048f | |
![]() |
4a7659bad2 | |
![]() |
0370f39fe8 | |
![]() |
31761f7249 | |
![]() |
05c77cc6a6 | |
![]() |
a39a03309e | |
![]() |
e5e4e542b2 | |
![]() |
30c58be443 | |
![]() |
9308efcd9d | |
![]() |
83af23081f | |
![]() |
b68b587cc1 | |
![]() |
57dff93271 | |
![]() |
b20b1c1bfe | |
![]() |
975a6940a5 | |
![]() |
d8fad47e93 | |
![]() |
36b3c70ef6 | |
![]() |
8bc9b00660 | |
![]() |
cc6d53d561 | |
![]() |
9ac88c6662 | |
![]() |
33234936f2 | |
![]() |
ddefa7a66e | |
![]() |
502b73f288 | |
![]() |
4d784d4a5b | |
![]() |
f4d135fc6e | |
![]() |
b1f98f7ce4 | |
![]() |
547b2e4bdf | |
![]() |
4c7684bf74 | |
![]() |
fb164fb740 | |
![]() |
bccb2d3cb2 | |
![]() |
435bf7cb8a | |
![]() |
c19a86147a | |
![]() |
0a2e25cdec | |
![]() |
f35864406c | |
![]() |
7dabe6a781 | |
![]() |
5419a3b9a9 | |
![]() |
cc3b17a00e | |
![]() |
5a2d0345ec | |
![]() |
1b9e885370 | |
![]() |
ed07f642cd | |
![]() |
82666d6e43 | |
![]() |
a0e666aef2 | |
![]() |
a593fdfb49 | |
![]() |
204c1f092c | |
![]() |
8d67d9a2e5 | |
![]() |
c7869803b1 | |
![]() |
b9f4a9258f | |
![]() |
b50798242a | |
![]() |
0e51197934 | |
![]() |
4f73d84f49 | |
![]() |
d9140500db | |
![]() |
d3166fee1d | |
![]() |
eed55ed3b1 | |
![]() |
a61f5f5977 | |
![]() |
9d427d5260 | |
![]() |
f4a8947528 | |
![]() |
7f98563a6f | |
![]() |
b28526da7d | |
![]() |
2cdd9bc1f6 | |
![]() |
a83683a902 | |
![]() |
091ccf3506 | |
![]() |
b22b4d963a | |
![]() |
4e9f1fc9c5 | |
![]() |
37c27ef52b | |
![]() |
a4edbe8b85 | |
![]() |
59708aab62 | |
![]() |
4e71ab3c79 | |
![]() |
0a77776cd2 | |
![]() |
0248e4a6dc | |
![]() |
15aa163b84 | |
![]() |
cd497bc8a5 | |
![]() |
fd5713d764 | |
![]() |
e66bfc2c99 | |
![]() |
8c29b3749f | |
![]() |
083bc8b556 | |
![]() |
8834f4770f | |
![]() |
2841ac52ca | |
![]() |
30656f73c2 | |
![]() |
65180d524f | |
![]() |
6fa24835c0 | |
![]() |
d7a3ab5b6c | |
![]() |
df9758903a | |
![]() |
eec90382e7 | |
![]() |
dde7ab5936 | |
![]() |
c33bccbc61 | |
![]() |
0e39371e76 | |
![]() |
6593e25f41 | |
![]() |
eccf1d0d36 | |
![]() |
db44445386 | |
![]() |
077cd38c76 | |
![]() |
5004b439bd | |
![]() |
3902778b12 | |
![]() |
bdd7035fef | |
![]() |
4836dd0be1 | |
![]() |
ffcf26d822 | |
![]() |
537f85d391 | |
![]() |
7a8b5c276c | |
![]() |
24cf13c535 | |
![]() |
c1a488f19f | |
![]() |
491e377752 | |
![]() |
199f120d91 | |
![]() |
aae9027383 | |
![]() |
a340e43f7c | |
![]() |
bfc091b975 |
|
@ -0,0 +1,68 @@
|
|||
---
|
||||
name: Build
|
||||
|
||||
on:
|
||||
pull_request:
|
||||
push:
|
||||
|
||||
permissions: {}
|
||||
|
||||
jobs:
|
||||
linux:
|
||||
name: Linux
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: Check out the repository
|
||||
uses: actions/checkout@93ea575cb5d8a053eaa0ac8fa3b40d7e05a33cc8
|
||||
- name: Install SDL2
|
||||
run: |
|
||||
sudo apt-get update
|
||||
sudo apt-get install libsdl2-dev
|
||||
- name: Build Stella
|
||||
run: |
|
||||
./configure && make -j2 all
|
||||
|
||||
macos:
|
||||
name: macOS
|
||||
runs-on: macos-latest
|
||||
steps:
|
||||
- uses: maxim-lobanov/setup-xcode@v1
|
||||
with:
|
||||
xcode-version: '16.2'
|
||||
- name: Check out the repository
|
||||
uses: actions/checkout@93ea575cb5d8a053eaa0ac8fa3b40d7e05a33cc8
|
||||
- name: Install SDL2
|
||||
run: |
|
||||
curl https://www.libsdl.org/release/SDL2-2.26.0.tar.gz | tar xzf -
|
||||
mkdir SDL2-2.26.0/build
|
||||
cd SDL2-2.26.0/build
|
||||
../configure && make -j3 && sudo make install
|
||||
- name: Build Stella
|
||||
run: |
|
||||
./configure && make -j3 all
|
||||
|
||||
windows:
|
||||
name: Windows
|
||||
runs-on: windows-latest
|
||||
strategy:
|
||||
matrix:
|
||||
platform: [x64]
|
||||
env:
|
||||
Platform: ${{ matrix.platform }}
|
||||
SDL2_version: 2.26.0
|
||||
steps:
|
||||
- name: Check out the repository
|
||||
uses: actions/checkout@93ea575cb5d8a053eaa0ac8fa3b40d7e05a33cc8
|
||||
- name: Set up MSBUILD
|
||||
uses: microsoft/setup-msbuild@34cfbaee7f672c76950673338facd8a73f637506
|
||||
- name: Install SDL2
|
||||
shell: cmd
|
||||
run: |
|
||||
curl -o "C:\SDL2-devel.zip" "https://www.libsdl.org/release/SDL2-devel-%SDL2_version%-VC.zip"
|
||||
7z x "C:\SDL2-devel.zip" -o"C:\"
|
||||
xcopy /S "C:\SDL2-%SDL2_version%\include" src\common
|
||||
if %Platform%==x64 xcopy /S "C:\SDL2-%SDL2_version%\lib\x64" src\os\windows
|
||||
|
||||
- name: Build Stella
|
||||
run: |
|
||||
msbuild src\os\windows\Stella.sln
|
|
@ -10,7 +10,9 @@ src/**/*.tlog
|
|||
out
|
||||
out.pgo
|
||||
out.pgen
|
||||
out.test
|
||||
stella
|
||||
stella-test
|
||||
stella-pgo
|
||||
stella-pgo-generate
|
||||
*.diff
|
||||
|
@ -18,15 +20,17 @@ project.xcworkspace/
|
|||
xcuserdata/
|
||||
.DS_Store
|
||||
build/
|
||||
src/macosx/M6502.ins
|
||||
src/os/macos/M6502.ins
|
||||
*.dSYM
|
||||
.vscode/c_cpp_properties.json
|
||||
.vscode/settings.json
|
||||
src/windows/sdl/*
|
||||
src/windows/x64/*
|
||||
src/windows/Win32/*
|
||||
src/windows/Stella.vcxproj.user
|
||||
src/windows/*.bak
|
||||
src/os/windows/sdl/*
|
||||
src/os/windows/x64/*
|
||||
src/os/windows/Win32/*
|
||||
src/os/windows/Stella.vcxproj.user
|
||||
src/os/windows/*.bak
|
||||
src/os/libretro/x64/*
|
||||
src/os/libretro/Stella.vcxproj.user
|
||||
.vs/*
|
||||
.tgitconfig
|
||||
src/**/*.psess
|
||||
|
@ -38,3 +42,5 @@ src/tools/fonts/*
|
|||
a.out
|
||||
*.json
|
||||
*.sqlite3
|
||||
*.bak
|
||||
debian/files
|
||||
|
|
148
.gitlab-ci.yml
|
@ -1,60 +1,148 @@
|
|||
# DESCRIPTION: GitLab CI/CD for libRetro (NOT FOR GitLab-proper)
|
||||
|
||||
##############################################################################
|
||||
################################# BOILERPLATE ################################
|
||||
##############################################################################
|
||||
|
||||
# Core definitions
|
||||
.core-defs:
|
||||
variables:
|
||||
JNI_PATH: src/libretro
|
||||
MAKEFILE_PATH: src/libretro
|
||||
JNI_PATH: src/os/libretro
|
||||
MAKEFILE_PATH: src/os/libretro
|
||||
CORENAME: stella
|
||||
|
||||
# Inclusion templates, required for the build to work
|
||||
include:
|
||||
- template: Jobs/Code-Quality.gitlab-ci.yml
|
||||
- project: 'libretro-infrastructure/ci-templates'
|
||||
file: '/libnx-static.yml'
|
||||
- project: 'libretro-infrastructure/ci-templates'
|
||||
file: '/linux-x64.yml'
|
||||
################################## DESKTOPS ################################
|
||||
# Windows 64-bit
|
||||
- project: 'libretro-infrastructure/ci-templates'
|
||||
file: '/windows-x64-mingw.yml'
|
||||
|
||||
# Linux 64-bit
|
||||
- project: 'libretro-infrastructure/ci-templates'
|
||||
file: '/linux-x64.yml'
|
||||
|
||||
# MacOS 64-bit
|
||||
- project: 'libretro-infrastructure/ci-templates'
|
||||
file: '/osx-x64.yml'
|
||||
|
||||
# MacOS ARM 64-bit
|
||||
- project: 'libretro-infrastructure/ci-templates'
|
||||
file: '/osx-arm64.yml'
|
||||
|
||||
################################## CELLULAR ################################
|
||||
# Android
|
||||
- project: 'libretro-infrastructure/ci-templates'
|
||||
file: '/android-jni.yml'
|
||||
|
||||
# iOS
|
||||
- project: 'libretro-infrastructure/ci-templates'
|
||||
file: '/ios-arm64.yml'
|
||||
|
||||
# iOS (armv7)
|
||||
- project: 'libretro-infrastructure/ci-templates'
|
||||
file: '/ios9.yml'
|
||||
|
||||
################################## CONSOLES ################################
|
||||
# Nintendo Switch
|
||||
- project: 'libretro-infrastructure/ci-templates'
|
||||
file: '/libnx-static.yml'
|
||||
|
||||
# tvOS (AppleTV)
|
||||
- project: 'libretro-infrastructure/ci-templates'
|
||||
file: '/tvos-arm64.yml'
|
||||
|
||||
#################################### MISC ##################################
|
||||
|
||||
# Stages for building
|
||||
stages:
|
||||
- build-prepare
|
||||
- build-shared
|
||||
- build-static
|
||||
- test
|
||||
|
||||
#Desktop
|
||||
libretro-build-linux-x64:
|
||||
extends:
|
||||
- .libretro-linux-x64-make-default
|
||||
- .core-defs
|
||||
|
||||
##############################################################################
|
||||
#################################### STAGES ##################################
|
||||
##############################################################################
|
||||
#
|
||||
################################### DESKTOPS #################################
|
||||
# Windows 64-bit
|
||||
libretro-build-windows-x64:
|
||||
extends:
|
||||
- .libretro-windows-x64-mingw-make-default
|
||||
- .core-defs
|
||||
|
||||
# Android
|
||||
android-armeabi-v7a:
|
||||
|
||||
# Linux 64-bit
|
||||
libretro-build-linux-x64:
|
||||
extends:
|
||||
- .libretro-android-jni-armeabi-v7a
|
||||
- .libretro-linux-x64-make-default
|
||||
- .core-defs
|
||||
image: $CI_SERVER_HOST:5050/libretro-infrastructure/libretro-build-amd64-ubuntu:latest
|
||||
before_script:
|
||||
- export NUMPROC=$(($(nproc)/5))
|
||||
- sudo apt-get update -qy
|
||||
- sudo apt-get install -qy software-properties-common
|
||||
- sudo add-apt-repository -y ppa:savoury1/build-tools
|
||||
- sudo add-apt-repository -y ppa:savoury1/gcc-defaults-12
|
||||
- sudo apt-get update -qy
|
||||
- sudo apt-get install -qy gcc-12 g++-12
|
||||
# This container's existing installations of gcc and CMake are way too old
|
||||
variables:
|
||||
CC: /usr/bin/gcc-12
|
||||
CXX: /usr/bin/g++-12
|
||||
CXXFLAGS: -Wno-deprecated-declarations # Deprecation warnings aren't helpful on the libretro Gitlab
|
||||
|
||||
# MacOS 64-bit
|
||||
libretro-build-osx-x64:
|
||||
tags:
|
||||
- mac-apple-silicon
|
||||
extends:
|
||||
- .libretro-osx-x64-make-default
|
||||
- .core-defs
|
||||
|
||||
android-arm64-v8a:
|
||||
# MacOS ARM 64-bit
|
||||
libretro-build-osx-arm64:
|
||||
tags:
|
||||
- mac-apple-silicon
|
||||
extends:
|
||||
- .libretro-android-jni-arm64-v8a
|
||||
- .libretro-osx-arm64-make-default
|
||||
- .core-defs
|
||||
|
||||
android-x86_64:
|
||||
################################### CELLULAR #################################
|
||||
# Android ARMv7a
|
||||
# android-armeabi-v7a:
|
||||
# extends:
|
||||
# - .libretro-android-jni-armeabi-v7a
|
||||
# - .core-defs
|
||||
|
||||
# Android ARMv8a
|
||||
# android-arm64-v8a:
|
||||
# extends:
|
||||
# - .libretro-android-jni-arm64-v8a
|
||||
# - .core-defs
|
||||
|
||||
# Android 64-bit x86
|
||||
# android-x86_64:
|
||||
# extends:
|
||||
# - .libretro-android-jni-x86_64
|
||||
# - .core-defs
|
||||
|
||||
# iOS
|
||||
libretro-build-ios-arm64:
|
||||
tags:
|
||||
- mac-apple-silicon
|
||||
extends:
|
||||
- .libretro-android-jni-x86_64
|
||||
- .core-defs
|
||||
|
||||
android-x86:
|
||||
extends:
|
||||
- .libretro-android-jni-x86
|
||||
- .libretro-ios-arm64-make-default
|
||||
- .core-defs
|
||||
|
||||
# Static
|
||||
libretro-build-libnx-aarch64:
|
||||
# tvOS
|
||||
libretro-build-tvos-arm64:
|
||||
extends:
|
||||
- .libretro-libnx-static-retroarch-master
|
||||
- .libretro-tvos-arm64-make-default
|
||||
- .core-defs
|
||||
|
||||
################################### CONSOLES #################################
|
||||
# Nintendo Switch
|
||||
# libretro-build-libnx-aarch64:
|
||||
# extends:
|
||||
# - .libretro-libnx-static-retroarch-master
|
||||
# - .core-defs
|
||||
|
|
63
.travis.yml
|
@ -1,63 +0,0 @@
|
|||
# Build matrix / environment variables are explained on:
|
||||
# http://about.travis-ci.org/docs/user/build-configuration/
|
||||
# This file can be validated on: http://lint.travis-ci.org/
|
||||
|
||||
|
||||
language: cpp
|
||||
|
||||
|
||||
matrix:
|
||||
include:
|
||||
- os: linux
|
||||
dist: xenial
|
||||
compiler: gcc
|
||||
env: GCC=9 CC=gcc-9 CXX=g++-9
|
||||
addons:
|
||||
apt:
|
||||
sources:
|
||||
- ubuntu-toolchain-r-test
|
||||
packages:
|
||||
- gcc-9
|
||||
- g++-9
|
||||
update: true
|
||||
|
||||
|
||||
- os: osx
|
||||
osx_image: xcode11.3
|
||||
compiler: clang
|
||||
addons:
|
||||
homebrew:
|
||||
update: true
|
||||
|
||||
|
||||
install:
|
||||
- |
|
||||
old_cwd=$(pwd)
|
||||
cd ~
|
||||
|
||||
if [[ "$HOST" == macosx-* ]]; then
|
||||
curl -O https://www.libsdl.org/release/SDL2-2.0.10.tar.gz
|
||||
tar xzf SDL2-2.0.10.tar.gz
|
||||
cd SDL2-2.0.10/Xcode/SDL
|
||||
sed -i -e 's/@rpath//g' SDL.xcodeproj/project.pbxproj
|
||||
xcodebuild -configuration Release
|
||||
mkdir -p ~/Library/Frameworks/
|
||||
ln -s `pwd`/build/Release/SDL2.framework ~/Library/Frameworks/
|
||||
else
|
||||
curl -O https://www.libsdl.org/release/SDL2-2.0.10.tar.gz
|
||||
tar xzf SDL2-2.0.10.tar.gz
|
||||
cd SDL2-2.0.10
|
||||
mkdir build
|
||||
cd build
|
||||
../configure
|
||||
make
|
||||
sudo make install
|
||||
fi
|
||||
|
||||
cd $old_cwd
|
||||
|
||||
|
||||
script:
|
||||
- |
|
||||
./configure
|
||||
make all
|
|
@ -14,6 +14,7 @@
|
|||
"C_Cpp.intelliSenseEngine": "Default",
|
||||
"files.insertFinalNewline": true,
|
||||
"files.associations": {
|
||||
"*.h": "cpp",
|
||||
"__functional_base": "cpp",
|
||||
"array": "cpp",
|
||||
"istream": "cpp",
|
||||
|
@ -103,6 +104,18 @@
|
|||
"version": "cpp",
|
||||
"shared_mutex": "cpp",
|
||||
"compare": "cpp",
|
||||
"concepts": "cpp"
|
||||
"concepts": "cpp",
|
||||
"__verbose_abort": "cpp",
|
||||
"any": "cpp",
|
||||
"charconv": "cpp",
|
||||
"csignal": "cpp",
|
||||
"execution": "cpp",
|
||||
"numbers": "cpp",
|
||||
"span": "cpp",
|
||||
"unordered_set": "cpp",
|
||||
"variant": "cpp",
|
||||
"hash_map": "cpp",
|
||||
"format": "cpp",
|
||||
"*.inc": "cpp"
|
||||
}
|
||||
}
|
||||
|
|
22
Announce.txt
|
@ -9,7 +9,7 @@
|
|||
SSSS ttt eeeee llll llll aaaaa
|
||||
|
||||
===========================================================================
|
||||
Release 6.5.2 for Linux, macOS and Windows
|
||||
Release 7.0 for Linux, macOS and Windows
|
||||
===========================================================================
|
||||
|
||||
The Atari 2600 Video Computer System (VCS), introduced in 1977, was the
|
||||
|
@ -21,25 +21,21 @@ all of your favourite Atari 2600 games again! Stella was originally
|
|||
developed for Linux by Bradford W. Mott, however, it has been ported to a
|
||||
number of other platforms and is currently maintained by Stephen Anthony.
|
||||
|
||||
This is the 6.5.2 release of Stella for Linux, macOS and Windows. The
|
||||
This is the 7.0 release of Stella for Linux, macOS and Windows. The
|
||||
distributions currently available are:
|
||||
|
||||
* Binaries for Windows 7/8/10 :
|
||||
Stella-6.5.2-win32.exe (32-bit EXE installer)
|
||||
Stella-6.5.2-x64.exe (64-bit EXE installer)
|
||||
Stella-6.5.2-windows.zip (32/64 bit versions)
|
||||
* Binary for Windows 7/8/10/11 :
|
||||
Stella-7.0-x64.exe (64-bit EXE installer)
|
||||
Stella-7.0-windows.zip (64 bit ZIP version)
|
||||
|
||||
* Binary distribution for macOS 10.7 and above :
|
||||
Stella-6.5.2-macos.dmg (64-bit Intel)
|
||||
* Binary distribution for macOS 10.13 and above :
|
||||
Stella-7.0-macos.dmg (ARM M1 and 64-bit Intel)
|
||||
|
||||
* Binary distribution for 64-bit Ubuntu :
|
||||
stella_6.5.2-1_amd64.deb
|
||||
|
||||
* Binary distribution for 64-bit Redhat :
|
||||
stella-6.5.2-2.x86_64.rpm
|
||||
stella_7.0-1_amd64.deb
|
||||
|
||||
* Source code distribution for all platforms :
|
||||
stella-6.5.2-src.tar.xz
|
||||
stella-7.0-src.tar.xz
|
||||
|
||||
|
||||
Distribution Site
|
||||
|
|
194
Changes.txt
|
@ -12,6 +12,198 @@
|
|||
Release History
|
||||
===========================================================================
|
||||
|
||||
7.0 to 7.1 (xxx x, 202x)
|
||||
|
||||
* Added developer option for disabling PlusROM support (TODO: Doc)
|
||||
|
||||
* Enhanced PAL-60 detection, searches for signature (e.g. PAL60) in ROM
|
||||
|
||||
* Enhanced VSYNC emulation, considers VBLANK now too
|
||||
|
||||
6.7.1 to 7.0 (October 5, 2024)
|
||||
|
||||
* Enhanced ROM launcher to allow multiple images per ROM.
|
||||
|
||||
* Made heaps of additional images available for the ROM launcher.
|
||||
|
||||
* Added searching by filename for ROM launcher images.
|
||||
|
||||
* Added option to start random ROM.
|
||||
|
||||
* Added automatically enabled phosphor modes.
|
||||
|
||||
* Enhanced Game Properties dialog for multigame ROMs.
|
||||
|
||||
* Added 2nd UI theme and hotkey for toggling UI theme.
|
||||
|
||||
* Added bezel support (incl. Sinden Lightgun).
|
||||
|
||||
* Added optional type format detection based on colors used.
|
||||
|
||||
* Added Joy2B+ controller support.
|
||||
|
||||
* Added auto detection for QuadTari attached controllers.
|
||||
|
||||
* Enhanced Kid Vid support to play tape audio.
|
||||
|
||||
* Added port selection, used for controller default mapping.
|
||||
|
||||
* Added missing PlusROM support for E7 bankswitching.
|
||||
|
||||
* Enhanced movie cart (MVC) support.
|
||||
|
||||
* Accelerated emulation up to ~15% (ARM).
|
||||
|
||||
* Added limited GameLine Master Module bankswitching support.
|
||||
|
||||
* Added 03E0 bankswitching for Brazilian Parker Bros ROMs.
|
||||
|
||||
* Added WF8 bankswitching used by some certain Coleco white carts.
|
||||
|
||||
* Added JANE bankswitching used by Coleco's Tarzan prototype.
|
||||
|
||||
* Added ELF mapper for Mattress Monkeys.
|
||||
|
||||
* Added BUS bankswitching support for some older demos.
|
||||
|
||||
* Fixed broken 7800 pause key support.
|
||||
|
||||
* Added developer option for random hotspot peek values.
|
||||
|
||||
* Added user defined CPU cycle timers to debugger.
|
||||
|
||||
* Removed 'launcherroms' option, since it was causing some issues.
|
||||
|
||||
* Codebase now uses C++20 features, which means a minimum of gcc-11
|
||||
or clang-10 for Linux/Mac, and Visual Studio 2022 for Windows.
|
||||
|
||||
-Have fun!
|
||||
|
||||
|
||||
6.7 to 6.7.1 (January 15, 2024)
|
||||
|
||||
* Fixed broken mouse and Stelladaptor input for Driving Controller.
|
||||
|
||||
* For UNIX systems: Now defaults to using system-installed libsqlite3
|
||||
when available, and fixes delay on exiting app experienced on some
|
||||
systems.
|
||||
|
||||
|
||||
6.6 to 6.7 (June 13, 2022)
|
||||
|
||||
* IMPORTANT NOTES:
|
||||
- Because of fixes to JSON handling, all remappings will be reset
|
||||
to defaults; if you had custom mappings, they will need to be
|
||||
re-entered again.
|
||||
- Because of internal changes, all state files are now invalid.
|
||||
|
||||
* Completely reworked the file launcher:
|
||||
- Redesigned user interface
|
||||
- Added tracking of user favorites, recently played and most popular
|
||||
games
|
||||
- Added virtual directories for selecting tracked games
|
||||
- Added quick path navigation
|
||||
- Added navigation history
|
||||
- Added icons for files and directories
|
||||
- Added option to show/hide file extensions
|
||||
- Extended context menu and shortcuts
|
||||
- Fixed sluggish behaviour when reading large and/or invalid files
|
||||
|
||||
* Added hotkey display to tooltips.
|
||||
|
||||
* Added option to automatically pause emulation when focus is lost.
|
||||
|
||||
* Added option to toggle autofire mode.
|
||||
|
||||
* Improved controller mappings for Paddles.
|
||||
|
||||
* Improved controller mappings for Driving controllers.
|
||||
|
||||
* Improved Mindlink support.
|
||||
|
||||
* Added another oddball TIA glitch option for score mode color.
|
||||
|
||||
* Enhanced TV jitter emulation (TODO: doc).
|
||||
|
||||
* Enhanced support for CDFJ+ bankswitching type.
|
||||
|
||||
* Added 0FA0 bankswitching for Fotomania ROMs.
|
||||
|
||||
* Added ARM chip auto detection.
|
||||
|
||||
* Extended support for older BUS (experimental) ROMs that worked
|
||||
with an older, obsolete version of the BUS scheme; special thanks
|
||||
to SpiceWare for the code.
|
||||
|
||||
* Fixed Stella crash due to invalid ZIP files.
|
||||
|
||||
* Fixed TV mode auto detection in some ARM ROMs.
|
||||
|
||||
* Fixed color loss when switching TV mode from/to PAL.
|
||||
|
||||
* Fixed score mode glitch emulation corner case.
|
||||
|
||||
* Fixed state messages staying on screen forever.
|
||||
|
||||
* Added M1 support for the macOS build.
|
||||
|
||||
* Debugger improvements:
|
||||
- added PlusROM information
|
||||
- fixed patching code in ZP-RAM
|
||||
- improved bank origin detection
|
||||
|
||||
* Updated internal ROM properties database to ROM-Hunter version 17
|
||||
(thanks go to RomHunter for his tireless research in this area).
|
||||
Related to this, updated the snapshot collection.
|
||||
|
||||
|
||||
6.5.3 to 6.6 (November 16, 2021)
|
||||
|
||||
* Added preliminary PlusROM support for saving high scores.
|
||||
|
||||
* Added preliminary support for 'MVC' bankswitching scheme by
|
||||
Rob Bairos.
|
||||
|
||||
* Added web links for many games.
|
||||
|
||||
* Added dead zone and linearity settings for analog controllers.
|
||||
|
||||
* Added 'Check for Update' button to Help dialog.
|
||||
|
||||
* Added different mask patterns for scanline emulation.
|
||||
|
||||
* Fixed MindLink controller.
|
||||
|
||||
* Fixed SaveKey not working with QuadTari.
|
||||
|
||||
* Added TIA randomization on startup option.
|
||||
|
||||
* Added different debug color luminances for player and missile copies.
|
||||
|
||||
* Added hotkeys for TV roll speed and toggling 'Developer settings' sets.
|
||||
|
||||
* Debugger: enhanced prompt's auto complete and history.
|
||||
|
||||
* Debugger: added optional logging of breaks and traps.
|
||||
|
||||
* Debugger: added Thumb cycle counting.
|
||||
|
||||
|
||||
6.5.2 to 6.5.3 (April 20, 2021)
|
||||
|
||||
* Added context-sensitive help.
|
||||
|
||||
* Improved support of multiple monitors with different resolutions.
|
||||
|
||||
* Improved analog input reading (Paddles, Keyboards...).
|
||||
|
||||
* Fixed QuadTari support for controller types other than Joysticks.
|
||||
|
||||
* Fixed palette and TV effects saving for Retron77.
|
||||
|
||||
* Fixed immediate disassembling when switching options in debugger.
|
||||
|
||||
|
||||
6.5.1 to 6.5.2 (February 25, 2021)
|
||||
|
||||
* Fixed broken Driving Controller support for Stelladaptor/2600-daptor
|
||||
|
@ -23,8 +215,6 @@
|
|||
|
||||
* Added CPU usage stats to ARM cart classes debug widgets.
|
||||
|
||||
-Have fun!
|
||||
|
||||
|
||||
6.5 to 6.5.1 (January 24, 2021)
|
||||
|
||||
|
|
|
@ -12,7 +12,7 @@
|
|||
License Information and Copyright Notice
|
||||
===========================================================================
|
||||
|
||||
Copyright (c) 1995-2021 by Bradford W. Mott, Stephen Anthony and the
|
||||
Copyright (c) 1995-2025 by Bradford W. Mott, Stephen Anthony and the
|
||||
Stella Team
|
||||
|
||||
This program is free software; you can redistribute it and/or modify it
|
||||
|
|
91
Makefile
|
@ -8,7 +8,7 @@
|
|||
## SS SS tt ee ll ll aa aa
|
||||
## SSSS ttt eeeee llll llll aaaaa
|
||||
##
|
||||
## Copyright (c) 1995-2021 by Bradford W. Mott, Stephen Anthony
|
||||
## Copyright (c) 1995-2025 by Bradford W. Mott, Stephen Anthony
|
||||
## and the Stella Team
|
||||
##
|
||||
## See the file "License.txt" for information on usage and redistribution of
|
||||
|
@ -26,6 +26,7 @@ LDFLAGS := -pthread
|
|||
INCLUDES :=
|
||||
LIBS :=
|
||||
OBJS :=
|
||||
OBJS_TEST :=
|
||||
PROF :=
|
||||
|
||||
MODULES :=
|
||||
|
@ -47,28 +48,53 @@ else
|
|||
CFLAGS:= -O2
|
||||
endif
|
||||
|
||||
ifndef CXXFLAGS_TEST
|
||||
CXXFLAGS_TEST := $(CXXFLAGS)
|
||||
endif
|
||||
|
||||
ifndef CFLAGS_TEST
|
||||
CFLAGS_TEST := $(CFLAGS)
|
||||
endif
|
||||
|
||||
ifndef LDFLAGS_TEST
|
||||
LDFLAGS_TEST := $(LDFLAGS)
|
||||
endif
|
||||
|
||||
CXXFLAGS+= -Wall -Wextra -Wno-unused-parameter
|
||||
CFLAGS+= -Wall -Wextra -Wno-unused-parameter
|
||||
|
||||
CXXFLAGS_TEST+= -Wall -Wextra -Wno-unused-parameter
|
||||
CFLAGS_TEST+= -Wall -Wextra -Wno-unused-parameter
|
||||
|
||||
ifdef HAVE_GCC
|
||||
CXXFLAGS+= -Wno-multichar -Wunused -Woverloaded-virtual -Wnon-virtual-dtor -std=c++17
|
||||
CFLAGS+= -Wno-multichar -Wunused
|
||||
CXXFLAGS+= -Wno-multichar -Wunused -Woverloaded-virtual -std=c++20
|
||||
CFLAGS+= -Wunused
|
||||
|
||||
CXXFLAGS_TEST+= -Wno-multichar -Wunused -Woverloaded-virtual -std=c++20
|
||||
CFLAGS_TEST+= -Wno-multichar -Wunused
|
||||
endif
|
||||
|
||||
ifdef HAVE_CLANG
|
||||
CXXFLAGS+= -Wno-multichar -Wunused -Woverloaded-virtual -Wnon-virtual-dtor -std=c++17
|
||||
CFLAGS+= -Wno-multichar -Wunused
|
||||
CXXFLAGS+= -Wunused -Woverloaded-virtual -std=c++20
|
||||
CFLAGS+= -Wunused
|
||||
|
||||
CXXFLAGS_TEST+= -Wno-multichar -Wunused -Woverloaded-virtual -std=c++20
|
||||
CFLAGS_TEST+= -Wno-multichar -Wunused
|
||||
endif
|
||||
|
||||
ifdef CLANG_WARNINGS
|
||||
EXTRA_WARN=-Weverything -Wno-c++17-extensions -Wno-c++98-compat-pedantic \
|
||||
EXTRA_WARN=-Wno-c++98-compat-pedantic -Wno-undefined-func-template \
|
||||
-Wno-switch-enum -Wno-conversion -Wno-covered-switch-default \
|
||||
-Wno-inconsistent-missing-destructor-override -Wno-float-equal \
|
||||
-Wno-documentation -Wno-float-equal \
|
||||
-Wno-exit-time-destructors -Wno-global-constructors -Wno-weak-vtables \
|
||||
-Wno-four-char-constants -Wno-padded
|
||||
-Wno-four-char-constants -Wno-padded -Wno-reserved-identifier \
|
||||
-Wno-duplicate-enum -Wno-unsafe-buffer-usage
|
||||
|
||||
CXXFLAGS+= $(EXTRA_WARN)
|
||||
CFLAGS+= $(EXTRA_WARN)
|
||||
|
||||
CXXFLAGS_TEST+= $(EXTRA_WARN)
|
||||
CFLAGS_TEST+= $(EXTRA_WARN)
|
||||
endif
|
||||
|
||||
ifdef PROFILE
|
||||
|
@ -78,8 +104,8 @@ ifdef PROFILE
|
|||
endif
|
||||
|
||||
ifdef DEBUG
|
||||
CXXFLAGS += -g
|
||||
CFLAGS += -g
|
||||
CXXFLAGS += -g -Wp,-D_GLIBCXX_DEBUG
|
||||
CFLAGS += -g -Wp,-D_GLIBCXX_DEBUG
|
||||
else
|
||||
ifdef HAVE_GCC
|
||||
CXXFLAGS+= -fomit-frame-pointer
|
||||
|
@ -107,12 +133,14 @@ ifdef STELLA_BUILD_ROOT
|
|||
else
|
||||
OBJECT_ROOT := out
|
||||
endif
|
||||
OBJECT_ROOT_TEST := out.test
|
||||
OBJECT_ROOT_PROFILE_GENERERATE := out.pgen
|
||||
OBJECT_ROOT_PROFILE_USE := out.pgo
|
||||
|
||||
EXECUTABLE := stella$(EXEEXT)
|
||||
EXECUTABLE_PROFILE_GENERATE := stella-pgo-generate$(EXEEXT)
|
||||
EXECUTABLE_PROFILE_USE := stella-pgo$(EXEEXT)
|
||||
EXECUTABLE_TEST := stella-test$(EXEEXT)
|
||||
|
||||
PROFILE_DIR = $(CURDIR)/test/roms/profile
|
||||
PROFILE_OUT = $(PROFILE_DIR)/out
|
||||
|
@ -145,14 +173,17 @@ ifdef HAVE_GCC
|
|||
CFLAGS_PROFILE_USE += -fprofile-use -fprofile-dir=$(PROFILE_OUT)
|
||||
LDFLAGS_PROFILE_GENERATE += -fprofile-generate
|
||||
STELLA_PROFILE_GENERATE := $(STELLA_PROFILE_GENERATE) && \
|
||||
rm -fr $(PROFILE_OUT)/$(OBJECT_ROOT_PROFILE_USE) && \
|
||||
mv $(PROFILE_OUT)/$(OBJECT_ROOT_PROFILE_GENERERATE) $(PROFILE_OUT)/$(OBJECT_ROOT_PROFILE_USE)
|
||||
(rm -fr $(PROFILE_OUT)/$(OBJECT_ROOT_PROFILE_USE) || true) && \
|
||||
(mv $(PROFILE_OUT)/$(OBJECT_ROOT_PROFILE_GENERERATE) $(PROFILE_OUT)/$(OBJECT_ROOT_PROFILE_USE) || true)
|
||||
endif
|
||||
|
||||
all: $(EXECUTABLE)
|
||||
|
||||
pgo: $(EXECUTABLE_PROFILE_USE)
|
||||
|
||||
test: $(EXECUTABLE_TEST)
|
||||
./$(EXECUTABLE_TEST)
|
||||
|
||||
######################################################################
|
||||
# Various minor settings
|
||||
######################################################################
|
||||
|
@ -175,8 +206,8 @@ MODULES += \
|
|||
src/emucore \
|
||||
src/emucore/tia \
|
||||
src/emucore/tia/frame-manager \
|
||||
src/common/repository/sqlite \
|
||||
src/sqlite
|
||||
src/emucore/elf \
|
||||
src/common/repository/sqlite
|
||||
|
||||
######################################################################
|
||||
# The build rules follow - normally you should have no need to
|
||||
|
@ -194,6 +225,7 @@ DEPDIRS = $(addsuffix /$(DEPDIR),$(MODULE_DIRS))
|
|||
DEPFILES =
|
||||
|
||||
OBJ=$(addprefix $(OBJECT_ROOT)/,$(OBJS))
|
||||
OBJ_TEST=$(addprefix $(OBJECT_ROOT_TEST)/,$(OBJS_TEST))
|
||||
OBJ_PROFILE_GENERATE=$(addprefix $(OBJECT_ROOT_PROFILE_GENERERATE)/,$(OBJS))
|
||||
OBJ_PROFILE_USE=$(addprefix $(OBJECT_ROOT_PROFILE_USE)/,$(OBJS))
|
||||
|
||||
|
@ -201,6 +233,9 @@ OBJ_PROFILE_USE=$(addprefix $(OBJECT_ROOT_PROFILE_USE)/,$(OBJS))
|
|||
$(EXECUTABLE): $(OBJ)
|
||||
$(LD) $(LDFLAGS) $(PRE_OBJS_FLAGS) $+ $(POST_OBJS_FLAGS) $(LIBS) $(PROF) -o $@
|
||||
|
||||
$(EXECUTABLE_TEST): $(OBJ_TEST)
|
||||
$(LD) $(LDFLAGS_TEST) $(PRE_OBJS_FLAGS) $+ $(POST_OBJS_FLAGS) $(LIBS) -lgtest -lgtest_main -o $@
|
||||
|
||||
$(EXECUTABLE_PROFILE_GENERATE): $(OBJ_PROFILE_GENERATE)
|
||||
$(LD) $(LDFLAGS_PROFILE_GENERATE) $(PRE_OBJS_FLAGS) $+ $(POST_OBJS_FLAGS) $(LIBS) $(PROF) -o $@
|
||||
|
||||
|
@ -215,7 +250,7 @@ clean:
|
|||
-$(RM) -fr \
|
||||
$(OBJECT_ROOT) $(OBJECT_ROOT_PROFILE_GENERERATE) $(OBJECT_ROOT_PROFILE_USE) \
|
||||
$(EXECUTABLE) $(EXECUTABLE_PROFILE_GENERATE) $(EXECUTABLE_PROFILE_USE) \
|
||||
$(PROFILE_OUT) $(PROFILE_STAMP)
|
||||
$(OBJECT_ROOT_TEST) $(PROFILE_OUT) $(PROFILE_STAMP)
|
||||
|
||||
.PHONY: all clean dist distclean
|
||||
|
||||
|
@ -243,6 +278,16 @@ $(OBJECT_ROOT)/%.o: %.cxx
|
|||
$(merge_dep)
|
||||
|
||||
$(OBJECT_ROOT)/%.o: %.c
|
||||
$(create_dir)
|
||||
$(CC) $(CXX_UPDATE_DEP_FLAG) $(CFLAGS_TEST) $(CPPFLAGS) -c $(<) -o $@
|
||||
$(merge_dep)
|
||||
|
||||
$(OBJECT_ROOT_TEST)/%.o: %.cxx
|
||||
$(create_dir)
|
||||
$(CXX) $(CXX_UPDATE_DEP_FLAG) $(CXXFLAGS_TEST) $(CPPFLAGS) -c $(<) -o $@
|
||||
$(merge_dep)
|
||||
|
||||
$(OBJECT_ROOT_TEST)/%.o: %.c
|
||||
$(create_dir)
|
||||
$(CC) $(CXX_UPDATE_DEP_FLAG) $(CFLAGS) $(CPPFLAGS) -c $(<) -o $@
|
||||
$(merge_dep)
|
||||
|
@ -280,6 +325,14 @@ $(OBJECT_ROOT)/%.o: %.c
|
|||
$(create_dir)
|
||||
$(CC) $(CXX_UPDATE_DEP_FLAG) $(CFLAGS) $(CPPFLAGS) -c $(<) -o $@
|
||||
|
||||
$(OBJECT_ROOT_TEST)/%.o: %.cxx
|
||||
$(create_dir)
|
||||
$(CXX) $(CXX_UPDATE_DEP_FLAG) $(CXXFLAGS_TEST) $(CPPFLAGS) -c $(<) -o $@
|
||||
|
||||
$(OBJECT_ROOT_TEST)/%.o: %.c
|
||||
$(create_dir)
|
||||
$(CC) $(CXX_UPDATE_DEP_FLAG) $(CFLAGS_TEST) $(CPPFLAGS) -c $(<) -o $@
|
||||
|
||||
$(OBJECT_ROOT_PROFILE_GENERERATE)/%.o: %.cxx
|
||||
$(create_dir)
|
||||
$(CXX) $(CXX_UPDATE_DEP_FLAG) $(CXXFLAGS_PROFILE_GENERATE) $(CPPFLAGS) -c $(<) -o $@
|
||||
|
@ -317,11 +370,11 @@ install: all
|
|||
$(INSTALL) -d "$(DESTDIR)$(BINDIR)"
|
||||
$(INSTALL) -c -m 755 "$(srcdir)/stella$(EXEEXT)" "$(DESTDIR)$(BINDIR)/stella$(EXEEXT)"
|
||||
$(INSTALL) -d "$(DESTDIR)$(DOCDIR)"
|
||||
$(INSTALL) -c -m 644 "$(srcdir)/Announce.txt" "$(srcdir)/Changes.txt" "$(srcdir)/Copyright.txt" "$(srcdir)/License.txt" "$(srcdir)/README-SDL.txt" "$(srcdir)/Readme.txt" "$(srcdir)/Todo.txt" "$(srcdir)/docs/index.html" "$(srcdir)/docs/debugger.html" "$(DESTDIR)$(DOCDIR)/"
|
||||
$(INSTALL) -c -m 644 "$(srcdir)/Announce.txt" "$(srcdir)/Changes.txt" "$(srcdir)/Copyright.txt" "$(srcdir)/License.txt" "$(srcdir)/README-SDL.txt" "$(srcdir)/README.md" "$(srcdir)/Todo.txt" "$(srcdir)/docs/index.html" "$(srcdir)/docs/debugger.html" "$(DESTDIR)$(DOCDIR)/"
|
||||
$(INSTALL) -d "$(DESTDIR)$(DOCDIR)/graphics"
|
||||
$(INSTALL) -c -m 644 $(wildcard $(srcdir)/docs/graphics/*.png) "$(DESTDIR)$(DOCDIR)/graphics"
|
||||
$(INSTALL) -d "$(DESTDIR)$(DATADIR)/applications"
|
||||
$(INSTALL) -c -m 644 "$(srcdir)/src/unix/stella.desktop" "$(DESTDIR)$(DATADIR)/applications"
|
||||
$(INSTALL) -c -m 644 "$(srcdir)/src/os/unix/stella.desktop" "$(DESTDIR)$(DATADIR)/applications"
|
||||
$(INSTALL) -d "$(DESTDIR)$(DATADIR)/icons/hicolor/16x16/apps"
|
||||
$(INSTALL) -d "$(DESTDIR)$(DATADIR)/icons/hicolor/22x22/apps"
|
||||
$(INSTALL) -d "$(DESTDIR)$(DATADIR)/icons/hicolor/24x24/apps"
|
||||
|
@ -357,7 +410,7 @@ src/emucore/M6502.ins: src/emucore/M6502.m4
|
|||
m4 src/emucore/M6502.m4 > src/emucore/M6502.ins
|
||||
|
||||
# Special rule for windows icon stuff (there's probably a better way to do this ...)
|
||||
src/windows/stella_icon.o: src/windows/stella.ico src/windows/stella.rc
|
||||
windres --include-dir src/windows src/windows/stella.rc src/windows/stella_icon.o
|
||||
src/os/windows/stella_icon.o: src/os/windows/stella.ico src/os/windows/stella.rc
|
||||
windres --include-dir src/os/windows src/os/windows/stella.rc src/os/windows/stella_icon.o
|
||||
|
||||
.PHONY: deb bundle test install uninstall
|
||||
|
|
|
@ -15,6 +15,10 @@ Please check the list of known issues first (see below) before reporting new one
|
|||
If you encounter any issues, please open a new issue on the project
|
||||
[issue tracker](https://github.com/stella-emu/stella/issues).
|
||||
|
||||
Note: Please do **not** report issues regarding platforms other than PC and RetroN 77
|
||||
(e.g. Libretro) here. The Stella Team is not responsible for these forks and cannot
|
||||
help with them.
|
||||
|
||||
# Known issues
|
||||
|
||||
Please check out the [issue tracker](https://github.com/stella-emu/stella/issues) for
|
||||
|
|
10
Readme.txt
|
@ -1,10 +0,0 @@
|
|||
Stella is a multi-platform Atari 2600 VCS emulator which allows you to
|
||||
play all of your favourite Atari 2600 games on your PC. You'll find the
|
||||
Stella Users Manual in the docs subdirectory. If you'd like to verify
|
||||
that you have the latest release of Stella, visit the Stella Website at:
|
||||
|
||||
https://stella-emu.github.io
|
||||
|
||||
Enjoy,
|
||||
|
||||
The Stella Team
|
32
appveyor.yml
|
@ -1,32 +0,0 @@
|
|||
image: Visual Studio 2019
|
||||
|
||||
shallow_clone: true
|
||||
|
||||
|
||||
environment:
|
||||
matrix:
|
||||
- Platform: x64
|
||||
- Platform: Win32
|
||||
|
||||
Configuration: Release
|
||||
|
||||
SDL2_version: 2.0.12
|
||||
|
||||
|
||||
install:
|
||||
- cmd: |
|
||||
curl -o "C:\SDL2-devel.zip" "https://www.libsdl.org/release/SDL2-devel-%SDL2_version%-VC.zip"
|
||||
7z x "C:\SDL2-devel.zip" -o"C:\"
|
||||
xcopy /S "C:\SDL2-%SDL2_version%\include" src\common
|
||||
|
||||
if %Platform%==x64 xcopy /S "C:\SDL2-%SDL2_version%\lib\x64" src\windows
|
||||
if %Platform%==Win32 xcopy /S "C:\SDL2-%SDL2_version%\lib\x86" src\windows
|
||||
|
||||
|
||||
build_script:
|
||||
- cmd: |
|
||||
msbuild src\windows\Stella.sln
|
||||
|
||||
|
||||
artifacts:
|
||||
- path: '**\stella.exe'
|
|
@ -4,7 +4,9 @@
|
|||
# contains the module name, a trick we use so we can keep multiple different
|
||||
# module object lists, one for each module.
|
||||
MODULE_OBJS-$(MODULE) := $(MODULE_OBJS)
|
||||
MODULE_TEST_OBJS-$(MODULE) := $(MODULE_TEST_OBJS)
|
||||
|
||||
# If not building as a plugin, add the object files to the main OBJS list
|
||||
#OBJS += $(MODULE_LIB-$(MODULE))
|
||||
OBJS += $(MODULE_OBJS)
|
||||
OBJS_TEST += $(MODULE_TEST_OBJS)
|
||||
|
|
|
@ -13,6 +13,16 @@
|
|||
# use environment vars if set
|
||||
CXXFLAGS="$CXXFLAGS $CPPFLAGS"
|
||||
|
||||
if test -n "$CXXFLAGS_TEST"; then
|
||||
CXXFLAGS_TEST="$CXXFLAGS_TEST $CPPFLAGS"
|
||||
else
|
||||
CXXFLAGS_TEST="$CXXFLAGS"
|
||||
fi
|
||||
|
||||
if test -z "$LDFLAGS_TEST"; then
|
||||
LDFLAGS_TEST="$LDFLAGS"
|
||||
fi
|
||||
|
||||
# default option behaviour yes/no
|
||||
_build_gui=yes
|
||||
_build_windowed=yes
|
||||
|
@ -20,18 +30,22 @@ _build_sound=yes
|
|||
_build_debugger=yes
|
||||
_build_joystick=yes
|
||||
_build_cheats=yes
|
||||
_build_httplib=yes
|
||||
_build_png=yes
|
||||
_build_sqlite3=yes
|
||||
_build_zip=yes
|
||||
_build_static=no
|
||||
_build_profile=no
|
||||
_build_debug=no
|
||||
_build_release=no
|
||||
_build_mold=no
|
||||
|
||||
# more defaults
|
||||
_ranlib=ranlib
|
||||
_install=install
|
||||
_ar="ar cru"
|
||||
_strip=strip
|
||||
_pkg_config=pkg-config
|
||||
_mkdir="mkdir -p"
|
||||
_echo=printf
|
||||
_cat=cat
|
||||
|
@ -214,11 +228,15 @@ Optional Features:
|
|||
--disable-profile
|
||||
--enable-debug build with debugging symbols [disabled]
|
||||
--disable-debug
|
||||
--enable-release build with all optimizations, for final release [disabled]
|
||||
--disable-release
|
||||
--use-mold-linker use mold linker (experimental) [disabled]
|
||||
|
||||
Optional Libraries:
|
||||
--with-sdl-prefix=DIR Prefix where the sdl2-config script is installed (optional)
|
||||
--with-libpng-prefix=DIR Prefix where libpng is installed (optional)
|
||||
--with-zlib-prefix=DIR Prefix where zlib is installed (optional)
|
||||
--with-gtest-prefix=DIR Prefix where googletest is installed (optional)
|
||||
|
||||
Some influential environment variables:
|
||||
LDFLAGS linker flags, e.g. -L<lib dir> if you have libraries in a
|
||||
|
@ -227,6 +245,8 @@ Some influential environment variables:
|
|||
CXXFLAGS C++ compiler flags
|
||||
CPPFLAGS C++ preprocessor flags, e.g. -I<include dir> if you have
|
||||
headers in a nonstandard directory <include dir>
|
||||
LDFLAGS_TEST linker flags for unit tests
|
||||
CXXFLAGS_TEST C++ compiler flags for unit tests
|
||||
|
||||
EOF
|
||||
exit 0
|
||||
|
@ -260,6 +280,7 @@ for ac_option in $@; do
|
|||
--disable-debug) _build_debug=no ;;
|
||||
--enable-release) _build_release=yes ;;
|
||||
--disable-release) _build_release=no ;;
|
||||
--use-mold-linker) _build_mold=yes ;;
|
||||
--with-sdl-prefix=*)
|
||||
arg=`echo $ac_option | cut -d '=' -f 2`
|
||||
_sdlpath="$arg:$arg/bin"
|
||||
|
@ -273,6 +294,11 @@ for ac_option in $@; do
|
|||
_prefix=`echo $ac_option | cut -d '=' -f 2`
|
||||
ZLIB_CFLAGS="-I$_prefix/include"
|
||||
ZLIB_LIBS="-L$_prefix/lib"
|
||||
;;
|
||||
--with-gtest-prefix=*)
|
||||
_prefix=`echo $ac_option | cut -d '=' -f 2`
|
||||
CXXFLAGS_TEST="$CXXFLAGS_TEST -I$_prefix/include"
|
||||
LDFLAGS_TEST="$LDFLAGS_TEST -L$_prefix/lib"
|
||||
;;
|
||||
--host=*)
|
||||
_host=`echo $ac_option | cut -d '=' -f 2`
|
||||
|
@ -318,12 +344,17 @@ mingw32-cross)
|
|||
_host_cpu=i386
|
||||
_host_prefix=i386-mingw32msvc
|
||||
;;
|
||||
*)
|
||||
"")
|
||||
guessed_host=`$_srcdir/config.guess`
|
||||
_host_cpu=`echo $guessed_host | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\1/'`
|
||||
_host_os=`echo $guessed_host | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\3/'`
|
||||
_host_vendor=`echo $guessed_host | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\2/'`
|
||||
;;
|
||||
*)
|
||||
_host_cpu=`echo "$_host" | sed 's/^\([^-]*\)-.*/\1/'`
|
||||
_host_os=`echo "$_host" | sed 's/-\([^-]*\)-[^-]*$/\1/'`
|
||||
_host_prefix="$_host"
|
||||
;;
|
||||
esac
|
||||
|
||||
#
|
||||
|
@ -339,9 +370,6 @@ arm-riscos-aof)
|
|||
psp)
|
||||
EXEEXT=".elf"
|
||||
;;
|
||||
gp2x)
|
||||
EXEEXT=""
|
||||
;;
|
||||
*)
|
||||
EXEEXT=""
|
||||
;;
|
||||
|
@ -374,7 +402,7 @@ else
|
|||
fi
|
||||
|
||||
for compiler in $compilers; do
|
||||
if test_compiler "$compiler -std=c++17"; then
|
||||
if test_compiler "$compiler -std=c++20"; then
|
||||
CXX=$compiler
|
||||
echo $CXX
|
||||
break
|
||||
|
@ -537,6 +565,7 @@ if test -n "$_host"; then
|
|||
_build_windowed=no
|
||||
_build_debugger=no
|
||||
_build_cheats=no
|
||||
_build_httplib=no
|
||||
;;
|
||||
mingw32-cross)
|
||||
echo "Cross-compiling for Windows using MinGW."
|
||||
|
@ -603,6 +632,9 @@ fi
|
|||
# Cross-compilers use their own commands for the following functions
|
||||
if test -n "$_host_prefix"; then
|
||||
_strip="$_host_prefix-$_strip"
|
||||
if command -v "$_host_prefix-$_pkg_config" >/dev/null 2>&1; then
|
||||
_pkg_config="$_host_prefix-$_pkg_config"
|
||||
fi
|
||||
fi
|
||||
|
||||
#
|
||||
|
@ -616,7 +648,7 @@ if test "$_build_zip" = yes ; then
|
|||
#include <zlib.h>
|
||||
int main(void) { return strcmp(ZLIB_VERSION, zlibVersion()); }
|
||||
EOF
|
||||
cc_check $LDFLAGS $CXXFLAGS $ZLIB_CFLAGS $ZLIB_LIBS -lz && _zlib=yes
|
||||
cc_check $LDFLAGS $CXXFLAGS $ZLIB_CFLAGS $ZLIB_LIBS `$_pkg_config --libs zlib` && _zlib=yes
|
||||
|
||||
if test "$_zlib" = yes ; then
|
||||
echo "$_zlib"
|
||||
|
@ -642,7 +674,7 @@ if test "$_build_png" = yes ; then
|
|||
#include <png.h>
|
||||
int main(void) { return printf("%s\n", PNG_HEADER_VERSION_STRING); }
|
||||
EOF
|
||||
cc_check $LDFLAGS $CXXFLAGS $LIBPNG_CFLAGS $LIBPNG_LIBS `pkg-config --libs libpng` && _libpng=yes
|
||||
cc_check $LDFLAGS $CXXFLAGS $LIBPNG_CFLAGS $LIBPNG_LIBS `$_pkg_config --libs libpng` && _libpng=yes
|
||||
|
||||
if test "$_libpng" = yes ; then
|
||||
echo "$_libpng"
|
||||
|
@ -655,6 +687,30 @@ else
|
|||
_build_png=no
|
||||
fi
|
||||
|
||||
#
|
||||
# Check for sqlite3
|
||||
#
|
||||
echocheck "libsqlite3"
|
||||
if test "$_build_sqlite3" = yes ; then
|
||||
_libsqlite3=no
|
||||
cat > $TMPC << EOF
|
||||
#include <stdio.h>
|
||||
#include <sqlite3.h>
|
||||
int main(void) { return printf("%s\n", SQLITE_VERSION); }
|
||||
EOF
|
||||
cc_check $LDFLAGS $CXXFLAGS `$_pkg_config --libs sqlite3` && _libsqlite3=yes
|
||||
|
||||
if test "$_libsqlite3" = yes ; then
|
||||
echo "$_libsqlite3"
|
||||
else
|
||||
echo "built-in"
|
||||
_build_sqlite3=yes
|
||||
fi
|
||||
else
|
||||
echo "built-in"
|
||||
_build_sqlite3=yes
|
||||
fi
|
||||
|
||||
#
|
||||
# figure out installation directories
|
||||
#
|
||||
|
@ -765,23 +821,29 @@ echo
|
|||
find_sdlconfig
|
||||
|
||||
SRC="src"
|
||||
SRC_OS="$SRC/os"
|
||||
SRC_LIB="$SRC/lib"
|
||||
CORE="$SRC/emucore"
|
||||
COMMON="$SRC/common"
|
||||
TIA="$SRC/emucore/tia"
|
||||
ELF="$SRC/emucore/elf"
|
||||
TIA_FRAME_MANAGER="$SRC/emucore/tia/frame-manager"
|
||||
TV="$SRC/common/tv_filters"
|
||||
GUI="$SRC/gui"
|
||||
DBG="$SRC/debugger"
|
||||
DBGGUI="$SRC/debugger/gui"
|
||||
YACC="$SRC/yacc"
|
||||
YACC="$SRC/debugger/yacc"
|
||||
CHEAT="$SRC/cheat"
|
||||
LIBPNG="$SRC/libpng"
|
||||
ZLIB="$SRC/zlib"
|
||||
LIBPNG="$SRC_LIB/libpng"
|
||||
LIBJPG="$SRC_LIB/nanojpeg"
|
||||
LIBJPGEXIF="$SRC_LIB/tinyexif"
|
||||
ZLIB="$SRC_LIB/zlib"
|
||||
SQLITE_REPO="$SRC/common/repository/sqlite"
|
||||
SQLITE_LIB="$SRC/sqlite"
|
||||
JSON="$SRC/json"
|
||||
SQLITE_LIB="$SRC_LIB/sqlite"
|
||||
JSON="$SRC_LIB/json"
|
||||
HTTP_LIB="$SRC_LIB/httplib"
|
||||
|
||||
INCLUDES="-I$CORE -I$COMMON -I$TV -I$TIA -I$TIA_FRAME_MANAGER -I$JSON -I$SQLITE_REPO -I$SQLITE_LIB"
|
||||
INCLUDES="-I$CORE -I$COMMON -I$TV -I$TIA -I$TIA_FRAME_MANAGER -I$ELF -I$JSON -I$SQLITE_REPO"
|
||||
|
||||
INCLUDES="$INCLUDES `$_sdlconfig --cflags`"
|
||||
if test "$_build_static" = yes ; then
|
||||
|
@ -797,26 +859,30 @@ LD=$CXX
|
|||
case $_host_os in
|
||||
unix)
|
||||
DEFINES="$DEFINES -DBSPF_UNIX"
|
||||
MODULES="$MODULES $SRC/unix"
|
||||
INCLUDES="$INCLUDES -I$SRC/unix"
|
||||
MODULES="$MODULES $SRC_OS/unix"
|
||||
INCLUDES="$INCLUDES -I$SRC_OS/unix"
|
||||
;;
|
||||
darwin)
|
||||
DEFINES="$DEFINES -DBSPF_UNIX -DMACOS_KEYS"
|
||||
MODULES="$MODULES $SRC/unix"
|
||||
INCLUDES="$INCLUDES -I$SRC/unix"
|
||||
MODULES="$MODULES $SRC_OS/unix"
|
||||
INCLUDES="$INCLUDES -I$SRC_OS/unix"
|
||||
if test "$have_clang" == yes; then
|
||||
CXXFLAGS="$CXXFLAGS -Wno-poison-system-directories"
|
||||
if test -n "$CXXFLAGS_TEST"; then
|
||||
CXXFLAGS_TEST="$CXXFLAGS_TEST -Wno-poison-system-directories"
|
||||
fi
|
||||
fi
|
||||
_libsqlite3=no
|
||||
;;
|
||||
retron77)
|
||||
DEFINES="$DEFINES -DBSPF_UNIX -DRETRON77"
|
||||
MODULES="$MODULES $SRC/unix $SRC/unix/r77"
|
||||
INCLUDES="$INCLUDES -I$SRC/unix -I$SRC/unix/r77"
|
||||
MODULES="$MODULES $SRC_OS/unix $SRC_OS/unix/r77"
|
||||
INCLUDES="$INCLUDES -I$SRC_OS/unix -I$SRC_OS/unix/r77"
|
||||
;;
|
||||
win32)
|
||||
DEFINES="$DEFINES -DBSPF_WINDOWS"
|
||||
MODULES="$MODULES $SRC/windows"
|
||||
INCLUDES="$INCLUDES -I$SRC/windows"
|
||||
MODULES="$MODULES $SRC_OS/windows"
|
||||
INCLUDES="$INCLUDES -I$SRC_OS/windows"
|
||||
LIBS="$LIBS -lmingw32 -lwinmm"
|
||||
;;
|
||||
*)
|
||||
|
@ -855,20 +921,34 @@ if test "$_build_cheats" = yes ; then
|
|||
INCLUDES="$INCLUDES -I$CHEAT"
|
||||
fi
|
||||
|
||||
if test "$_build_httplib" = yes ; then
|
||||
DEFINES="$DEFINES -DHTTP_LIB_SUPPORT"
|
||||
INCLUDES="$INCLUDES -I$HTTP_LIB"
|
||||
fi
|
||||
|
||||
if test "$_build_png" = yes ; then
|
||||
DEFINES="$DEFINES -DPNG_SUPPORT"
|
||||
DEFINES="$DEFINES -DIMAGE_SUPPORT"
|
||||
INCLUDES="$INCLUDES -I$LIBJPG -I$LIBJPGEXIF"
|
||||
MODULES="$MODULES $LIBJPGEXIF"
|
||||
if test "$_libpng" = yes ; then
|
||||
LIBS="$LIBS -lpng"
|
||||
LIBS="$LIBS `$_pkg_config --libs libpng`"
|
||||
else
|
||||
MODULES="$MODULES $LIBPNG"
|
||||
INCLUDES="$INCLUDES -I$LIBPNG"
|
||||
fi
|
||||
fi
|
||||
|
||||
if test "$_libsqlite3" = yes ; then
|
||||
LIBS="$LIBS `$_pkg_config --libs sqlite3`"
|
||||
else
|
||||
MODULES="$MODULES $SQLITE_LIB"
|
||||
INCLUDES="$INCLUDES -I$SQLITE_LIB"
|
||||
fi
|
||||
|
||||
if test "$_build_zip" = yes ; then
|
||||
DEFINES="$DEFINES -DZIP_SUPPORT"
|
||||
if test "$_zlib" = yes ; then
|
||||
LIBS="$LIBS -lz"
|
||||
LIBS="$LIBS `$_pkg_config --libs zlib`"
|
||||
else
|
||||
MODULES="$MODULES $ZLIB"
|
||||
INCLUDES="$INCLUDES -I$ZLIB"
|
||||
|
@ -887,12 +967,24 @@ if test "$_build_release" = no ; then
|
|||
_build_release=
|
||||
fi
|
||||
|
||||
if test "$_build_mold" = yes ; then
|
||||
LDFLAGS="-fuse-ld=mold"
|
||||
fi
|
||||
|
||||
# Workaround until we deal with autodetection of C compiler properly
|
||||
# Or we remove C files from Stella entirely, by making them C++
|
||||
if test -z "$CC"; then
|
||||
CC=cc
|
||||
fi
|
||||
|
||||
echo "Creating config.mak"
|
||||
cat > config.mak << EOF
|
||||
# -------- Generated by configure -----------
|
||||
|
||||
CC := $CC
|
||||
CXX := $CXX
|
||||
CXXFLAGS := $CXXFLAGS
|
||||
CXXFLAGS_TEST := $CXXFLAGS_TEST
|
||||
LD := $LD
|
||||
LIBS += $LIBS
|
||||
RANLIB := $_ranlib
|
||||
|
@ -930,6 +1022,7 @@ INCLUDES += $INCLUDES
|
|||
OBJS += $OBJS
|
||||
DEFINES += $DEFINES
|
||||
LDFLAGS += $LDFLAGS
|
||||
LDFLAGS_TEST += $LDFLAGS_TEST
|
||||
$_config_mk_data
|
||||
EOF
|
||||
|
||||
|
|
|
@ -1,3 +1,31 @@
|
|||
stella (7.0) stable; urgency=high
|
||||
|
||||
* Version 7.0 release
|
||||
|
||||
-- Stephen Anthony <sa666666@gmail.com> Sat, 5 Oct 2024 17:09:59 -0230
|
||||
|
||||
|
||||
stella (6.7) stable; urgency=high
|
||||
|
||||
* Version 6.7 release
|
||||
|
||||
-- Stephen Anthony <sa666666@gmail.com> Mon, 13 Jun 2022 17:09:59 -0230
|
||||
|
||||
|
||||
stella (6.6) stable; urgency=high
|
||||
|
||||
* Version 6.6 release
|
||||
|
||||
-- Stephen Anthony <sa666666@gmail.com> Tue, 16 Nov 2021 17:09:59 -0230
|
||||
|
||||
|
||||
stella (6.5.3) stable; urgency=high
|
||||
|
||||
* Version 6.5.3 release
|
||||
|
||||
-- Stephen Anthony <sa666666@gmail.com> Tue, 20 Apr 2021 17:09:59 -0230
|
||||
|
||||
|
||||
stella (6.5.2) stable; urgency=high
|
||||
|
||||
* Version 6.5.2 release
|
||||
|
|
|
@ -3,6 +3,7 @@ Maintainer: Stephen Anthony <sa666666@gmail.com>
|
|||
Section: otherosfs
|
||||
Priority: optional
|
||||
Build-Depends: debhelper (>= 10~),
|
||||
libgtest-dev,
|
||||
libpng-dev,
|
||||
libsdl2-dev,
|
||||
zlib1g-dev
|
||||
|
|
|
@ -1,18 +1,18 @@
|
|||
Format: https://www.debian.org/doc/packaging-manuals/copyright-format/1.0
|
||||
Upstream-Name: stella
|
||||
Source: https://stella-emu.github.io
|
||||
Copyright: 1995-2021 Bradford W. Mott, Stephen Anthony and the Stella Team
|
||||
Copyright: 1995-2025 Bradford W. Mott, Stephen Anthony and the Stella Team
|
||||
License: GPL-2+
|
||||
|
||||
Files: *
|
||||
Copyright: 1995-2021 Bradford W. Mott, Stephen Anthony and the Stella
|
||||
Copyright: 1995-2025 Bradford W. Mott, Stephen Anthony and the Stella
|
||||
Team
|
||||
License: GPL-2+
|
||||
|
||||
Files: debian/*
|
||||
Copyright: 1998-2004 Tom Lear <tom@trap.mtview.ca.us>
|
||||
2006 Mario Iseli <admin@marioiseli.com>
|
||||
2010-2021 Stephen Kitt <skitt@debian.org>
|
||||
2010-2025 Stephen Kitt <skitt@debian.org>
|
||||
License: GPL-2+
|
||||
|
||||
Files:
|
||||
|
@ -73,7 +73,7 @@ License: RSA
|
|||
These notices must be retained in any copies of any part of this
|
||||
documentation and/or software.
|
||||
|
||||
Files: src/libpng/*
|
||||
Files: src/lib/libpng/*
|
||||
Copyright: 1995-1996 Guy Eric Schalnat, Group 42, Inc.
|
||||
1996-1997 Andreas Dilger
|
||||
1998-2013 Glenn Randers-Pehrson
|
||||
|
@ -112,7 +112,7 @@ License: libpng
|
|||
risk of satisfactory quality, performance, accuracy, and effort is
|
||||
with the user.
|
||||
|
||||
Files: src/libretro/libretro.h
|
||||
Files: src/os/libretro/libretro.h
|
||||
Copyright: 2010-2017 The RetroArch team
|
||||
License: MIT
|
||||
Permission is hereby granted, free of charge, to any person obtaining
|
||||
|
@ -135,7 +135,7 @@ License: MIT
|
|||
CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
||||
|
||||
Files: src/macos/*
|
||||
Files: src/os/macos/*
|
||||
Copyright: 2005-2006 Mark Grebe
|
||||
License: GPL-2+
|
||||
|
||||
|
@ -164,7 +164,7 @@ License: GPL-2
|
|||
License version 2 can be found in
|
||||
`/usr/share/common-licenses/GPL-2'.
|
||||
|
||||
Files: src/zlib/*
|
||||
Files: src/lib/zlib/*
|
||||
Copyright: 1995-2012, 2016 Jean-loup Gailly and Mark Adler
|
||||
License: zlib
|
||||
This software is provided 'as-is', without any express or implied
|
||||
|
|
|
@ -2,7 +2,7 @@ Announce.txt
|
|||
Changes.txt
|
||||
Copyright.txt
|
||||
README-SDL.txt
|
||||
Readme.txt
|
||||
README.md
|
||||
docs/*.html
|
||||
doc/graphics/*.png
|
||||
docs/graphics/*.png
|
||||
Todo.txt
|
||||
|
|
|
@ -15,7 +15,7 @@
|
|||
<body>
|
||||
|
||||
<center><b><font size="7">Stella</font></b></center>
|
||||
<center><h4><b>Release 6.5.2</b></h4></center>
|
||||
<center><h4><b>Release 7.0</b></h4></center>
|
||||
<center><h1><b>Integrated Debugger</b></h1></center>
|
||||
<center><h4><b>(a work in progress)</b></h4></center>
|
||||
<br>
|
||||
|
@ -45,6 +45,7 @@
|
|||
<li><a href="#PseudoRegisters">Pseudo-Registers</a></li>
|
||||
<li><a href="#Watches">Watches</a></li>
|
||||
<li><a href="#Traps">Traps</a></li>
|
||||
<li><a href="#Timers">Timers</a></li>
|
||||
</ul>
|
||||
</li>
|
||||
<li><a href="#SaveWork">Save your work!</a></li>
|
||||
|
@ -102,10 +103,10 @@ feature that no other 2600 debugger has; it's <b>completely</b> cross-platform.<
|
|||
breakpoints as you want.</li>
|
||||
|
||||
<li>Conditional breakpoints - Break running program when some arbitrary
|
||||
condition is true (e.g. "breakif {a == $7f && c}" will break when the Accumulator value is $7f and the Carry flag is true, no matter where
|
||||
condition is true (e.g. "breakIf {a == $7f && c}" will break when the Accumulator value is $7f and the Carry flag is true, no matter where
|
||||
in the program this happens). Unlike the cond breaks in PCAE, Stella's
|
||||
are *fast*: the emulation will run at full speed unless you use lots
|
||||
of breakif's at the same time, or have a slow CPU.</li>
|
||||
of breakIf's at the same time, or have a slow CPU.</li>
|
||||
|
||||
<li>Watches - View contents of a location/register before every
|
||||
debugger prompt.</li>
|
||||
|
@ -172,7 +173,7 @@ feature that no other 2600 debugger has; it's <b>completely</b> cross-platform.<
|
|||
<li>Data sources for the CPU SP/A/X/Y registers, showing the resolved/source
|
||||
address of of load operands.</li>
|
||||
<li>Scanline advance (like frame advance, break at beginning
|
||||
of next scanline).</li>
|
||||
of next scanLine).</li>
|
||||
<li>TIA display is updated during step/trace, so we can see our
|
||||
scanlines being drawn as it happens. This isn't 100% perfect: unlike
|
||||
a real TIA, the one in Stella only updates when it's written to.</li>
|
||||
|
@ -183,7 +184,7 @@ feature that no other 2600 debugger has; it's <b>completely</b> cross-platform.<
|
|||
named after the ROM image.</li>
|
||||
<li>Saving the current debugger state to a script file (including
|
||||
breakpoints, traps, etc).</li>
|
||||
<li>Built-in functions for use with "breakif", to support common conditions
|
||||
<li>Built-in functions for use with "breakIf", to support common conditions
|
||||
(such as breaking when the user presses Game Select...)</li>
|
||||
<li>Patching ROM in-place.</li>
|
||||
<li>Save patched ROM</li>
|
||||
|
@ -251,9 +252,9 @@ command on the command line, or alternatively within the ROM launcher in
|
|||
</p>
|
||||
|
||||
<p>Using the ` key will always enter the debugger at the end of
|
||||
the frame (for NTSC games usually scanline 262). This is because Stella only checks
|
||||
the frame (for NTSC games usually scanLine 262). This is because Stella only checks
|
||||
for keystrokes once per frame. Once in the debugger, you can control
|
||||
execution by stepping one instruction, scanline, or frame at a time
|
||||
execution by stepping one instruction, scanLine, or frame at a time
|
||||
(or more than one at a time, using commands in the prompt). You can
|
||||
also set breakpoints or traps, which will cause the emulator to enter
|
||||
the debugger when they are triggered, even if it happens in mid-frame.</p>
|
||||
|
@ -310,7 +311,7 @@ more convenient.
|
|||
</li>
|
||||
<li>
|
||||
"<rom_filename>.sym" (located in the same directory as the ROM)</br>
|
||||
If you provied the -l and -s parameters DASM will create these two files during
|
||||
If you provide the -l and -s parameters DASM will create these two files during
|
||||
assembly. Stella uses the file content to display the correct labels.
|
||||
</li>
|
||||
</ul>
|
||||
|
@ -345,56 +346,57 @@ size can be configured e.g. in the
|
|||
<p>
|
||||
<table BORDER=1 cellpadding=4>
|
||||
<tr>
|
||||
<th>Key</th>
|
||||
<th>Function</th>
|
||||
<th>Key</th>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>Step ¹</td>
|
||||
<td>Control + S</td>
|
||||
<td>Step</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>Trace ¹</td>
|
||||
<td>Control + T</td>
|
||||
<td>Trace</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>Scan +1 ¹</td>
|
||||
<td>Control + L</td>
|
||||
<td>Scan +1</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>Frame +1 ¹</td>
|
||||
<td>Control + F</td>
|
||||
<td>Frame +1</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>Alt + Left arrow</td>
|
||||
<td>Rewind 1</td>
|
||||
<td>Alt + Left arrow</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>Shift-Alt + Left arrow</td>
|
||||
<td>Rewind 10</td>
|
||||
<td>Shift-Alt + Left arrow</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>Alt + Down arrow</td>
|
||||
<td>Rewind all</td>
|
||||
<td>Alt + Down arrow</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>Alt + Right arrow</td>
|
||||
<td>Unwind 1</td>
|
||||
<td>Alt + Right arrow</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>Shift-Alt + Right arrow</td>
|
||||
<td>Unwind 10</td>
|
||||
<td>Shift-Alt + Right arrow</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>Alt + Up arrow</td>
|
||||
<td>Unwind all</td>
|
||||
<td>Alt + Up arrow</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>Backquote (`)</td>
|
||||
<td>Run, exits debugger</td>
|
||||
<td>Backquote (`), Escape</td>
|
||||
</tr>
|
||||
</table>
|
||||
</p>
|
||||
For MacOS use 'Cmd' instead of 'Alt' key.
|
||||
<p>¹: External I/O input is ignored, the state of the <a href="#IOTab">I/O Tab</a> remains unchanged.</p>
|
||||
<p>To the left of the global buttons, you find the 'Options...' button.</p>
|
||||
<ul>
|
||||
<p><img src="graphics/debugger_options.png"></p>
|
||||
|
@ -408,7 +410,7 @@ in detail in the <a href="index.html">User's Guide</a>.</p>
|
|||
|
||||
<p>The debugger tracks changes to the CPU, TIA and RIOT registers and RAM by
|
||||
displaying changed locations or registers with a red background after each step,
|
||||
trace, scanline, or frame advance. This sounds simple, and it is, but
|
||||
trace, scanLine, or frame advance. This sounds simple, and it is, but
|
||||
it's also amazingly useful.</p>
|
||||
|
||||
<p>One clarification about the change tracking: it only tracks when values
|
||||
|
@ -428,25 +430,28 @@ or Supermon for the C=64.</p>
|
|||
Bash-style commands are also supported:</p>
|
||||
|
||||
<table border="1" cellpadding=4>
|
||||
<tr><th>Key</th><th>Function</th></tr>
|
||||
<tr><td>Home</td><td>Move cursor to beginning of line</td></tr>
|
||||
<tr><td>End</td><td>Move cursor to end of line</td></tr>
|
||||
<tr><td>Delete</td><td>Remove character to right of cursor</td></tr>
|
||||
<tr><td>Backspace</td><td>Remove character to left of cursor</td></tr>
|
||||
<tr><td>Control + A</td><td>Same function as 'Home'</td></tr>
|
||||
<tr><td>Control + E</td><td>Same function as 'End'</td></tr>
|
||||
<tr><td>Control + D</td><td>Same function as 'Delete'</td></tr>
|
||||
<tr><td>Control + K</td><td>Remove all characters from cursor to end of line</td></tr>
|
||||
<tr><td>Control + U</td><td>Remove all characters from cursor to beginning of line</td></tr>
|
||||
<tr><td>Control + W</td><td>Remove entire word to left of cursor</td></tr>
|
||||
<tr><td>Shift + PgUp</td><td>Scroll up through previous commands one screen/page</td></tr>
|
||||
<tr><td>Shift + PgDown</td><td>Scroll down through previous commands one screen/page</td></tr>
|
||||
<tr><td>Shift + Up</td><td>Scroll up through previous commands one line</td></tr>
|
||||
<tr><td>Shift + Down</td><td>Scroll down through previous commands one line</td></tr>
|
||||
<tr><td>Shift + Home</td><td>Scroll to beginning of commands</td></tr>
|
||||
<tr><td>Shift + End</td><td>Scroll to end of commands</td></tr>
|
||||
<tr><th>Function</th><th>Key</th></tr>
|
||||
<tr><td>Move cursor to beginning of line</td><td>Home</td></tr>
|
||||
<tr><td>Move cursor to end of line</td><td>End</td></tr>
|
||||
<tr><td>Remove character to right of cursor</td><td>Delete</td></tr>
|
||||
<tr><td>Remove character to left of cursor</td><td>Backspace</td></tr>
|
||||
<tr><td>Same function as 'Home'</td><td>Control + A</td></tr>
|
||||
<tr><td>Same function as 'End'</td><td>Control + E</td></tr>
|
||||
<tr><td>Same function as 'Delete'</td><td>Control + D</td></tr>
|
||||
<tr><td>Remove all characters from cursor to end of line</td><td>Control + K</td></tr>
|
||||
<tr><td>Remove all characters from cursor to beginning of line</td><td>Control + U</td></tr>
|
||||
<tr><td>Remove entire word to left of cursor</td><td>Control + W</td></tr>
|
||||
<tr><td>Copy current line</td><td>Control + C</td></tr>
|
||||
<tr><td>Cut current line</td><td>Control + X</td></tr>
|
||||
<tr><td>Paste over current line</td><td>Control + V</td></tr>
|
||||
<tr><td>Scroll up through previous commands one screen/page</td><td>Shift + PgUp</td></tr>
|
||||
<tr><td>Scroll down through previous commands one screen/page</td><td>Shift + PgDown</td></tr>
|
||||
<tr><td>Scroll up through previous commands one line</td><td>Shift + Up</td></tr>
|
||||
<tr><td>Scroll down through previous commands one line</td><td>Shift + Down</td></tr>
|
||||
<tr><td>Scroll to beginning of commands</td><td>Shift + Home</td></tr>
|
||||
<tr><td>Scroll to end of commands</td><td>Shift + End</td></tr>
|
||||
</table>
|
||||
<p>You can also scroll with the mouse. Copy and paste is not yet supported.</p>
|
||||
<p>You can also scroll with the mouse. Copy and paste is currently only supported for a complete line.</p>
|
||||
|
||||
<p>To see the available commands, enter "help". For extended help, type "help cmd",
|
||||
where 'cmd' is the command you wish to know about. The available commands are listed
|
||||
|
@ -467,16 +472,16 @@ just by re-running the relevant commands in the prompt.</p>
|
|||
<h3><a name="TabCompletion">Tab Key Auto-Complete</a></h3>
|
||||
|
||||
<p>While entering a command, label or function, you can type a partial name and
|
||||
press the Tab key to attempt to auto-complete it. If you've ever used
|
||||
press the (Shift +) Tab key to attempt to auto-complete it. If you've ever used
|
||||
"bash", this will be immediately familiar. If not, try it: load up
|
||||
a ROM, go to the debugger, type "g" (but don't press Enter),
|
||||
then hit Tab. The "g" will change to "gfx" (since this is the only
|
||||
built-in command starting with a "g"). If there are multiple possible
|
||||
completions (try with "tr" instead of "g"), you'll see a list of them,
|
||||
and your partial name will be completed as far as possible.
|
||||
completions (try with "tr" instead of "g"), you can tab through them.
|
||||
After the first character, the autocompletion considers all
|
||||
characters in the right order as a match (e.g. "twf" will be completed to
|
||||
"trapwriteif").</p>
|
||||
"trapWriteIf"). Alternatively you can make use of the camel case names and type
|
||||
e.g. "tWI" ("trapWriteIf") or "lAS" ("LoadAllStates").</p>
|
||||
|
||||
<p>Tab completion works on all labels: built-in, loaded from a symbol file,
|
||||
or set during debugging with the "define" command. It also works with
|
||||
|
@ -609,7 +614,7 @@ command that takes arguments.</p>
|
|||
<h4><a name="Breakpoints">Breakpoints</a></h4>
|
||||
|
||||
<p>A breakpoint is a "hotspot" in your program that causes the emulator
|
||||
to stop emulating and jump into the debugger. You can set as many
|
||||
to stop emulating and jump into the debugger ¹. You can set as many
|
||||
breakpoints as you like. The command is "break xx yy" where xx is any
|
||||
expression and yy a bank number. Both arguments are optional. If you have
|
||||
created a symbol file, you can use labels for the expression.</p>
|
||||
|
@ -630,8 +635,11 @@ set it. In the example, "break kernel" will remove the breakpoint.
|
|||
The "break" command can be thought of as a *toggle*: it turns the
|
||||
breakpoint on & off, like a light switch.</p>
|
||||
|
||||
<p>You could also use "clearbreaks" to remove all the breakpoints. Also,
|
||||
there is a "listbreaks" command that will list them all.</p>
|
||||
<p>You could also use "clearBreaks" to remove all the breakpoints. Also,
|
||||
there is a "listBreaks" command that will list them all.</p>
|
||||
|
||||
<p>¹ By enabling "logBreaks" you can log the current state into
|
||||
the System Log and continue emulation instead.</p>
|
||||
|
||||
<h4><a name="ConditionalBreaks">Conditional Breaks</a></h4>
|
||||
|
||||
|
@ -661,10 +669,10 @@ is the "!" operator): !(*SWCHB&1). The parentheses are necessary as
|
|||
we want to apply the ! to the result of the &, not just the first term
|
||||
(the "*SWCHB").</p>
|
||||
|
||||
<p>"breakif !(*SWCHB&1)" will do the job for us. However, it's an ugly mess
|
||||
<p>"breakIf !(*SWCHB&1)" will do the job for us. However, it's an ugly mess
|
||||
of letters, numbers, and punctuation. We can do a little better:</p>
|
||||
|
||||
<p>"breakif { !(*SWCHB & 1 ) }" is a lot more readable, isn't it? If
|
||||
<p>"breakIf { !(*SWCHB & 1 ) }" is a lot more readable, isn't it? If
|
||||
you're going to use readable expressions with spaces in them,
|
||||
enclose the entire expression in curly braces.</p>
|
||||
|
||||
|
@ -673,9 +681,9 @@ condition that depends on input (like SWCHB) will always happen at the
|
|||
end of a frame. This is different from how a real 2600 works, but most
|
||||
ROMs only check for input once per frame anyway.</p>
|
||||
|
||||
<p>Conditional breaks appear in "listbreaks", numbered starting from
|
||||
zero. You can remove a cond-break with "delbreakif number", where
|
||||
the number comes from "listbreaks" or by entering the same conditional break again.</p>
|
||||
<p>Conditional breaks appear in "listBreaks", numbered starting from
|
||||
zero. You can remove a cond-break with "delBreakIf number", where
|
||||
the number comes from "listBreaks" or by entering the same conditional break again.</p>
|
||||
|
||||
<p>Any time the debugger is entered due to a trap, breakpoint, or
|
||||
conditional break, the reason will be displayed in the
|
||||
|
@ -684,16 +692,16 @@ conditional break, the reason will be displayed in the
|
|||
<h4><a name="Functions">Functions</a></h4>
|
||||
|
||||
<p>There is one annoyance about complex expressions: once we
|
||||
remove the conditional break with "delbreakif" or "clearbreaks",
|
||||
remove the conditional break with "delBreakIf" or "clearBreaks",
|
||||
we'd have to retype it (or search backwards with the up-arrow key)
|
||||
if we wanted to use it again.</p>
|
||||
|
||||
<p>We can avoid this by defining the expression as a function, then using
|
||||
"breakif function_name":</p>
|
||||
"breakIf function_name":</p>
|
||||
|
||||
<pre>
|
||||
function gameReset { !(*SWCHB & 1 ) }
|
||||
breakif gameReset
|
||||
breakIf gameReset
|
||||
</pre>
|
||||
|
||||
<p>Now we have a meaningful name for the condition, so we can use it again.
|
||||
|
@ -703,16 +711,16 @@ if the Game Select switch is pressed. We want to break when the user
|
|||
presses both Select and Reset:</p>
|
||||
|
||||
<pre>
|
||||
breakif { gameReset && gameSelect }
|
||||
breakIf { gameReset && gameSelect }
|
||||
</pre>
|
||||
|
||||
<p>User-defined functions appear in "listfunctions", which shows the label
|
||||
<p>User-defined functions appear in "listFunctions", which shows the label
|
||||
and expression for each function. Functions can be removed with
|
||||
"delfunction label", where the labels come from "listfunctions".</p>
|
||||
"delFunction label", where the labels come from "listFunctions".</p>
|
||||
|
||||
<h4><a name="BuiltInFunctions">Built-in Functions</a></h4>
|
||||
|
||||
<p>Stella has some pre-defined functions for use with the "breakif"
|
||||
<p>Stella has some pre-defined functions for use with the "breakIf"
|
||||
command. These allow you to break and enter the debugger on various
|
||||
conditions without having to define the conditions yourself.</p>
|
||||
|
||||
|
@ -723,24 +731,24 @@ Stella debugger.</p>
|
|||
|
||||
<table border="1" cellpadding=4>
|
||||
<tr><th>Function</th><th>Definition</th><th>Description</th></tr>
|
||||
<tr><td> _joy0left</td><td> !(*SWCHA & $40)</td><td> Left joystick moved left</td></tr>
|
||||
<tr><td> _joy0right</td><td> !(*SWCHA & $80)</td><td> Left joystick moved right</td></tr>
|
||||
<tr><td> _joy0up</td><td> !(*SWCHA & $10)</td><td> Left joystick moved up</td></tr>
|
||||
<tr><td> _joy0down</td><td> !(*SWCHA & $20)</td><td> Left joystick moved down</td></tr>
|
||||
<tr><td> _joy0button</td><td> !(*INPT4 & $80)</td><td> Left joystick button pressed</td></tr>
|
||||
<tr><td> _joy1left</td><td> !(*SWCHA & $04)</td><td> Right joystick moved left</td></tr>
|
||||
<tr><td> _joy1right</td><td> !(*SWCHA & $08)</td><td> Right joystick moved right</td></tr>
|
||||
<tr><td> _joy1up</td><td> !(*SWCHA & $01)</td><td> Right joystick moved up</td></tr>
|
||||
<tr><td> _joy1down</td><td> !(*SWCHA & $02)</td><td> Right joystick moved down</td></tr>
|
||||
<tr><td> _joy1button</td><td> !(*INPT5 & $80)</td><td> Right joystick button pressed</td></tr>
|
||||
<tr><td> _joy0Left</td><td> !(*SWCHA & $40)</td><td> Left joystick moved left</td></tr>
|
||||
<tr><td> _joy0Right</td><td> !(*SWCHA & $80)</td><td> Left joystick moved right</td></tr>
|
||||
<tr><td> _joy0Up</td><td> !(*SWCHA & $10)</td><td> Left joystick moved up</td></tr>
|
||||
<tr><td> _joy0Down</td><td> !(*SWCHA & $20)</td><td> Left joystick moved down</td></tr>
|
||||
<tr><td> _joy0Fire</td><td> !(*INPT4 & $80)</td><td> Left joystick fire button pressed</td></tr>
|
||||
<tr><td> _joy1Left</td><td> !(*SWCHA & $04)</td><td> Right joystick moved left</td></tr>
|
||||
<tr><td> _joy1Right</td><td> !(*SWCHA & $08)</td><td> Right joystick moved right</td></tr>
|
||||
<tr><td> _joy1Up</td><td> !(*SWCHA & $01)</td><td> Right joystick moved up</td></tr>
|
||||
<tr><td> _joy1Down</td><td> !(*SWCHA & $02)</td><td> Right joystick moved down</td></tr>
|
||||
<tr><td> _joy1Fire</td><td> !(*INPT5 & $80)</td><td> Right joystick fire button pressed</td></tr>
|
||||
<tr><td> _select</td><td> !(*SWCHB & $02)</td><td> Game Select pressed</td></tr>
|
||||
<tr><td> _reset</td><td> !(*SWCHB & $01)</td><td> Game Reset pressed</td></tr>
|
||||
<tr><td> _color</td><td> *SWCHB & $08</td><td> Color/BW set to Color</td></tr>
|
||||
<tr><td> _bw</td><td> !(*SWCHB & $08)</td><td> Color/BW set to BW</td></tr>
|
||||
<tr><td> _diff0b</td><td> !(*SWCHB & $40)</td><td> Left difficulty set to B (easy)</td></tr>
|
||||
<tr><td> _diff0a</td><td> *SWCHB & $40</td><td> Left difficulty set to A (hard)</td></tr>
|
||||
<tr><td> _diff1b</td><td> !(*SWCHB & $80)</td><td> Right difficulty set to B (easy)</td></tr>
|
||||
<tr><td> _diff1a</td><td> *SWCHB & $80</td><td> Right difficulty set to A (hard)</td></tr>
|
||||
<tr><td> _diff0B</td><td> !(*SWCHB & $40)</td><td> Left difficulty set to B (easy)</td></tr>
|
||||
<tr><td> _diff0A</td><td> *SWCHB & $40</td><td> Left difficulty set to A (hard)</td></tr>
|
||||
<tr><td> _diff1B</td><td> !(*SWCHB & $80)</td><td> Right difficulty set to B (easy)</td></tr>
|
||||
<tr><td> _diff1A</td><td> *SWCHB & $80</td><td> Right difficulty set to A (hard)</td></tr>
|
||||
</table>
|
||||
|
||||
<p>Don't worry about memorizing them all: the Prompt "help" command
|
||||
|
@ -756,36 +764,38 @@ that holds 'number of scanlines' on an actual console).</p>
|
|||
<table border="1" cellpadding=4>
|
||||
<tr><th>Function</th><th>Description</th></tr>
|
||||
<tr><td> _bank</td><td> Currently selected bank</td></tr>
|
||||
<tr><td> _cclocks</td><td> Color clocks on a scanline</td></tr>
|
||||
<tr><td> _cycleshi</td><td> Higher 32 bits of number of cycles since emulation started</td></tr>
|
||||
<tr><td> _cycleslo</td><td> Lower 32 bits of number of cycles since emulation started</td></tr>
|
||||
<tr><td> _fcount</td><td> Number of frames since emulation started</td></tr>
|
||||
<tr><td> _fcycles</td><td> Number of cycles since frame started</td></tr>
|
||||
<tr><td> _ftimreadcycles</td><td>Number of cycles used by timer reads since frame started</td></tr>
|
||||
<tr><td> _fwsynccycles</td><td>Number of cycles skipped by WSYNC since frame started</td></tr>
|
||||
<tr><td> _icycles</td><td> Number of cycles of last instruction</td></tr>
|
||||
<tr><td> _scan</td><td> Current scanline count</td></tr>
|
||||
<tr><td> _scanend</td><td> Scanline count at end of last frame</td></tr>
|
||||
<tr><td> _scycles</td><td> Number of cycles in current scanline</td></tr>
|
||||
<tr><td> _timwrapread</td><td> Timer read wrapped on this cycle</td></tr>
|
||||
<tr><td> _timwrapwrite</td><td> Timer write wrapped on this cycle</td></tr>
|
||||
<tr><td> _vblank</td><td> Whether vertical blank is enabled (1 or 0)</td></tr>
|
||||
<tr><td> _vsync</td><td> Whether vertical sync is enabled (1 or 0)</td></tr>
|
||||
<tr><td> _cClocks</td><td> Color clocks on a scanLine</td></tr>
|
||||
<tr><td> _cyclesHi</td><td> Higher 32 bits of number of cycles since emulation started</td></tr>
|
||||
<tr><td> _cyclesLo</td><td> Lower 32 bits of number of cycles since emulation started</td></tr>
|
||||
<tr><td> _fCount</td><td> Number of frames since emulation started</td></tr>
|
||||
<tr><td> _fCycles</td><td> Number of cycles since frame started</td></tr>
|
||||
<tr><td> _fTimReadCycles</td><td>Number of cycles used by timer reads since frame started</td></tr>
|
||||
<tr><td> _fWsyncCycles</td><td>Number of cycles skipped by WSYNC since frame started</td></tr>
|
||||
<tr><td> _iCycles</td><td> Number of cycles of last instruction</td></tr>
|
||||
<tr><td> _inTim</td><td> Current INTIM value</td></tr>
|
||||
<tr><td> _scan</td><td> Current scanLine count</td></tr>
|
||||
<tr><td> _scanEnd</td><td> Scanline count at end of last frame</td></tr>
|
||||
<tr><td> _sCycles</td><td> Number of cycles in current scanLine</td></tr>
|
||||
<tr><td> _timInt</td><td> Current TIMINT value</td></tr>
|
||||
<tr><td> _timWrapRead</td><td> Timer read wrapped on this cycle</td></tr>
|
||||
<tr><td> _timWrapWrite</td><td> Timer write wrapped on this cycle</td></tr>
|
||||
<tr><td> _vBlank</td><td> Whether vertical blank is enabled (1 or 0)</td></tr>
|
||||
<tr><td> _vSync</td><td> Whether vertical sync is enabled (1 or 0)</td></tr>
|
||||
</table>
|
||||
|
||||
<p><b>_scan</b> always contains the current scanline count. You can use
|
||||
<p><b>_scan</b> always contains the current scanLine count. You can use
|
||||
this to break your program in the middle of your kernel. Example:</p>
|
||||
<pre>
|
||||
breakif _scan==#64
|
||||
breakIf _scan==#64
|
||||
</pre>
|
||||
<p>This will cause Stella to enter the debugger when the TIA reaches the
|
||||
beginning of the 64th scanline.</p>
|
||||
beginning of the 64th scanLine.</p>
|
||||
|
||||
<p><b>_bank</b> always contains the currently selected bank. For 2K or 4K
|
||||
(non-bankswitched) ROMs, it will always contain 0. One useful use is:</p>
|
||||
|
||||
<pre>
|
||||
breakif { pc==myLabel && _bank==1 }
|
||||
breakIf { pc==myLabel && _bank==1 }
|
||||
</pre>
|
||||
|
||||
<p>This is similar to setting a regular breakpoint, but it will only trigger
|
||||
|
@ -804,8 +814,8 @@ pointed to by the Y register, even if the Y register changes.</p>
|
|||
|
||||
<p>The watches are numbered. The numbers are printed along with the
|
||||
watches, so you can tell which is which. To delete a watch use the
|
||||
"delwatch" command with the watch number (1 to whatever). You can
|
||||
also delete them all with the "clearwatches" command.</p>
|
||||
"delWatch" command with the watch number (1 to whatever). You can
|
||||
also delete them all with the "clearWatches" command.</p>
|
||||
|
||||
<p>Note that there's no real point in watching a label or CPU register
|
||||
without dereferencing it: Labels are constants, and CPU registers
|
||||
|
@ -818,7 +828,7 @@ accesses to a memory address, rather than specific location in the
|
|||
program. They're useful for finding code that modifies TIA registers
|
||||
or memory.</p>
|
||||
|
||||
<p>Traps can also combined with a condition ("trapif"). If an access
|
||||
<p>Traps can also combined with a condition ("trapIf"). If an access
|
||||
to a memory address is caught, the condition is evaluated additionally.
|
||||
Only if the condition is true too, the emulations stops. For details
|
||||
about conditions see <a href="#ConditionalBreaks"><b>Conditional Breaks</b></a> described above.</p>
|
||||
|
@ -842,12 +852,28 @@ so the best we can do is stop before the next instruction runs.</p>
|
|||
<p>Traps come in two varieties: read access traps and write access traps.
|
||||
It is possible to set both types of trap on the same address (that's
|
||||
what the plain "trap" command does). To set a read or write only trap,
|
||||
use "trapread(if)" or "trapwrite(if)".
|
||||
use "trapRead(if)" or "trapWrite(if)".
|
||||
|
||||
<p>All traps appear in "listtraps", numbered starting from zero. You
|
||||
can remove a trap with "deltrap number", where the number comes from
|
||||
"listtraps" or by entering the identical trap again. You can get rid of
|
||||
all traps at once with the "cleartraps" command.</p></p>
|
||||
<p>All traps appear in "listTraps", numbered starting from zero. You
|
||||
can remove a trap with "delTrap number", where the number comes from
|
||||
"listTraps" or by entering the identical trap again. You can get rid of
|
||||
all traps at once with the "clearTraps" command.</p></p>
|
||||
|
||||
<h4><a name="Timers">Timers</a></h4>
|
||||
|
||||
<p>Timers are used to measure cycles used between two timer points. They
|
||||
measure the minimum, maximum and average cycles executed between their two
|
||||
timer points. Start and end points can be set via prompt command or ROM
|
||||
Disassembly settings dialog.</p>
|
||||
|
||||
<p>If the timer point is defined without an address or bank, the current PC
|
||||
address or bank are used. If a '+' is added, both timer points use address
|
||||
mirrors too, a '*' triggers both timer points in any bank.</p>
|
||||
|
||||
<p>All timers can be shown in detail with "listTimers", a single timer
|
||||
with "printTimer number". "resetTimers" allows resetting all timer statistics,
|
||||
"delTimer number" removes a single timer. All timers can be deleted with the
|
||||
"clearTimers" command.</p>
|
||||
|
||||
</br>
|
||||
<h3><a name="SaveWork">Save your work!</a></h3>
|
||||
|
@ -856,58 +882,61 @@ later re-use.</p>
|
|||
|
||||
<ul>
|
||||
<li>
|
||||
<b><a name="savecmd">save</a></b>: If you've defined a lot of complex functions, you probably will
|
||||
want to re-use them in future runs of the debugger. You can save all
|
||||
your functions, breakpoints, conditional breaks, traps and watches with the
|
||||
"save" command. If you name your saved file the same as the ROM filename
|
||||
and place it in the ROM directory, it will be auto-loaded next time you
|
||||
load the same ROM in Stella. The saved file is just a plain text file
|
||||
called "<rom_filename>.script", so you can edit it and add new functions, etc.
|
||||
<b><a name="savecmd">save</a></b>: If you've defined a lot of complex
|
||||
functions, you probably will want to re-use them in future runs of the
|
||||
debugger. You can save all your functions, breakpoints, conditional breaks,
|
||||
traps and watches with the "save" command. By default it is saved in the
|
||||
user directory with the same as the ROM filename. In this case it will be
|
||||
auto-loaded next time you load the same ROM in Stella. The saved file is
|
||||
just a plain text file called "<rom_filename>.script", so you can
|
||||
edit it and add more functions, etc.
|
||||
<p>Use "autoSave" to automatically execute the "save" command when
|
||||
exiting the debugger.</p>
|
||||
<p>Note: While "save" is ROM specific, you can also create a file called
|
||||
"autoexec.script" which will be loaded when the debugger starts, no matter
|
||||
what ROM you have loaded.<p>
|
||||
See <a href="#Startup"><b>Startup</b></a> for details.
|
||||
</li>
|
||||
<li>
|
||||
<b>saveconfig</b>: The "saveconfig" command creates a
|
||||
<b>saveConfig</b>: The "saveConfig" command creates a
|
||||
<a href="#DistellaConfiguration"><b>DiStella Configuration File</b></a> which is
|
||||
based on Stella's dynamic and static analysis of the current ROM.
|
||||
<p>This will be automatically loaded the next time your start the debugger.
|
||||
From there on, you can continue analyzing the ROM and then use "saveconfig"
|
||||
again to update the configuration. You can also use "loadconfig" to load it
|
||||
From there on, you can continue analyzing the ROM and then use "saveConfig"
|
||||
again to update the configuration. You can also use "loadConfig" to load it
|
||||
manually.
|
||||
<p>Note that this is not tested for multi-banked ROMs.</p>
|
||||
</li>
|
||||
<li>
|
||||
<b>savedis</b>:
|
||||
<b>saveDis</b>:
|
||||
While your are playing or debugging a game, Stella will gather dynamic
|
||||
information about the ROM. It can then use that information together with
|
||||
a static analysis of the ROM and therefore create a better disassembly
|
||||
than DiStella alone. "savedis" allows you to save that disassembly as the
|
||||
than DiStella alone. "saveDis" allows you to save that disassembly as the
|
||||
result of this combined analysis.
|
||||
<p>Note that this currently only works for single banked ROMs. For larger
|
||||
ROMs, the created disassembly is incomplete.</p>
|
||||
</li>
|
||||
<li>
|
||||
<p><b>saverom</b>:
|
||||
If you have manipulated a ROM, you can save it with "saverom". The file is
|
||||
<p><b>saveRom</b>:
|
||||
If you have manipulated a ROM, you can save it with "saveRom". The file is
|
||||
named "<rom_filename>.a26".</p>
|
||||
</li>
|
||||
<li>
|
||||
<p><b>saveses</b>:
|
||||
The "saveses" command dumps the whole prompt session into a file named
|
||||
<p><b>saveSes</b>:
|
||||
The "saveSes" command dumps the whole prompt session into a file named
|
||||
"<YYYY-MM-DD_HH-mm-ss>.txt". So you can later lookup what you did exactly
|
||||
when you were debugging at that time.</p>
|
||||
</li>
|
||||
<li>
|
||||
<p><b>saveallstates</b>:
|
||||
<p><b>saveAllStates</b>:
|
||||
This command works identical to the save all states hotkey (Alt + F9) during emulation.
|
||||
The saved states can be loaded with "loadallstates".</p>
|
||||
The saved states can be loaded with "loadAllStates".</p>
|
||||
</li>
|
||||
<li>
|
||||
<p><b>savestate</b>:
|
||||
<p><b>saveState</b>:
|
||||
This command works identical to the save state hotkey (F9) during emulation.
|
||||
Any previously saved state can be loaded with "loadstate" plus the slot
|
||||
Any previously saved state can be loaded with "loadState" plus the slot
|
||||
number (0-9).</p>
|
||||
</li>
|
||||
</ul>
|
||||
|
@ -921,97 +950,107 @@ Type "help 'cmd'" to see extended information about the given command.</p>
|
|||
<pre>
|
||||
a - Set Accumulator to <value>
|
||||
aud - Mark 'AUD' range in disassembly
|
||||
autoSave - Automatically execute "save" when exiting the debugger
|
||||
base - Set default number base to <base> (bin, dec, hex)
|
||||
bcol - Mark 'BCOL' range in disassembly
|
||||
bCol - Mark 'BCOL' range in disassembly
|
||||
break - Set/clear breakpoint at <address> and <bank>
|
||||
breakif - Set/clear breakpoint on <condition>
|
||||
breaklabel - Set/clear breakpoint on <address> (no mirrors, all banks)
|
||||
breakIf - Set/clear breakpoint on <condition>
|
||||
breakLabel - Set/clear breakpoint on <address> (no mirrors, all banks)
|
||||
c - Carry Flag: set (0 or 1), or toggle (no arg)
|
||||
cheat - Use a cheat code (see manual for cheat types)
|
||||
clearbreaks - Clear all breakpoints
|
||||
clearconfig - Clear DiStella config directives [bank xx]
|
||||
clearsavestateifs - Clear all savestate points
|
||||
cleartraps - Clear all traps
|
||||
clearwatches - Clear all watches
|
||||
clearBreaks - Clear all breakpoints
|
||||
clearConfig - Clear DiStella config directives [bank xx]
|
||||
clearHistory - Clear the prompt history
|
||||
clearSaveStateIfs - Clear all saveState points
|
||||
clearTimers - Clear all timers
|
||||
clearTraps - Clear all traps
|
||||
clearWatches - Clear all watches
|
||||
cls - Clear prompt area of text
|
||||
code - Mark 'CODE' range in disassembly
|
||||
col - Mark 'COL' range in disassembly
|
||||
colortest - Show value xx as TIA color
|
||||
colorTest - Show value xx as TIA color
|
||||
d - Decimal Mode Flag: set (0 or 1), or toggle (no arg)
|
||||
data - Mark 'DATA' range in disassembly
|
||||
debugcolors - Show Fixed Debug Colors information
|
||||
debugColors - Show Fixed Debug Colors information
|
||||
define - Define label xx for address yy
|
||||
delbreakif - Delete conditional breakif <xx>
|
||||
delfunction - Delete function with label xx
|
||||
delsavestateif - Delete conditional savestate point <xx>
|
||||
deltrap - Delete trap <xx>
|
||||
delwatch - Delete watch <xx>
|
||||
disasm - Disassemble address xx [yy lines] (default=PC)
|
||||
delBreakIf - Delete conditional breakIf <xx>
|
||||
delFunction - Delete function with label xx
|
||||
delSaveStateIf - Delete conditional saveState point <xx>
|
||||
delTrap - Delete trap <xx>
|
||||
delTimer - Delete timer <xx>
|
||||
delWatch - Delete watch <xx>
|
||||
disAsm - Disassemble address xx [yy lines] (default=PC)
|
||||
dump - Dump data at address <xx> [to yy] [1: memory; 2: CPU state; 4: input regs] [?]
|
||||
exec - Execute script file <xx> [prefix]
|
||||
exitrom - Exit emulator, return to ROM launcher
|
||||
exitRom - Exit emulator, return to ROM launcher
|
||||
frame - Advance emulation by <xx> frames (default=1)
|
||||
function - Define function name xx for expression yy
|
||||
gfx - Mark 'GFX' range in disassembly
|
||||
help - help <command>
|
||||
joy0up - Set joystick 0 up direction to value <x> (0 or 1), or toggle (no arg)
|
||||
joy0down - Set joystick 0 down direction to value <x> (0 or 1), or toggle (no arg)
|
||||
joy0left - Set joystick 0 left direction to value <x> (0 or 1), or toggle (no arg)
|
||||
joy0right - Set joystick 0 right direction to value <x> (0 or 1), or toggle (no arg)
|
||||
joy0fire - Set joystick 0 fire button to value <x> (0 or 1), or toggle (no arg)
|
||||
joy1up - Set joystick 1 up direction to value <x> (0 or 1), or toggle (no arg)
|
||||
joy1down - Set joystick 1 down direction to value <x> (0 or 1), or toggle (no arg)
|
||||
joy1left - Set joystick 1 left direction to value <x> (0 or 1), or toggle (no arg)
|
||||
joy1right - Set joystick 1 right direction to value <x> (0 or 1), or toggle (no arg)
|
||||
joy1fire - Set joystick 1 fire button to value <x> (0 or 1), or toggle (no arg)
|
||||
joy0Up - Set joystick 0 up direction to value <x> (0 or 1), or toggle (no arg)
|
||||
joy0Down - Set joystick 0 down direction to value <x> (0 or 1), or toggle (no arg)
|
||||
joy0Left - Set joystick 0 left direction to value <x> (0 or 1), or toggle (no arg)
|
||||
joy0Right - Set joystick 0 right direction to value <x> (0 or 1), or toggle (no arg)
|
||||
joy0Fire - Set joystick 0 fire button to value <x> (0 or 1), or toggle (no arg)
|
||||
joy1Up - Set joystick 1 up direction to value <x> (0 or 1), or toggle (no arg)
|
||||
joy1Down - Set joystick 1 down direction to value <x> (0 or 1), or toggle (no arg)
|
||||
joy1Left - Set joystick 1 left direction to value <x> (0 or 1), or toggle (no arg)
|
||||
joy1Right - Set joystick 1 right direction to value <x> (0 or 1), or toggle (no arg)
|
||||
joy1Fire - Set joystick 1 fire button to value <x> (0 or 1), or toggle (no arg)
|
||||
jump - Scroll disassembly to address xx
|
||||
listbreaks - List breakpoints
|
||||
listconfig - List DiStella config directives [bank xx]
|
||||
listfunctions - List user-defined functions
|
||||
listsavestateifs - List savestate points
|
||||
listtraps - List traps
|
||||
loadconfig - Load DiStella config file
|
||||
loadallstates - Load all emulator states
|
||||
loadstate - Load emulator state xx (0-9)
|
||||
listBreaks - List breakpoints
|
||||
listConfig - List DiStella config directives [bank xx]
|
||||
listFunctions - List user-defined functions
|
||||
listSaveStateIfs - List saveState points
|
||||
listTraps - List traps
|
||||
loadConfig - Load DiStella config file
|
||||
loadAllStates - Load all emulator states
|
||||
loadState - Load emulator state xx (0-9)
|
||||
logBreaks - Logs breaks and traps and continues emulation
|
||||
logTrace - Logs emulation (note: emulation may slow down and the log becomes huge soon)
|
||||
n - Negative Flag: set (0 or 1), or toggle (no arg)
|
||||
palette - Show current TIA palette
|
||||
pc - Set Program Counter to address xx
|
||||
pcol - Mark 'PCOL' range in disassembly
|
||||
pgfx - Mark 'PGFX' range in disassembly
|
||||
pCol - Mark 'PCOL' range in disassembly
|
||||
pGfx - Mark 'PGFX' range in disassembly
|
||||
print - Evaluate/print expression xx in hex/dec/binary
|
||||
printTimer - Print details of timer xx
|
||||
ram - Show ZP RAM, or set address xx to yy1 [yy2 ...]
|
||||
reset - Reset system to power-on state
|
||||
resetTimers - Reset all timers' statistics
|
||||
rewind - Rewind state by one or [xx] steps/traces/scanlines/frames...
|
||||
riot - Show RIOT timer/input status
|
||||
rom - Set ROM address xx to yy1 [yy2 ...]
|
||||
row - Mark 'ROW' range in disassembly
|
||||
run - Exit debugger, return to emulator
|
||||
runto - Run until string xx in disassembly
|
||||
runtopc - Run until PC is set to value xx
|
||||
runTo - Run until string xx in disassembly
|
||||
runToPc - Run until PC is set to value xx
|
||||
s - Set Stack Pointer to value xx
|
||||
save - Save breaks, watches, traps and functions to file <xx or ?>
|
||||
saveaccess - Save access counters to CSV file [?]
|
||||
saveconfig - Save DiStella config file (with default name)
|
||||
savedis - Save DiStella disassembly to file [?]
|
||||
saverom - Save (possibly patched) ROM to file [?]
|
||||
saveses - Save console session to file [?]
|
||||
savesnap - Save current TIA image to PNG file
|
||||
saveallstates - Save all emulator states
|
||||
savestate - Save emulator state xx (valid args 0-9)
|
||||
savestateif - Create savestate on <condition>
|
||||
scanline - Advance emulation by <xx> scanlines (default=1)
|
||||
save - Save breaks, watches, traps and functions to file [xx or ?]
|
||||
saveAccess - Save access counters to CSV file [?]
|
||||
saveConfig - Save DiStella config file (with default name)
|
||||
saveDis - Save DiStella disassembly to file [?]
|
||||
saveRom - Save (possibly patched) ROM to file [?]
|
||||
saveSes - Save console session to file [?]
|
||||
saveSnap - Save current TIA image to PNG file
|
||||
saveAllStates - Save all emulator states
|
||||
saveState - Save emulator state xx (valid args 0-9)
|
||||
saveStateIf - Create saveState on <condition>
|
||||
scanLine - Advance emulation by <xx> scanlines (default=1)
|
||||
step - Single step CPU [with count xx]
|
||||
stepwhile - Single step CPU while <condition> is true
|
||||
stepWhile - Single step CPU while <condition> is true
|
||||
swchb - Set SWCHB to value xx
|
||||
tia - Show TIA state
|
||||
timer - Set a timer point
|
||||
trace - Single step CPU over subroutines [with count xx]
|
||||
trap - Trap read/write access to address(es) xx [yy]
|
||||
trapif - On <condition> trap R/W access to address(es) xx [yy]
|
||||
trapread - Trap read access to address(es) xx [yy]
|
||||
trapreadif - On <condition> trap read access to address(es) xx [yy]
|
||||
trapwrite - Trap write access to address(es) xx [yy]
|
||||
trapwriteif - On <condition> trap write access to address(es) xx [yy]
|
||||
trapIf - On <condition> trap R/W access to address(es) xx [yy]
|
||||
trapRead - Trap read access to address(es) xx [yy]
|
||||
trapReadIf - On <condition> trap read access to address(es) xx [yy]
|
||||
trapWrite - Trap write access to address(es) xx [yy]
|
||||
trapWriteIf - On <condition> trap write access to address(es) xx [yy]
|
||||
type - Show disassembly type for address xx [yy]
|
||||
uhex - Toggle upper/lowercase HEX display
|
||||
uHex - Toggle upper/lowercase HEX display
|
||||
undef - Undefine label xx (if defined)
|
||||
unwind - Unwind state state by one or [xx] steps/traces/scanlines/frames...
|
||||
v - Overflow Flag: set (0 or 1), or toggle (no arg)
|
||||
|
@ -1069,7 +1108,7 @@ VDELBL selects the register that is used to control the ball. This is
|
|||
visualized in the debugger in the same way as the two copies of GRP0 and
|
||||
GRP1</p>
|
||||
|
||||
<p>For many registers, writes don't take effect immediatelly as the
|
||||
<p>For many registers, writes don't take effect immediately as the
|
||||
TIA takes some color clocks to change state. In Stella's TIA core, this
|
||||
is implemented by queueing the writes, and the contents of this queue
|
||||
are visualized in the debugger in the "Queued Writes" area of the TIA tab.</p>
|
||||
|
@ -1084,11 +1123,11 @@ in another part of the debugger).</p>
|
|||
<p><img src="graphics/debugger_iotab.png"></p>
|
||||
|
||||
<p>As with the TIA tab, most of the values here will be self-explanatory to a 2600
|
||||
developer, and almost all can be modified. However, the SWCHx registers need
|
||||
developer, and many can be modified. However, the SWCHx registers need
|
||||
further explanation:<p>
|
||||
<p>SWCHx(W) can be modified; here, the (W) stands for write. Similarly,
|
||||
SWACNT/SWBCNT can be directly modified. However, the results of reading back from
|
||||
the SWCHx register are influenced by SWACNT/SWBCNT, and SWCHx(R) is a read-only display
|
||||
<p>SWCHx(W/R) can be modified; here (W) stands for write, (R) for read.
|
||||
Similarly, SWxCNT can be directly modified. However, the results of reading
|
||||
back from the SWCHx register are influenced by SWxCNT, and SWCHx(R) is
|
||||
reflecting this result.</p>
|
||||
|
||||
|
||||
|
@ -1111,12 +1150,12 @@ volume resulting from the two channel volumes.</p>
|
|||
<p>In the upper left of the debugger, you'll see the current frame of
|
||||
video as generated by the TIA. If a complete frame hasn't been drawn,
|
||||
the partial contents of the current frame will be displayed up to the
|
||||
current scanline, with the contents of the old frame (in black &
|
||||
current scanLine, with the contents of the old frame (in black &
|
||||
white) filling the rest of the display. Note that if 'phosphor mode'
|
||||
or TV effects are enabled, you won't see the effects here; this shows the
|
||||
<b>raw</b> TIA image only.</p>
|
||||
|
||||
<p>To e.g. watch the TIA draw the frame one scanline at a time, you can
|
||||
<p>To e.g. watch the TIA draw the frame one scanLine at a time, you can
|
||||
use the 'Scan+1' button, the prompt "scan" command or the Control-L key.</p>
|
||||
|
||||
<p>You can also right-click anywhere in this window to show a context menu,
|
||||
|
@ -1124,10 +1163,10 @@ as illustrated:</p>
|
|||
<p><img src="graphics/debugger_tiaoutcmenu.png"></p>
|
||||
<p>The options are as follows:</p>
|
||||
<ul>
|
||||
<li><b>Fill to scanline</b>: This option will draw all scanlines up to the
|
||||
<li><b>Fill to scanLine</b>: This option will draw all scanlines up to the
|
||||
vertical position where the mouse was clicked (see also <a href="#TIAZoom"><b>TIA Zoom</b></a>).</li>
|
||||
<li><b>Toggle breakpoint</b>: Will toggle a conditional breakpoint at the
|
||||
scanline where the mouse was clicked. You can also use a left-click or
|
||||
scanLine where the mouse was clicked. You can also use a left-click or
|
||||
the Prompt Tab commands to list and turn off the breakpoint
|
||||
(see also <a href="#TIAZoom"><b>TIA Zoom</b></a>).</li>
|
||||
<li><b>Set zoom position</b>: Influences what is shown in the TIA
|
||||
|
@ -1148,27 +1187,27 @@ as illustrated:</p>
|
|||
<p>The indicators are as follows (note that all these are read-only):</p>
|
||||
<ul>
|
||||
<li><b>Frame Cycls</b>: The number of CPU cycles that have been executed this frame since
|
||||
VSYNC was cleared at scanline 0.</li>
|
||||
VSYNC was cleared at scanLine 0.</li>
|
||||
<li><b>WSync Cycls</b>: The number of CPU cycles that have been skipped by WSYNC this frame since
|
||||
VSYNC was cleared at scanline 0.</li>
|
||||
VSYNC was cleared at scanLine 0.</li>
|
||||
<li><b>Timer Cycls</b>: The number of CPU cycles (approximately) that have been used by timer read loops since
|
||||
VSYNC was cleared at scanline 0.</li>
|
||||
VSYNC was cleared at scanLine 0.</li>
|
||||
<li><b>Total</b>: The total number of CPU cycles since this ROM was loaded or reset.</li>
|
||||
<li><b>Delta</b>: The number of CPU cycles that have been executed since the last debugger
|
||||
interrupt.</li>
|
||||
<li><b>Frame Cnt.</b>: The number of frames since this ROM was loaded or reset.</li>
|
||||
<li><b>Scanline</b>: The scanline that's currently being drawn, and the count from the
|
||||
<li><b>Scanline</b>: The scanLine that's currently being drawn, and the count from the
|
||||
previous frame. Scanline 0 is the one on which VSYNC is cleared (after being set for
|
||||
3 scanlines, as per the Stella Programmer's Guide).</li>
|
||||
<li><b>Scan Cycle</b>: The number of CPU cycles that have been executed since the beginning
|
||||
of the current scanline.</li>
|
||||
of the current scanLine.</li>
|
||||
<li><b>Pixel Pos</b>: The current number of visible color clocks that have been displayed on
|
||||
the current scanline, starting from the beginning of the Horizontal Blank period.
|
||||
the current scanLine, starting from the beginning of the Horizontal Blank period.
|
||||
During HBLANK, this value will be negative (representing the number of clocks
|
||||
until the first visible one). Since there are 68 color clocks per HBLANK and
|
||||
160 visible clocks per scanline, the Pixel Position will range from -68 to 159.</li>
|
||||
160 visible clocks per scanLine, the Pixel Position will range from -68 to 159.</li>
|
||||
<li><b>Color Clock</b>: The current number of total color clocks since the beginning of this
|
||||
scanline's HBLANK. This counter starts at zero, but otherwise displays the same
|
||||
scanLine's HBLANK. This counter starts at zero, but otherwise displays the same
|
||||
information as the Pixel Position (so Color Clock will always be 68 more than Pixel
|
||||
Position, and will range from 0 to 228).</li>
|
||||
</ul>
|
||||
|
@ -1186,10 +1225,10 @@ as illustrated:</p>
|
|||
<p><img src="graphics/debugger_tiazoomcmenu.png"></p>
|
||||
<p>These options allow you to:</p>
|
||||
<ul>
|
||||
<li><b>Fill to scanline</b>: This option will draw all scanlines up to the
|
||||
<li><b>Fill to scanLine</b>: This option will draw all scanlines up to the
|
||||
vertical position where the mouse was clicked.</li>
|
||||
<li><b>Toggle breakpoint</b>: Will toggle a conditional breakpoint at the
|
||||
scanline where the mouse was clicked. You can also
|
||||
scanLine where the mouse was clicked. You can also
|
||||
the Prompt Tab commands to list and turn off the breakpoint.</li>
|
||||
<li><b>2x|4x|8x zoom</b>: Zoom in on the image for even greater detail.</li>
|
||||
</ul>
|
||||
|
@ -1288,13 +1327,40 @@ are lost (they will NOT end up in the Carry flag).</p>
|
|||
<h2><a name="M6532"><u>(K)</u> M6532/RIOT RAM</a></h2>
|
||||
<p>This is a spreadsheet-like GUI for inspecting and changing the contents
|
||||
of the 2600's zero-page RAM.</p>
|
||||
<p>You can navigate with either the mouse or the keyboard arrow keys.
|
||||
<p>You can navigate with either the mouse or the keyboard (see below).
|
||||
To change a RAM location, either double-click on it or press 'Enter' while
|
||||
it's highlighted. Enter the new value (hex, other formats using the bottom textboxes), then
|
||||
press 'Enter' to make the change. The currently selected RAM cell
|
||||
can also be changed by using the
|
||||
<a href="#DataOpButtons"><b>Data Operations Buttons</b></a> or the associated
|
||||
shortcut keys.</p>
|
||||
|
||||
<p>You can navigate all RAM grids (and other data grids too) using the following keyboard shortcuts.</p>
|
||||
<table border="1" cellpadding=4>
|
||||
<tr>
|
||||
<th>Shortut</th><th>Description</th>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>Left arrow</td><td>Move to left cell.</td>
|
||||
</tr><tr>
|
||||
<td>Right arrow</td><td>Move to right cell.</td>
|
||||
</tr><tr>
|
||||
<td>Home</td><td>Move to leftmost cell.</td>
|
||||
</tr><tr>
|
||||
<td>End</td><td>Move to rightmost cell.</td>
|
||||
</tr><tr>
|
||||
<td>Up arrow</td><td>Move to cell above.</td>
|
||||
</tr><tr>
|
||||
<td>Down arrow</td><td>Move to cell below.</td>
|
||||
</tr><tr>
|
||||
<td>Page Up</td><td>Move to top visible row.</td>
|
||||
</tr><tr>
|
||||
<td>Page Down</td><td>Move to bottom visible row.</td>
|
||||
</tr><tr>
|
||||
<td>Shift + Page Up</td><td>Scroll one page up.</td>
|
||||
</tr><tr>
|
||||
<td>Shift + Page Down</td><td>Scroll one page down.</td>
|
||||
</table>
|
||||
<p><img src="graphics/debugger_ram.png"></p>
|
||||
<p>The 'Undo' button in the upper right should be self-explanatory; it will
|
||||
undo the most previous operation to one cell only. The 'Revert' button is
|
||||
|
@ -1375,7 +1441,7 @@ labels. Normally there will be nothing there: this indicates that there's
|
|||
no breakpoint set at that address. You can set and clear breakpoints by
|
||||
clicking in this area. When a breakpoint is set, there will be a
|
||||
red circle in this area. These are the same breakpoints as used
|
||||
by the <a href="#Breakpoints">break</a> command, <b>not</b> the conditional "breakif" breakpoints
|
||||
by the <a href="#Breakpoints">break</a> command, <b>not</b> the conditional "breakIf" breakpoints
|
||||
(which makes sense: conditional breaks can break on any condition, the Program
|
||||
Counter isn't necessarily involved).</li>
|
||||
<li><b>Labels</b>: Any labels assigned to the given address, either generated
|
||||
|
@ -1473,7 +1539,7 @@ or lowercase for "illegal" 6502 instructions (like "dcp"). If automatic resolvin
|
|||
of code sections has been disabled for any reason, you'll likely see a lot
|
||||
of illegal opcodes if you scroll to a data table in ROM. This can also
|
||||
occur if the disassembler hasn't yet encountered addresses in the PC.
|
||||
If you step/trace/scanline/frame advance into such an area, the disassembler
|
||||
If you step/trace/scanLine/frame advance into such an area, the disassembler
|
||||
will make note of it, and disassemble it correctly from that point on.</p>
|
||||
|
||||
<!-- TODO - is this true any longer?
|
||||
|
@ -1520,13 +1586,16 @@ matches the address of the disassembly line where the mouse was clicked.</li>
|
|||
<li><b>Disassemble @ current line</b>: Disassemble from the disassembly line where the mouse was clicked.
|
||||
This allows to fill gaps in the disassembly and is most useful for bankswitched ROMs.</li>
|
||||
|
||||
<li><b>Set timer @ current line</b>: Set a timer point using the current
|
||||
disassembly line's address and bank</li>
|
||||
|
||||
<li><b>Show tentative code</b>: Allow DiStella to do a static analysis/disassembly.</li>
|
||||
|
||||
<li><b>Show PC addresses</b>: Show Program Counter addresses as labels (where there
|
||||
isn't already a defined label).</li>
|
||||
|
||||
<li><b>Show GFX as binary</b>: Switch between displaying/editing GFX and PGFX sections
|
||||
in either binary or hexidecimal.</li>
|
||||
in either binary or hexadecimal.</li>
|
||||
|
||||
<li><b>Use address relocation</b>: Corresponds to the DiStella '-r' option
|
||||
(Relocate calls out of address range).</br>
|
||||
|
@ -1541,7 +1610,7 @@ Note: The code will continue to run fine, but the ROM image will be altered.</li
|
|||
<li>The ROM Widget only works on ROM or zero-page RAM separately. If your game runs
|
||||
code from zero-page RAM, the disassembly will show addresses $80 to $FF (zero-page
|
||||
RAM address space) only. Once your RAM routine returns, the ROM Widget will switch
|
||||
back to ROM space ($1000 - $1FFF and mirrors). The same is true of the "disasm"
|
||||
back to ROM space ($1000 - $1FFF and mirrors). The same is true of the "disAsm"
|
||||
command; it will show either ROM or RAM space, not both at the same time.</li>
|
||||
|
||||
<li>The standard VCS memory map has the cartridge port at locations
|
||||
|
@ -1610,13 +1679,13 @@ space with the appropriate directive, there are times when it will fail. There a
|
|||
several options in this case:</p>
|
||||
<ol>
|
||||
<li><b>Manually set the directives</b>: Directives can be set in the debugger
|
||||
prompt with the aud/code/col/bcol/gfx/pcol/pgfx/data/row commands. These accept an address range
|
||||
prompt with the aud/code/col/bcol/gfx/pCol/pGfx/data/row commands. These accept an address range
|
||||
for the given directive type. Setting a range with the same type a second time
|
||||
will remove that directive from the range.</li>
|
||||
<li><b>Use configuration files</b>: Configuration files can be used to automatically
|
||||
load a list of directives when a ROM is loaded. These files can be generated with the
|
||||
'saveconfig' command, and loaded with the 'loadconfig' command. There are also
|
||||
'listconfig' and 'clearconfig' commands to show and erase (respectively) the current
|
||||
'saveConfig' command, and loaded with the 'loadConfig' command. There are also
|
||||
'listConfig' and 'clearConfig' commands to show and erase (respectively) the current
|
||||
directive listing. Upon opening the debugger for the first time, Stella attempts
|
||||
to load a configuration file from the folder containing the ROM. Assuming a ROM named "rr.a26" exists, the config file must be named <i>rr.cfg</i>.
|
||||
</ul>
|
||||
|
@ -1689,7 +1758,7 @@ but it helps to know at least a little about 6502 programming.</p>
|
|||
(for that, we have to disable the collision checking code, which means
|
||||
we have to find and understand it first!)</li>
|
||||
|
||||
<li>Set a Write Trap on the lives counter address: "trapwrite $ba"
|
||||
<li>Set a Write Trap on the lives counter address: "trapWrite $ba"
|
||||
in the Prompt. Exit the debugger and play until you get killed. When
|
||||
you die, the trap will cause the emulator to enter the debugger with the
|
||||
Program Counter pointing to the instruction *after* the one that wrote
|
||||
|
@ -1737,7 +1806,7 @@ but it helps to know at least a little about 6502 programming.</p>
|
|||
will *still* see 3 lives: Success! We've hacked Battlezone to give us
|
||||
infinite lives.</li>
|
||||
|
||||
<li>Save your work. In the prompt: "saverom". You now
|
||||
<li>Save your work. In the prompt: "saveRom". You now
|
||||
have your very own infinite-lives version of Battlezone. The file will
|
||||
be saved in your HOME directory (NOT your ROM directory), so you might
|
||||
want to move it to your ROM directory if it isn't the current directory.
|
||||
|
|
Before Width: | Height: | Size: 4.7 KiB After Width: | Height: | Size: 4.7 KiB |
Before Width: | Height: | Size: 2.8 KiB After Width: | Height: | Size: 2.1 KiB |
Before Width: | Height: | Size: 2.3 KiB After Width: | Height: | Size: 2.3 KiB |
Before Width: | Height: | Size: 5.2 KiB After Width: | Height: | Size: 5.2 KiB |
Before Width: | Height: | Size: 5.0 KiB After Width: | Height: | Size: 5.2 KiB |
Before Width: | Height: | Size: 63 KiB After Width: | Height: | Size: 64 KiB |
Before Width: | Height: | Size: 8.5 KiB After Width: | Height: | Size: 15 KiB |
Before Width: | Height: | Size: 4.4 KiB After Width: | Height: | Size: 4.5 KiB |
Before Width: | Height: | Size: 1.7 KiB After Width: | Height: | Size: 1.7 KiB |
Before Width: | Height: | Size: 4.5 KiB After Width: | Height: | Size: 4.9 KiB |
Before Width: | Height: | Size: 3.1 KiB After Width: | Height: | Size: 3.2 KiB |
Before Width: | Height: | Size: 4.3 KiB After Width: | Height: | Size: 4.4 KiB |
Before Width: | Height: | Size: 4.0 KiB After Width: | Height: | Size: 4.1 KiB |
Before Width: | Height: | Size: 14 KiB After Width: | Height: | Size: 28 KiB |
Before Width: | Height: | Size: 3.0 KiB After Width: | Height: | Size: 3.0 KiB |
Before Width: | Height: | Size: 4.1 KiB After Width: | Height: | Size: 4.5 KiB |
Before Width: | Height: | Size: 8.9 KiB After Width: | Height: | Size: 8.9 KiB |
After Width: | Height: | Size: 380 B |
After Width: | Height: | Size: 187 B |
Before Width: | Height: | Size: 2.0 KiB After Width: | Height: | Size: 2.0 KiB |
Before Width: | Height: | Size: 3.9 KiB After Width: | Height: | Size: 4.0 KiB |
After Width: | Height: | Size: 2.9 KiB |
Before Width: | Height: | Size: 5.1 KiB After Width: | Height: | Size: 6.2 KiB |
Before Width: | Height: | Size: 3.1 KiB After Width: | Height: | Size: 3.2 KiB |
Before Width: | Height: | Size: 5.0 KiB After Width: | Height: | Size: 6.1 KiB |
Before Width: | Height: | Size: 3.6 KiB After Width: | Height: | Size: 4.3 KiB |
Before Width: | Height: | Size: 3.4 KiB After Width: | Height: | Size: 3.4 KiB |
Before Width: | Height: | Size: 4.1 KiB After Width: | Height: | Size: 4.3 KiB |
Before Width: | Height: | Size: 3.4 KiB After Width: | Height: | Size: 3.5 KiB |
Before Width: | Height: | Size: 3.4 KiB After Width: | Height: | Size: 3.8 KiB |
Before Width: | Height: | Size: 2.7 KiB After Width: | Height: | Size: 2.8 KiB |
Before Width: | Height: | Size: 4.4 KiB After Width: | Height: | Size: 4.4 KiB |
Before Width: | Height: | Size: 3.5 KiB After Width: | Height: | Size: 3.6 KiB |
Before Width: | Height: | Size: 3.5 KiB After Width: | Height: | Size: 3.5 KiB |
Before Width: | Height: | Size: 1.4 KiB After Width: | Height: | Size: 1.5 KiB |
Before Width: | Height: | Size: 4.2 KiB After Width: | Height: | Size: 4.7 KiB |
Before Width: | Height: | Size: 3.7 KiB After Width: | Height: | Size: 3.7 KiB |
Before Width: | Height: | Size: 4.2 KiB After Width: | Height: | Size: 4.2 KiB |
Before Width: | Height: | Size: 5.7 KiB After Width: | Height: | Size: 5.7 KiB |
Before Width: | Height: | Size: 3.5 KiB After Width: | Height: | Size: 3.8 KiB |
Before Width: | Height: | Size: 3.5 KiB After Width: | Height: | Size: 3.5 KiB |
Before Width: | Height: | Size: 4.7 KiB |
Before Width: | Height: | Size: 9.6 KiB After Width: | Height: | Size: 9.6 KiB |
Before Width: | Height: | Size: 3.7 KiB After Width: | Height: | Size: 4.0 KiB |
After Width: | Height: | Size: 194 B |
Before Width: | Height: | Size: 3.0 KiB After Width: | Height: | Size: 2.2 KiB |
Before Width: | Height: | Size: 44 KiB After Width: | Height: | Size: 30 KiB |
Before Width: | Height: | Size: 36 KiB After Width: | Height: | Size: 15 KiB |
Before Width: | Height: | Size: 74 KiB After Width: | Height: | Size: 42 KiB |
After Width: | Height: | Size: 218 B |
After Width: | Height: | Size: 171 B |
After Width: | Height: | Size: 196 B |
Before Width: | Height: | Size: 18 KiB After Width: | Height: | Size: 18 KiB |
1878
docs/index.html
|
@ -58,7 +58,7 @@
|
|||
|
||||
<center><h1>Stella for RetroN 77</h1></center>
|
||||
<center><h2>Atari 2600 VCS emulator</h2></center>
|
||||
<center>Release 6.5.2</center>
|
||||
<center>Release 7.0</center>
|
||||
<center><h2>Quick Navigation Guide</h2></center>
|
||||
<br/>
|
||||
|
||||
|
@ -77,7 +77,7 @@
|
|||
<tr>
|
||||
<th width=110px>Joystick</th>
|
||||
<th width=100px>Button</th>
|
||||
<th width=170px>Action</th>
|
||||
<th width=200px>Action</th>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>Button 4</td>
|
||||
|
@ -95,17 +95,17 @@
|
|||
<td>Open settings</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>Button 7</td>
|
||||
<td>Button 8</td>
|
||||
<td>-</td>
|
||||
<td>Rewind game</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>Button 8</td>
|
||||
<td>Button 9</td>
|
||||
<td>MODE</td>
|
||||
<td>Select</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>Button 9</td>
|
||||
<td>Button 10</td>
|
||||
<td>RESET</td>
|
||||
<td>Reset</td>
|
||||
</tr>
|
||||
|
@ -119,7 +119,7 @@
|
|||
<tr>
|
||||
<th width=110px>Joystick</th>
|
||||
<th width=100px>Button</th>
|
||||
<th width=170px>Action</th>
|
||||
<th width=200px>Action</th>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>Up</td>
|
||||
|
@ -147,10 +147,40 @@
|
|||
<td>Start selected game</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>Button 2 or</br>hold Button 1</td>
|
||||
<td>Hold Button 1</td>
|
||||
<td>-</td>
|
||||
<td>Open a context menu with the following choices:
|
||||
<ul>
|
||||
<li>Add to favorites</li>
|
||||
<li>Power-On options...</li>
|
||||
<li>Go to initial directory</li>
|
||||
<li>Go to parent directory</li>
|
||||
<li><a href="#Settings">Settings...</a></li>
|
||||
</ul>
|
||||
Button 2 or 6 close the menu without any action.
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>Button 1 + Left</td>
|
||||
<td>-</td>
|
||||
<td>Display previous image</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>Button 1 + Right</td>
|
||||
<td>-</td>
|
||||
<td>Display next image</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>Button 1 + Up</td>
|
||||
<td>-</td>
|
||||
<td>Toggle image zoom</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>Button 2</td>
|
||||
<td>SKILL P2</td>
|
||||
<td>Open Power-On options</td>
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
<td>Button 4</td>
|
||||
<td>COLOR, B/W</td>
|
||||
|
@ -166,7 +196,7 @@
|
|||
<tr>
|
||||
<th width=110px>Joystick</th>
|
||||
<th width=100px>Button</th>
|
||||
<th width=170px>Action</th>
|
||||
<th width=200px>Action</th>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>Up</td>
|
||||
|
@ -234,7 +264,7 @@
|
|||
<td width="41%">This dialog is similar to the PC version's
|
||||
<a href="index.html#CommandMenu"><b>Command Menu</b></a>, but with some
|
||||
commands especially selected for the RetroN 77.</td>
|
||||
<td><p><img src="commandsmenu_r77.png"></p></td>
|
||||
<td><p><img src="graphics/commandsmenu_r77.png"></p></td>
|
||||
</tr>
|
||||
</table>
|
||||
</p>
|
||||
|
@ -279,7 +309,7 @@
|
|||
</tr>
|
||||
</table>
|
||||
</td>
|
||||
<td><p><img src="basic_settings.png"></p></td>
|
||||
<td><p><img src="graphics/basic_settings.png"></p></td>
|
||||
</tr>
|
||||
</table>
|
||||
</p>
|
||||
|
|
|
@ -8,7 +8,7 @@
|
|||
// SS SS tt ee ll ll aa aa
|
||||
// SSSS ttt eeeee llll llll aaaaa
|
||||
//
|
||||
// Copyright (c) 1995-2021 by Bradford W. Mott, Stephen Anthony
|
||||
// Copyright (c) 1995-2025 by Bradford W. Mott, Stephen Anthony
|
||||
// and the Stella Team
|
||||
//
|
||||
// See the file "License.txt" for information on usage and redistribution of
|
||||
|
@ -21,19 +21,19 @@
|
|||
#include "BankRomCheat.hxx"
|
||||
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
BankRomCheat::BankRomCheat(OSystem& os, const string& name, const string& code)
|
||||
BankRomCheat::BankRomCheat(OSystem& os, string_view name, string_view code)
|
||||
: Cheat(os, name, code)
|
||||
{
|
||||
if(myCode.length() == 7)
|
||||
myCode = "0" + code;
|
||||
myCode = "0" + string{code};
|
||||
|
||||
bank = unhex(myCode.substr(0, 2));
|
||||
address = 0xf000 + unhex(myCode.substr(2, 3));
|
||||
value = uInt8(unhex(myCode.substr(5, 2)));
|
||||
count = uInt8(unhex(myCode.substr(7, 1)) + 1);
|
||||
bank = BSPF::stoi<16>(myCode.substr(0, 2));
|
||||
address = 0xf000 + BSPF::stoi<16>(myCode.substr(2, 3));
|
||||
value = static_cast<uInt8>(BSPF::stoi<16>(myCode.substr(5, 2)));
|
||||
count = static_cast<uInt8>(BSPF::stoi<16>(myCode.substr(7, 1)) + 1);
|
||||
|
||||
// Back up original data; we need this if the cheat is ever disabled
|
||||
for(int i = 0; i < count; ++i)
|
||||
for(int i = 0; std::cmp_less(i, count); ++i)
|
||||
savedRom[i] = myOSystem.console().cartridge().peek(address + i);
|
||||
}
|
||||
|
||||
|
@ -47,11 +47,11 @@ bool BankRomCheat::enable()
|
|||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
bool BankRomCheat::disable()
|
||||
{
|
||||
int oldBank = myOSystem.console().cartridge().getBank(address);
|
||||
const int oldBank = myOSystem.console().cartridge().getBank(address);
|
||||
myOSystem.console().cartridge().bank(bank);
|
||||
|
||||
for(int i = 0; i < count; ++i)
|
||||
myOSystem.console().cartridge().patch(address + i, savedRom[i]);
|
||||
for(int i = 0; std::cmp_less(i, count); ++i)
|
||||
myOSystem.console().cartridge().patch(address + i, savedRom[i]);
|
||||
|
||||
myOSystem.console().cartridge().bank(oldBank);
|
||||
|
||||
|
@ -63,10 +63,10 @@ void BankRomCheat::evaluate()
|
|||
{
|
||||
if(!myEnabled)
|
||||
{
|
||||
int oldBank = myOSystem.console().cartridge().getBank(address);
|
||||
const int oldBank = myOSystem.console().cartridge().getBank(address);
|
||||
myOSystem.console().cartridge().bank(bank);
|
||||
|
||||
for(int i = 0; i < count; ++i)
|
||||
for(int i = 0; std::cmp_less(i, count); ++i)
|
||||
myOSystem.console().cartridge().patch(address + i, value);
|
||||
|
||||
myOSystem.console().cartridge().bank(oldBank);
|
||||
|
|
|
@ -8,7 +8,7 @@
|
|||
// SS SS tt ee ll ll aa aa
|
||||
// SSSS ttt eeeee llll llll aaaaa
|
||||
//
|
||||
// Copyright (c) 1995-2021 by Bradford W. Mott, Stephen Anthony
|
||||
// Copyright (c) 1995-2025 by Bradford W. Mott, Stephen Anthony
|
||||
// and the Stella Team
|
||||
//
|
||||
// See the file "License.txt" for information on usage and redistribution of
|
||||
|
@ -23,7 +23,7 @@
|
|||
class BankRomCheat : public Cheat
|
||||
{
|
||||
public:
|
||||
BankRomCheat(OSystem& os, const string& name, const string& code);
|
||||
BankRomCheat(OSystem& os, string_view name, string_view code);
|
||||
~BankRomCheat() override = default;
|
||||
|
||||
bool enable() override;
|
||||
|
@ -31,7 +31,7 @@ class BankRomCheat : public Cheat
|
|||
void evaluate() override;
|
||||
|
||||
private:
|
||||
std::array<uInt8, 16> savedRom;
|
||||
std::array<uInt8, 16> savedRom{};
|
||||
uInt16 address{0};
|
||||
uInt8 value{0};
|
||||
uInt8 count{0};
|
||||
|
|
|
@ -8,7 +8,7 @@
|
|||
// SS SS tt ee ll ll aa aa
|
||||
// SSSS ttt eeeee llll llll aaaaa
|
||||
//
|
||||
// Copyright (c) 1995-2021 by Bradford W. Mott, Stephen Anthony
|
||||
// Copyright (c) 1995-2025 by Bradford W. Mott, Stephen Anthony
|
||||
// and the Stella Team
|
||||
//
|
||||
// See the file "License.txt" for information on usage and redistribution of
|
||||
|
@ -25,9 +25,9 @@ class OSystem;
|
|||
class Cheat
|
||||
{
|
||||
public:
|
||||
Cheat(OSystem& osystem, const string& name, const string& code)
|
||||
Cheat(OSystem& osystem, string_view name, string_view code)
|
||||
: myOSystem{osystem},
|
||||
myName{name == "" ? code : name},
|
||||
myName{name.empty() ? code : name},
|
||||
myCode{code} { }
|
||||
virtual ~Cheat() = default;
|
||||
|
||||
|
@ -40,23 +40,6 @@ class Cheat
|
|||
|
||||
virtual void evaluate() = 0;
|
||||
|
||||
protected:
|
||||
static uInt16 unhex(const string& hex)
|
||||
{
|
||||
int ret = 0;
|
||||
for(char c: hex)
|
||||
{
|
||||
ret *= 16;
|
||||
if(c >= '0' && c <= '9')
|
||||
ret += c - '0';
|
||||
else if(c >= 'A' && c <= 'F')
|
||||
ret += c - 'A' + 10;
|
||||
else
|
||||
ret += c - 'a' + 10;
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
protected:
|
||||
OSystem& myOSystem;
|
||||
|
||||
|
|
|
@ -8,7 +8,7 @@
|
|||
// SS SS tt ee ll ll aa aa
|
||||
// SSSS ttt eeeee llll llll aaaaa
|
||||
//
|
||||
// Copyright (c) 1995-2021 by Bradford W. Mott, Stephen Anthony
|
||||
// Copyright (c) 1995-2025 by Bradford W. Mott, Stephen Anthony
|
||||
// and the Stella Team
|
||||
//
|
||||
// See the file "License.txt" for information on usage and redistribution of
|
||||
|
@ -25,7 +25,6 @@
|
|||
#include "Font.hxx"
|
||||
#include "InputTextDialog.hxx"
|
||||
#include "OSystem.hxx"
|
||||
#include "Props.hxx"
|
||||
#include "Widget.hxx"
|
||||
|
||||
#include "CheatCodeDialog.hxx"
|
||||
|
@ -43,16 +42,15 @@ CheatCodeDialog::CheatCodeDialog(OSystem& osystem, DialogContainer& parent,
|
|||
VGAP = Dialog::vGap(),
|
||||
VBORDER = Dialog::vBorder(),
|
||||
HBORDER = Dialog::hBorder();
|
||||
int xpos, ypos;
|
||||
WidgetArray wid;
|
||||
ButtonWidget* b;
|
||||
ButtonWidget* b = nullptr;
|
||||
|
||||
// Set real dimensions
|
||||
_w = 45 * fontWidth + HBORDER * 2;
|
||||
_h = _th + 11 * (lineHeight + 4) + VBORDER * 2;
|
||||
|
||||
// List of cheats, with checkboxes to enable/disable
|
||||
xpos = HBORDER; ypos = _th + VBORDER;
|
||||
int xpos = HBORDER, ypos = _th + VBORDER;
|
||||
myCheatList =
|
||||
new CheckListWidget(this, font, xpos, ypos, _w - buttonWidth - HBORDER * 2 - fontWidth,
|
||||
_h - _th - buttonHeight - VBORDER * 3);
|
||||
|
@ -84,18 +82,18 @@ CheatCodeDialog::CheatCodeDialog(OSystem& osystem, DialogContainer& parent,
|
|||
|
||||
// Inputbox which will pop up when adding/editing a cheat
|
||||
StringList labels;
|
||||
labels.push_back("Name ");
|
||||
labels.push_back("Code (hex) ");
|
||||
labels.emplace_back("Name ");
|
||||
labels.emplace_back("Code (hex) ");
|
||||
myCheatInput = make_unique<InputTextDialog>(this, font, labels, "Cheat code");
|
||||
myCheatInput->setTarget(this);
|
||||
|
||||
// Add filtering for each textfield
|
||||
EditableWidget::TextFilter f0 = [](char c) {
|
||||
const EditableWidget::TextFilter f0 = [](char c) {
|
||||
return isprint(c) && c != '\"' && c != ':';
|
||||
};
|
||||
myCheatInput->setTextFilter(f0, 0);
|
||||
|
||||
EditableWidget::TextFilter f1 = [](char c) {
|
||||
const EditableWidget::TextFilter f1 = [](char c) {
|
||||
return (c >= 'a' && c <= 'f') || (c >= '0' && c <= '9');
|
||||
};
|
||||
myCheatInput->setTextFilter(f1, 1);
|
||||
|
@ -107,10 +105,12 @@ CheatCodeDialog::CheatCodeDialog(OSystem& osystem, DialogContainer& parent,
|
|||
wid.clear();
|
||||
addOKCancelBGroup(wid, font);
|
||||
addBGroupToFocusList(wid);
|
||||
|
||||
setHelpAnchor("Cheats");
|
||||
}
|
||||
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
CheatCodeDialog::~CheatCodeDialog()
|
||||
CheatCodeDialog::~CheatCodeDialog() // NOLINT (we need an empty d'tor)
|
||||
{
|
||||
}
|
||||
|
||||
|
@ -127,14 +127,14 @@ void CheatCodeDialog::loadConfig()
|
|||
for(const auto& c: list)
|
||||
{
|
||||
l.push_back(c->name());
|
||||
b.push_back(bool(c->enabled()));
|
||||
b.push_back(c->enabled());
|
||||
}
|
||||
myCheatList->setList(l, b);
|
||||
|
||||
// Redraw the list, auto-selecting the first item if possible
|
||||
myCheatList->setSelected(l.size() > 0 ? 0 : -1);
|
||||
myCheatList->setSelected(!l.empty() ? 0 : -1);
|
||||
|
||||
bool enabled = (list.size() > 0);
|
||||
const bool enabled = !list.empty();
|
||||
myEditButton->setEnabled(enabled);
|
||||
myRemoveButton->setEnabled(enabled);
|
||||
}
|
||||
|
@ -167,7 +167,7 @@ void CheatCodeDialog::addCheat()
|
|||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
void CheatCodeDialog::editCheat()
|
||||
{
|
||||
int idx = myCheatList->getSelected();
|
||||
const int idx = myCheatList->getSelected();
|
||||
if(idx < 0)
|
||||
return;
|
||||
|
||||
|
@ -232,7 +232,7 @@ void CheatCodeDialog::handleCommand(CommandSender* sender, int cmd,
|
|||
{
|
||||
const string& name = myCheatInput->getResult(0);
|
||||
const string& code = myCheatInput->getResult(1);
|
||||
if(instance().cheat().isValidCode(code))
|
||||
if(CheatManager::isValidCode(code))
|
||||
{
|
||||
myCheatInput->close();
|
||||
instance().cheat().add(name, code);
|
||||
|
@ -247,9 +247,9 @@ void CheatCodeDialog::handleCommand(CommandSender* sender, int cmd,
|
|||
{
|
||||
const string& name = myCheatInput->getResult(0);
|
||||
const string& code = myCheatInput->getResult(1);
|
||||
bool enable = myCheatList->getSelectedState();
|
||||
int idx = myCheatList->getSelected();
|
||||
if(instance().cheat().isValidCode(code))
|
||||
const bool enable = myCheatList->getSelectedState();
|
||||
const int idx = myCheatList->getSelected();
|
||||
if(CheatManager::isValidCode(code))
|
||||
{
|
||||
myCheatInput->close();
|
||||
instance().cheat().add(name, code, enable, idx);
|
||||
|
@ -272,7 +272,7 @@ void CheatCodeDialog::handleCommand(CommandSender* sender, int cmd,
|
|||
{
|
||||
const string& name = myCheatInput->getResult(0);
|
||||
const string& code = myCheatInput->getResult(1);
|
||||
if(instance().cheat().isValidCode(code))
|
||||
if(CheatManager::isValidCode(code))
|
||||
{
|
||||
myCheatInput->close();
|
||||
instance().cheat().addOneShot(name, code);
|
||||
|
|
|
@ -8,7 +8,7 @@
|
|||
// SS SS tt ee ll ll aa aa
|
||||
// SSSS ttt eeeee llll llll aaaaa
|
||||
//
|
||||
// Copyright (c) 1995-2021 by Bradford W. Mott, Stephen Anthony
|
||||
// Copyright (c) 1995-2025 by Bradford W. Mott, Stephen Anthony
|
||||
// and the Stella Team
|
||||
//
|
||||
// See the file "License.txt" for information on usage and redistribution of
|
||||
|
|
|
@ -8,7 +8,7 @@
|
|||
// SS SS tt ee ll ll aa aa
|
||||
// SSSS ttt eeeee llll llll aaaaa
|
||||
//
|
||||
// Copyright (c) 1995-2021 by Bradford W. Mott, Stephen Anthony
|
||||
// Copyright (c) 1995-2025 by Bradford W. Mott, Stephen Anthony
|
||||
// and the Stella Team
|
||||
//
|
||||
// See the file "License.txt" for information on usage and redistribution of
|
||||
|
@ -16,7 +16,6 @@
|
|||
//============================================================================
|
||||
|
||||
#include "OSystem.hxx"
|
||||
#include "Console.hxx"
|
||||
#include "Cheat.hxx"
|
||||
#include "Settings.hxx"
|
||||
#include "CheetahCheat.hxx"
|
||||
|
@ -33,10 +32,10 @@ CheatManager::CheatManager(OSystem& osystem)
|
|||
}
|
||||
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
bool CheatManager::add(const string& name, const string& code,
|
||||
bool CheatManager::add(string_view name, string_view code,
|
||||
bool enable, int idx)
|
||||
{
|
||||
shared_ptr<Cheat> cheat = createCheat(name, code);
|
||||
const shared_ptr<Cheat> cheat = createCheat(name, code);
|
||||
if(!cheat)
|
||||
return false;
|
||||
|
||||
|
@ -68,7 +67,7 @@ bool CheatManager::add(const string& name, const string& code,
|
|||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
void CheatManager::remove(int idx)
|
||||
{
|
||||
if(uInt32(idx) < myCheatList.size())
|
||||
if(static_cast<size_t>(idx) < myCheatList.size())
|
||||
{
|
||||
// This will also remove it from the per-frame list (if applicable)
|
||||
myCheatList[idx]->disable();
|
||||
|
@ -79,7 +78,7 @@ void CheatManager::remove(int idx)
|
|||
}
|
||||
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
void CheatManager::addPerFrame(const string& name, const string& code, bool enable)
|
||||
void CheatManager::addPerFrame(string_view name, string_view code, bool enable)
|
||||
{
|
||||
// The actual cheat will always be in the main list; we look there first
|
||||
shared_ptr<Cheat> cheat;
|
||||
|
@ -93,8 +92,8 @@ void CheatManager::addPerFrame(const string& name, const string& code, bool enab
|
|||
}
|
||||
|
||||
// Make sure there are no duplicates
|
||||
bool found = false;
|
||||
uInt32 i;
|
||||
bool found{false};
|
||||
uInt32 i{0};
|
||||
for(i = 0; i < myPerFrameList.size(); ++i)
|
||||
{
|
||||
if(myPerFrameList[i]->code() == cheat->code())
|
||||
|
@ -117,16 +116,16 @@ void CheatManager::addPerFrame(const string& name, const string& code, bool enab
|
|||
}
|
||||
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
void CheatManager::addOneShot(const string& name, const string& code)
|
||||
void CheatManager::addOneShot(string_view name, string_view code)
|
||||
{
|
||||
// Evaluate this cheat once, and then immediately discard it
|
||||
shared_ptr<Cheat> cheat = createCheat(name, code);
|
||||
const shared_ptr<Cheat> cheat = createCheat(name, code);
|
||||
if(cheat)
|
||||
cheat->evaluate();
|
||||
}
|
||||
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
shared_ptr<Cheat> CheatManager::createCheat(const string& name, const string& code) const
|
||||
shared_ptr<Cheat> CheatManager::createCheat(string_view name, string_view code) const
|
||||
{
|
||||
if(!isValidCode(code))
|
||||
return nullptr;
|
||||
|
@ -136,14 +135,14 @@ shared_ptr<Cheat> CheatManager::createCheat(const string& name, const string& co
|
|||
{
|
||||
case 4: return make_shared<RamCheat>(myOSystem, name, code);
|
||||
case 6: return make_shared<CheetahCheat>(myOSystem, name, code);
|
||||
case 7: return make_shared<BankRomCheat>(myOSystem, name, code);
|
||||
case 7: [[fallthrough]];
|
||||
case 8: return make_shared<BankRomCheat>(myOSystem, name, code);
|
||||
default: return nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
void CheatManager::parse(const string& cheats)
|
||||
void CheatManager::parse(string_view cheats)
|
||||
{
|
||||
StringList s;
|
||||
string::size_type lastPos = cheats.find_first_not_of(',', 0);
|
||||
|
@ -186,6 +185,9 @@ void CheatManager::parse(const string& cheats)
|
|||
code = s[1];
|
||||
add(name, code, s[2] == "1");
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
s.clear();
|
||||
|
||||
|
@ -195,7 +197,7 @@ void CheatManager::parse(const string& cheats)
|
|||
}
|
||||
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
void CheatManager::enable(const string& code, bool enable)
|
||||
void CheatManager::enable(string_view code, bool enable)
|
||||
{
|
||||
for(const auto& cheat: myCheatList)
|
||||
{
|
||||
|
@ -218,18 +220,17 @@ void CheatManager::loadCheatDatabase()
|
|||
catch(...) { return; }
|
||||
|
||||
string line, md5, cheat;
|
||||
string::size_type one, two, three, four;
|
||||
|
||||
// Loop reading cheats
|
||||
while(getline(in, line))
|
||||
{
|
||||
if(line.length() == 0)
|
||||
if(line.empty())
|
||||
continue;
|
||||
|
||||
one = line.find('\"', 0);
|
||||
two = line.find('\"', one + 1);
|
||||
three = line.find('\"', two + 1);
|
||||
four = line.find('\"', three + 1);
|
||||
const string::size_type one = line.find('\"', 0);
|
||||
const string::size_type two = line.find('\"', one + 1);
|
||||
const string::size_type three = line.find('\"', two + 1);
|
||||
const string::size_type four = line.find('\"', three + 1);
|
||||
|
||||
// Invalid line if it doesn't contain 4 quotes
|
||||
if((one == string::npos) || (two == string::npos) ||
|
||||
|
@ -254,14 +255,14 @@ void CheatManager::saveCheatDatabase()
|
|||
|
||||
stringstream out;
|
||||
for(const auto& [md5, cheat]: myCheatMap)
|
||||
out << "\"" << md5 << "\" " << "\"" << cheat << "\"" << endl;
|
||||
out << "\"" << md5 << "\" " << "\"" << cheat << "\"\n";
|
||||
|
||||
try { myOSystem.cheatFile().write(out); }
|
||||
catch(...) { return; }
|
||||
}
|
||||
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
void CheatManager::loadCheats(const string& md5sum)
|
||||
void CheatManager::loadCheats(string_view md5sum)
|
||||
{
|
||||
myPerFrameList.clear();
|
||||
myCheatList.clear();
|
||||
|
@ -270,11 +271,11 @@ void CheatManager::loadCheats(const string& md5sum)
|
|||
// Set up any cheatcodes that was on the command line
|
||||
// (and remove the key from the settings, so they won't get set again)
|
||||
const string& cheats = myOSystem.settings().getString("cheat");
|
||||
if(cheats != "")
|
||||
if(!cheats.empty())
|
||||
myOSystem.settings().setValue("cheat", "");
|
||||
|
||||
const auto& iter = myCheatMap.find(md5sum);
|
||||
if(iter == myCheatMap.end() && cheats == "")
|
||||
if(iter == myCheatMap.end() && cheats.empty())
|
||||
return;
|
||||
|
||||
// Remember the cheats for this ROM
|
||||
|
@ -285,7 +286,7 @@ void CheatManager::loadCheats(const string& md5sum)
|
|||
}
|
||||
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
void CheatManager::saveCheats(const string& md5sum)
|
||||
void CheatManager::saveCheats(string_view md5sum)
|
||||
{
|
||||
ostringstream cheats;
|
||||
for(uInt32 i = 0; i < myCheatList.size(); ++i)
|
||||
|
@ -297,20 +298,20 @@ void CheatManager::saveCheats(const string& md5sum)
|
|||
cheats << ",";
|
||||
}
|
||||
|
||||
bool changed = cheats.str() != myCurrentCheat;
|
||||
const bool changed = cheats.view() != myCurrentCheat;
|
||||
|
||||
// Only update the list if absolutely necessary
|
||||
if(changed)
|
||||
{
|
||||
auto iter = myCheatMap.find(md5sum);
|
||||
const auto iter = myCheatMap.find(md5sum);
|
||||
|
||||
// Erase old entry and add a new one only if it's changed
|
||||
if(iter != myCheatMap.end())
|
||||
myCheatMap.erase(iter);
|
||||
|
||||
// Add new entry only if there are any cheats defined
|
||||
if(cheats.str() != "")
|
||||
myCheatMap.emplace(md5sum, cheats.str());
|
||||
if(!cheats.view().empty())
|
||||
myCheatMap.emplace(md5sum, cheats.view());
|
||||
}
|
||||
|
||||
// Update the dirty flag
|
||||
|
@ -320,12 +321,12 @@ void CheatManager::saveCheats(const string& md5sum)
|
|||
}
|
||||
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
bool CheatManager::isValidCode(const string& code) const
|
||||
bool CheatManager::isValidCode(string_view code)
|
||||
{
|
||||
for(char c: code)
|
||||
for(const auto c: code)
|
||||
if(!isxdigit(c))
|
||||
return false;
|
||||
|
||||
uInt32 length = uInt32(code.length());
|
||||
const size_t length = code.length();
|
||||
return (length == 4 || length == 6 || length == 7 || length == 8);
|
||||
}
|
||||
|
|
|
@ -8,7 +8,7 @@
|
|||
// SS SS tt ee ll ll aa aa
|
||||
// SSSS ttt eeeee llll llll aaaaa
|
||||
//
|
||||
// Copyright (c) 1995-2021 by Bradford W. Mott, Stephen Anthony
|
||||
// Copyright (c) 1995-2025 by Bradford W. Mott, Stephen Anthony
|
||||
// and the Stella Team
|
||||
//
|
||||
// See the file "License.txt" for information on usage and redistribution of
|
||||
|
@ -38,6 +38,7 @@ class CheatManager
|
|||
{
|
||||
public:
|
||||
explicit CheatManager(OSystem& osystem);
|
||||
~CheatManager() = default;
|
||||
|
||||
/**
|
||||
Adds the specified cheat to an internal list.
|
||||
|
@ -49,7 +50,7 @@ class CheatManager
|
|||
|
||||
@return Whether the cheat was created and enabled.
|
||||
*/
|
||||
bool add(const string& name, const string& code,
|
||||
bool add(string_view name, string_view code,
|
||||
bool enable = true, int idx = -1);
|
||||
|
||||
/**
|
||||
|
@ -68,7 +69,7 @@ class CheatManager
|
|||
@param code The actual cheatcode
|
||||
@param enable Add or remove the cheat to the per-frame list
|
||||
*/
|
||||
void addPerFrame(const string& name, const string& code, bool enable);
|
||||
void addPerFrame(string_view name, string_view code, bool enable);
|
||||
|
||||
/**
|
||||
Creates and enables a one-shot cheat. One-shot cheats are the
|
||||
|
@ -78,7 +79,7 @@ class CheatManager
|
|||
@param name Name of the cheat (not absolutely required)
|
||||
@param code The actual cheatcode (in hex)
|
||||
*/
|
||||
void addOneShot(const string& name, const string& code);
|
||||
void addOneShot(string_view name, string_view code);
|
||||
|
||||
/**
|
||||
Enable/disabled the cheat specified by the given code.
|
||||
|
@ -86,7 +87,7 @@ class CheatManager
|
|||
@param code The actual cheatcode to search for
|
||||
@param enable Enable/disable the cheat
|
||||
*/
|
||||
void enable(const string& code, bool enable);
|
||||
void enable(string_view code, bool enable);
|
||||
|
||||
/**
|
||||
Returns the game cheatlist.
|
||||
|
@ -111,17 +112,17 @@ class CheatManager
|
|||
/**
|
||||
Load cheats for ROM with given MD5sum to cheatlist(s).
|
||||
*/
|
||||
void loadCheats(const string& md5sum);
|
||||
void loadCheats(string_view md5sum);
|
||||
|
||||
/**
|
||||
Saves cheats for ROM with given MD5sum to cheat map.
|
||||
*/
|
||||
void saveCheats(const string& md5sum);
|
||||
void saveCheats(string_view md5sum);
|
||||
|
||||
/**
|
||||
Checks if a code is valid.
|
||||
*/
|
||||
bool isValidCode(const string& code) const;
|
||||
static bool isValidCode(string_view code);
|
||||
|
||||
private:
|
||||
/**
|
||||
|
@ -132,14 +133,14 @@ class CheatManager
|
|||
|
||||
@return The cheat (if was created), else nullptr.
|
||||
*/
|
||||
shared_ptr<Cheat> createCheat(const string& name, const string& code) const;
|
||||
shared_ptr<Cheat> createCheat(string_view name, string_view code) const;
|
||||
|
||||
/**
|
||||
Parses a list of cheats and adds/enables each one.
|
||||
|
||||
@param cheats Comma-separated list of cheats (without any names)
|
||||
*/
|
||||
void parse(const string& cheats);
|
||||
void parse(string_view cheats);
|
||||
|
||||
private:
|
||||
OSystem& myOSystem;
|
||||
|
@ -147,7 +148,7 @@ class CheatManager
|
|||
CheatList myCheatList;
|
||||
CheatList myPerFrameList;
|
||||
|
||||
std::map<string,string> myCheatMap;
|
||||
std::map<string,string, std::less<>> myCheatMap;
|
||||
string myCheatFile;
|
||||
|
||||
// This is set each time a new cheat/ROM is loaded, for later
|
||||
|
|
|
@ -8,7 +8,7 @@
|
|||
// SS SS tt ee ll ll aa aa
|
||||
// SSSS ttt eeeee llll llll aaaaa
|
||||
//
|
||||
// Copyright (c) 1995-2021 by Bradford W. Mott, Stephen Anthony
|
||||
// Copyright (c) 1995-2025 by Bradford W. Mott, Stephen Anthony
|
||||
// and the Stella Team
|
||||
//
|
||||
// See the file "License.txt" for information on usage and redistribution of
|
||||
|
@ -21,14 +21,14 @@
|
|||
#include "CheetahCheat.hxx"
|
||||
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
CheetahCheat::CheetahCheat(OSystem& os, const string& name, const string& code)
|
||||
CheetahCheat::CheetahCheat(OSystem& os, string_view name, string_view code)
|
||||
: Cheat(os, name, code),
|
||||
address{uInt16(0xf000 + unhex(code.substr(0, 3)))},
|
||||
value{uInt8(unhex(code.substr(3, 2)))},
|
||||
count{uInt8(unhex(code.substr(5, 1)) + 1)}
|
||||
address{static_cast<uInt16>(0xf000 + BSPF::stoi<16>(code.substr(0, 3)))},
|
||||
value{static_cast<uInt8>(BSPF::stoi<16>(code.substr(3, 2)))},
|
||||
count{static_cast<uInt8>(BSPF::stoi<16>(code.substr(5, 1)) + 1)}
|
||||
{
|
||||
// Back up original data; we need this if the cheat is ever disabled
|
||||
for(int i = 0; i < count; ++i)
|
||||
for(uInt8 i = 0; i < count; ++i)
|
||||
savedRom[i] = myOSystem.console().cartridge().peek(address + i);
|
||||
}
|
||||
|
||||
|
@ -42,7 +42,7 @@ bool CheetahCheat::enable()
|
|||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
bool CheetahCheat::disable()
|
||||
{
|
||||
for(int i = 0; i < count; ++i)
|
||||
for(uInt8 i = 0; i < count; ++i)
|
||||
myOSystem.console().cartridge().patch(address + i, savedRom[i]);
|
||||
|
||||
return myEnabled = false;
|
||||
|
@ -53,7 +53,7 @@ void CheetahCheat::evaluate()
|
|||
{
|
||||
if(!myEnabled)
|
||||
{
|
||||
for(int i = 0; i < count; ++i)
|
||||
for(uInt8 i = 0; i < count; ++i)
|
||||
myOSystem.console().cartridge().patch(address + i, value);
|
||||
|
||||
myEnabled = true;
|
||||
|
|
|
@ -8,7 +8,7 @@
|
|||
// SS SS tt ee ll ll aa aa
|
||||
// SSSS ttt eeeee llll llll aaaaa
|
||||
//
|
||||
// Copyright (c) 1995-2021 by Bradford W. Mott, Stephen Anthony
|
||||
// Copyright (c) 1995-2025 by Bradford W. Mott, Stephen Anthony
|
||||
// and the Stella Team
|
||||
//
|
||||
// See the file "License.txt" for information on usage and redistribution of
|
||||
|
@ -23,7 +23,7 @@
|
|||
class CheetahCheat : public Cheat
|
||||
{
|
||||
public:
|
||||
CheetahCheat(OSystem& os, const string& name, const string& code);
|
||||
CheetahCheat(OSystem& os, string_view name, string_view code);
|
||||
~CheetahCheat() override = default;
|
||||
|
||||
bool enable() override;
|
||||
|
@ -31,7 +31,7 @@ class CheetahCheat : public Cheat
|
|||
void evaluate() override;
|
||||
|
||||
private:
|
||||
std::array<uInt8, 16> savedRom;
|
||||
std::array<uInt8, 16> savedRom{};
|
||||
uInt16 address{0};
|
||||
uInt8 value{0};
|
||||
uInt8 count{0};
|
||||
|
|
|
@ -8,7 +8,7 @@
|
|||
// SS SS tt ee ll ll aa aa
|
||||
// SSSS ttt eeeee llll llll aaaaa
|
||||
//
|
||||
// Copyright (c) 1995-2021 by Bradford W. Mott, Stephen Anthony
|
||||
// Copyright (c) 1995-2025 by Bradford W. Mott, Stephen Anthony
|
||||
// and the Stella Team
|
||||
//
|
||||
// See the file "License.txt" for information on usage and redistribution of
|
||||
|
@ -23,10 +23,10 @@
|
|||
#include "RamCheat.hxx"
|
||||
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
RamCheat::RamCheat(OSystem& os, const string& name, const string& code)
|
||||
RamCheat::RamCheat(OSystem& os, string_view name, string_view code)
|
||||
: Cheat(os, name, code),
|
||||
address{uInt16(unhex(myCode.substr(0, 2)))},
|
||||
value{uInt8(unhex(myCode.substr(2, 2)))}
|
||||
address{static_cast<uInt16>(BSPF::stoi<16>(myCode.substr(0, 2)))},
|
||||
value{static_cast<uInt8>(BSPF::stoi<16>(myCode.substr(2, 2)))}
|
||||
{
|
||||
}
|
||||
|
||||
|
@ -55,5 +55,5 @@ bool RamCheat::disable()
|
|||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
void RamCheat::evaluate()
|
||||
{
|
||||
myOSystem.console().system().poke(address, value);
|
||||
myOSystem.console().system().pokeOob(address, value);
|
||||
}
|
||||
|
|
|
@ -8,7 +8,7 @@
|
|||
// SS SS tt ee ll ll aa aa
|
||||
// SSSS ttt eeeee llll llll aaaaa
|
||||
//
|
||||
// Copyright (c) 1995-2021 by Bradford W. Mott, Stephen Anthony
|
||||
// Copyright (c) 1995-2025 by Bradford W. Mott, Stephen Anthony
|
||||
// and the Stella Team
|
||||
//
|
||||
// See the file "License.txt" for information on usage and redistribution of
|
||||
|
@ -23,7 +23,7 @@
|
|||
class RamCheat : public Cheat
|
||||
{
|
||||
public:
|
||||
RamCheat(OSystem& os, const string& name, const string& code);
|
||||
RamCheat(OSystem& os, string_view name, string_view code);
|
||||
~RamCheat() override = default;
|
||||
|
||||
bool enable() override;
|
||||
|
|
|
@ -7,8 +7,10 @@ MODULE_OBJS := \
|
|||
src/cheat/BankRomCheat.o \
|
||||
src/cheat/RamCheat.o
|
||||
|
||||
MODULE_TEST_OBJS =
|
||||
|
||||
MODULE_DIRS += \
|
||||
src/cheat
|
||||
|
||||
# Include common rules
|
||||
# Include common rules
|
||||
include $(srcdir)/common.rules
|
||||
|
|
|
@ -8,7 +8,7 @@
|
|||
// SS SS tt ee ll ll aa aa
|
||||
// SSSS ttt eeeee llll llll aaaaa
|
||||
//
|
||||
// Copyright (c) 1995-2021 by Bradford W. Mott, Stephen Anthony
|
||||
// Copyright (c) 1995-2025 by Bradford W. Mott, Stephen Anthony
|
||||
// and the Stella Team
|
||||
//
|
||||
// See the file "License.txt" for information on usage and redistribution of
|
||||
|
@ -29,28 +29,32 @@ AudioQueue::AudioQueue(uInt32 fragmentSize, uInt32 capacity, bool isStereo)
|
|||
{
|
||||
const uInt8 sampleSize = myIsStereo ? 2 : 1;
|
||||
|
||||
myFragmentBuffer = make_unique<Int16[]>(myFragmentSize * sampleSize * (capacity + 2));
|
||||
myFragmentBuffer = make_unique<Int16[]>(
|
||||
static_cast<size_t>(myFragmentSize) * sampleSize * (capacity + 2));
|
||||
|
||||
for (uInt32 i = 0; i < capacity; ++i)
|
||||
myFragmentQueue[i] = myAllFragments[i] = myFragmentBuffer.get() + i * sampleSize * myFragmentSize;
|
||||
myFragmentQueue[i] = myAllFragments[i] = myFragmentBuffer.get() +
|
||||
static_cast<size_t>(myFragmentSize) * sampleSize * i;
|
||||
|
||||
myAllFragments[capacity] = myFirstFragmentForEnqueue =
|
||||
myFragmentBuffer.get() + capacity * sampleSize * myFragmentSize;
|
||||
myFragmentBuffer.get() + static_cast<size_t>(myFragmentSize) * sampleSize *
|
||||
capacity;
|
||||
|
||||
myAllFragments[capacity + 1] = myFirstFragmentForDequeue =
|
||||
myFragmentBuffer.get() + (capacity + 1) * sampleSize * myFragmentSize;
|
||||
myFragmentBuffer.get() + static_cast<size_t>(myFragmentSize) * sampleSize *
|
||||
(capacity + 1);
|
||||
}
|
||||
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
uInt32 AudioQueue::capacity() const
|
||||
{
|
||||
return uInt32(myFragmentQueue.size());
|
||||
return static_cast<uInt32>(myFragmentQueue.size());
|
||||
}
|
||||
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
uInt32 AudioQueue::size() const
|
||||
{
|
||||
lock_guard<mutex> guard(myMutex);
|
||||
const lock_guard<mutex> guard(myMutex);
|
||||
|
||||
return mySize;
|
||||
}
|
||||
|
@ -70,9 +74,9 @@ uInt32 AudioQueue::fragmentSize() const
|
|||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
Int16* AudioQueue::enqueue(Int16* fragment)
|
||||
{
|
||||
lock_guard<mutex> guard(myMutex);
|
||||
const lock_guard<mutex> guard(myMutex);
|
||||
|
||||
Int16* newFragment;
|
||||
Int16* newFragment = nullptr;
|
||||
|
||||
if (!fragment) {
|
||||
if (!myFirstFragmentForEnqueue) throw runtime_error("enqueue called empty");
|
||||
|
@ -83,7 +87,7 @@ Int16* AudioQueue::enqueue(Int16* fragment)
|
|||
return newFragment;
|
||||
}
|
||||
|
||||
const uInt8 capacity = uInt8(myFragmentQueue.size());
|
||||
const auto capacity = static_cast<uInt8>(myFragmentQueue.size());
|
||||
const uInt8 fragmentIndex = (myNextFragment + mySize) % capacity;
|
||||
|
||||
newFragment = myFragmentQueue.at(fragmentIndex);
|
||||
|
@ -101,7 +105,7 @@ Int16* AudioQueue::enqueue(Int16* fragment)
|
|||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
Int16* AudioQueue::dequeue(Int16* fragment)
|
||||
{
|
||||
lock_guard<mutex> guard(myMutex);
|
||||
const lock_guard<mutex> guard(myMutex);
|
||||
|
||||
if (mySize == 0) return nullptr;
|
||||
|
||||
|
@ -124,7 +128,7 @@ Int16* AudioQueue::dequeue(Int16* fragment)
|
|||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
void AudioQueue::closeSink(Int16* fragment)
|
||||
{
|
||||
lock_guard<mutex> guard(myMutex);
|
||||
const lock_guard<mutex> guard(myMutex);
|
||||
|
||||
if (myFirstFragmentForDequeue && fragment)
|
||||
throw runtime_error("attempt to return unknown buffer on closeSink");
|
||||
|
|
|
@ -8,7 +8,7 @@
|
|||
// SS SS tt ee ll ll aa aa
|
||||
// SSSS ttt eeeee llll llll aaaaa
|
||||
//
|
||||
// Copyright (c) 1995-2021 by Bradford W. Mott, Stephen Anthony
|
||||
// Copyright (c) 1995-2025 by Bradford W. Mott, Stephen Anthony
|
||||
// and the Stella Team
|
||||
//
|
||||
// See the file "License.txt" for information on usage and redistribution of
|
||||
|
@ -24,7 +24,7 @@
|
|||
#include "StaggeredLogger.hxx"
|
||||
|
||||
/**
|
||||
This class implements a an audio queue that acts both like a ring buffer
|
||||
This class implements an audio queue that acts both like a ring buffer
|
||||
and a pool of audio fragments. The TIA emulation core fills a fragment
|
||||
with samples and then returns it to the queue, receiving a new fragment
|
||||
in return. The sound driver removes fragments for playback from the
|
||||
|
@ -46,6 +46,7 @@ class AudioQueue
|
|||
@param isStereo Whether samples are stereo or mono.
|
||||
*/
|
||||
AudioQueue(uInt32 fragmentSize, uInt32 capacity, bool isStereo);
|
||||
~AudioQueue() = default;
|
||||
|
||||
/**
|
||||
Capacity getter.
|
||||
|
@ -133,7 +134,6 @@ class AudioQueue
|
|||
StaggeredLogger myOverflowLogger{"audio buffer overflow", Logger::Level::INFO};
|
||||
|
||||
private:
|
||||
|
||||
AudioQueue() = delete;
|
||||
AudioQueue(const AudioQueue&) = delete;
|
||||
AudioQueue(AudioQueue&&) = delete;
|
||||
|
|
|
@ -8,7 +8,7 @@
|
|||
// SS SS tt ee ll ll aa aa
|
||||
// SSSS ttt eeeee llll llll aaaaa
|
||||
//
|
||||
// Copyright (c) 1995-2021 by Bradford W. Mott, Stephen Anthony
|
||||
// Copyright (c) 1995-2025 by Bradford W. Mott, Stephen Anthony
|
||||
// and the Stella Team
|
||||
//
|
||||
// See the file "License.txt" for information on usage and redistribution of
|
||||
|
@ -19,12 +19,12 @@
|
|||
#include "Settings.hxx"
|
||||
|
||||
namespace {
|
||||
uInt32 lboundInt(int x, int defaultValue)
|
||||
constexpr uInt32 lboundInt(int x, int defaultValue)
|
||||
{
|
||||
return x <= 0 ? defaultValue : x;
|
||||
}
|
||||
|
||||
AudioSettings::Preset normalizedPreset(int numericPreset)
|
||||
constexpr AudioSettings::Preset normalizedPreset(int numericPreset)
|
||||
{
|
||||
return (
|
||||
numericPreset >= static_cast<int>(AudioSettings::Preset::custom) &&
|
||||
|
@ -32,14 +32,14 @@ namespace {
|
|||
) ? static_cast<AudioSettings::Preset>(numericPreset) : AudioSettings::DEFAULT_PRESET;
|
||||
}
|
||||
|
||||
AudioSettings::ResamplingQuality normalizeResamplingQuality(int numericResamplingQuality)
|
||||
constexpr AudioSettings::ResamplingQuality normalizeResamplingQuality(int numericResamplingQuality)
|
||||
{
|
||||
return (
|
||||
numericResamplingQuality >= static_cast<int>(AudioSettings::ResamplingQuality::nearestNeightbour) &&
|
||||
numericResamplingQuality >= static_cast<int>(AudioSettings::ResamplingQuality::nearestNeighbour) &&
|
||||
numericResamplingQuality <= static_cast<int>(AudioSettings::ResamplingQuality::lanczos_3)
|
||||
) ? static_cast<AudioSettings::ResamplingQuality>(numericResamplingQuality) : AudioSettings::DEFAULT_RESAMPLING_QUALITY;
|
||||
}
|
||||
}
|
||||
} // namespace
|
||||
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
AudioSettings::AudioSettings(Settings& settings)
|
||||
|
@ -51,9 +51,10 @@ AudioSettings::AudioSettings(Settings& settings)
|
|||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
void AudioSettings::normalize(Settings& settings)
|
||||
{
|
||||
int settingPreset = settings.getInt(SETTING_PRESET);
|
||||
Preset preset = normalizedPreset(settingPreset);
|
||||
if (static_cast<int>(preset) != settingPreset) settings.setValue(SETTING_PRESET, static_cast<int>(DEFAULT_PRESET));
|
||||
const int settingPreset = settings.getInt(SETTING_PRESET);
|
||||
const Preset preset = normalizedPreset(settingPreset);
|
||||
if (static_cast<int>(preset) != settingPreset)
|
||||
settings.setValue(SETTING_PRESET, static_cast<int>(DEFAULT_PRESET));
|
||||
|
||||
switch (settings.getInt(SETTING_SAMPLE_RATE)) {
|
||||
case 44100:
|
||||
|
@ -80,18 +81,19 @@ void AudioSettings::normalize(Settings& settings)
|
|||
break;
|
||||
}
|
||||
|
||||
int settingBufferSize = settings.getInt(SETTING_BUFFER_SIZE);
|
||||
const int settingBufferSize = settings.getInt(SETTING_BUFFER_SIZE);
|
||||
if (settingBufferSize < 0 || settingBufferSize > MAX_BUFFER_SIZE) settings.setValue(SETTING_BUFFER_SIZE, DEFAULT_BUFFER_SIZE);
|
||||
|
||||
int settingHeadroom = settings.getInt(SETTING_HEADROOM);
|
||||
const int settingHeadroom = settings.getInt(SETTING_HEADROOM);
|
||||
if (settingHeadroom < 0 || settingHeadroom > MAX_HEADROOM) settings.setValue(SETTING_HEADROOM, DEFAULT_HEADROOM);
|
||||
|
||||
int settingResamplingQuality = settings.getInt(SETTING_RESAMPLING_QUALITY);
|
||||
ResamplingQuality resamplingQuality = normalizeResamplingQuality(settingResamplingQuality);
|
||||
const int settingResamplingQuality = settings.getInt(SETTING_RESAMPLING_QUALITY);
|
||||
const ResamplingQuality resamplingQuality =
|
||||
normalizeResamplingQuality(settingResamplingQuality);
|
||||
if (static_cast<int>(resamplingQuality) != settingResamplingQuality)
|
||||
settings.setValue(SETTING_RESAMPLING_QUALITY, static_cast<int>(DEFAULT_RESAMPLING_QUALITY));
|
||||
|
||||
int settingVolume = settings.getInt(SETTING_VOLUME);
|
||||
const int settingVolume = settings.getInt(SETTING_VOLUME);
|
||||
if (settingVolume < 0 || settingVolume > 100) settings.setValue(SETTING_VOLUME, DEFAULT_VOLUME);
|
||||
}
|
||||
|
||||
|
@ -186,7 +188,7 @@ void AudioSettings::setPreset(AudioSettings::Preset preset)
|
|||
myPresetFragmentSize = 1024;
|
||||
myPresetBufferSize = 6;
|
||||
myPresetHeadroom = 5;
|
||||
myPresetResamplingQuality = ResamplingQuality::nearestNeightbour;
|
||||
myPresetResamplingQuality = ResamplingQuality::nearestNeighbour;
|
||||
break;
|
||||
|
||||
case Preset::highQualityMediumLag:
|
||||
|
|
|
@ -8,7 +8,7 @@
|
|||
// SS SS tt ee ll ll aa aa
|
||||
// SSSS ttt eeeee llll llll aaaaa
|
||||
//
|
||||
// Copyright (c) 1995-2021 by Bradford W. Mott, Stephen Anthony
|
||||
// Copyright (c) 1995-2025 by Bradford W. Mott, Stephen Anthony
|
||||
// and the Stella Team
|
||||
//
|
||||
// See the file "License.txt" for information on usage and redistribution of
|
||||
|
@ -26,7 +26,7 @@ class AudioSettings
|
|||
{
|
||||
public:
|
||||
|
||||
enum class Preset {
|
||||
enum class Preset: uInt8 {
|
||||
custom = 1,
|
||||
lowQualityMediumLag = 2,
|
||||
highQualityMediumLag = 3,
|
||||
|
@ -34,23 +34,23 @@ class AudioSettings
|
|||
ultraQualityMinimalLag = 5
|
||||
};
|
||||
|
||||
enum class ResamplingQuality {
|
||||
nearestNeightbour = 1,
|
||||
lanczos_2 = 2,
|
||||
lanczos_3 = 3
|
||||
enum class ResamplingQuality: uInt8 {
|
||||
nearestNeighbour = 1,
|
||||
lanczos_2 = 2,
|
||||
lanczos_3 = 3
|
||||
};
|
||||
|
||||
static constexpr const char* SETTING_PRESET = "audio.preset";
|
||||
static constexpr const char* SETTING_SAMPLE_RATE = "audio.sample_rate";
|
||||
static constexpr const char* SETTING_FRAGMENT_SIZE = "audio.fragment_size";
|
||||
static constexpr const char* SETTING_BUFFER_SIZE = "audio.buffer_size";
|
||||
static constexpr const char* SETTING_HEADROOM = "audio.headroom";
|
||||
static constexpr const char* SETTING_RESAMPLING_QUALITY = "audio.resampling_quality";
|
||||
static constexpr const char* SETTING_STEREO = "audio.stereo";
|
||||
static constexpr const char* SETTING_VOLUME = "audio.volume";
|
||||
static constexpr const char* SETTING_DEVICE = "audio.device";
|
||||
static constexpr const char* SETTING_ENABLED = "audio.enabled";
|
||||
static constexpr const char* SETTING_DPC_PITCH = "audio.dpc_pitch";
|
||||
static constexpr string_view SETTING_PRESET = "audio.preset";
|
||||
static constexpr string_view SETTING_SAMPLE_RATE = "audio.sample_rate";
|
||||
static constexpr string_view SETTING_FRAGMENT_SIZE = "audio.fragment_size";
|
||||
static constexpr string_view SETTING_BUFFER_SIZE = "audio.buffer_size";
|
||||
static constexpr string_view SETTING_HEADROOM = "audio.headroom";
|
||||
static constexpr string_view SETTING_RESAMPLING_QUALITY = "audio.resampling_quality";
|
||||
static constexpr string_view SETTING_STEREO = "audio.stereo";
|
||||
static constexpr string_view SETTING_VOLUME = "audio.volume";
|
||||
static constexpr string_view SETTING_DEVICE = "audio.device";
|
||||
static constexpr string_view SETTING_ENABLED = "audio.enabled";
|
||||
static constexpr string_view SETTING_DPC_PITCH = "audio.dpc_pitch";
|
||||
|
||||
static constexpr Preset DEFAULT_PRESET = Preset::highQualityMediumLag;
|
||||
static constexpr uInt32 DEFAULT_SAMPLE_RATE = 44100;
|
||||
|
@ -127,7 +127,7 @@ class AudioSettings
|
|||
|
||||
private:
|
||||
|
||||
Settings& mySettings;
|
||||
Settings& mySettings; // NOLINT: we want a reference here
|
||||
|
||||
Preset myPreset{Preset::custom};
|
||||
|
||||
|
@ -135,7 +135,7 @@ class AudioSettings
|
|||
uInt32 myPresetFragmentSize{0};
|
||||
uInt32 myPresetBufferSize{0};
|
||||
uInt32 myPresetHeadroom{0};
|
||||
ResamplingQuality myPresetResamplingQuality{ResamplingQuality::nearestNeightbour};
|
||||
ResamplingQuality myPresetResamplingQuality{ResamplingQuality::nearestNeighbour};
|
||||
|
||||
bool myIsPersistent{true};
|
||||
};
|
||||
|
|
|
@ -8,7 +8,7 @@
|
|||
// SS SS tt ee ll ll aa aa
|
||||
// SSSS ttt eeeee llll llll aaaaa
|
||||
//
|
||||
// Copyright (c) 1995-2021 by Bradford W. Mott, Stephen Anthony
|
||||
// Copyright (c) 1995-2025 by Bradford W. Mott, Stephen Anthony
|
||||
// and the Stella Team
|
||||
//
|
||||
// See the file "License.txt" for information on usage and redistribution of
|
||||
|
@ -24,7 +24,7 @@ string Base::toString(int value, Common::Base::Fmt outputBase)
|
|||
{
|
||||
static char vToS_buf[32]; // NOLINT : One place where C-style is acceptable
|
||||
|
||||
if(outputBase == Base::Fmt::_DEFAULT)
|
||||
if(outputBase == Base::Fmt::DEFAULT)
|
||||
outputBase = myDefaultBase;
|
||||
|
||||
switch(outputBase)
|
||||
|
@ -47,74 +47,83 @@ string Base::toString(int value, Common::Base::Fmt outputBase)
|
|||
|
||||
case Base::Fmt::_10: // base 10: 3 or 5 bytes (depending on value)
|
||||
if(value > -0x100 && value < 0x100)
|
||||
std::snprintf(vToS_buf, 5, "%3d", Int16(value));
|
||||
std::ignore = std::snprintf(vToS_buf, 5, "%3d", static_cast<Int16>(value));
|
||||
else
|
||||
std::snprintf(vToS_buf, 6, "%5d", value);
|
||||
std::ignore = std::snprintf(vToS_buf, 6, "%5d", value);
|
||||
break;
|
||||
|
||||
case Base::Fmt::_10_02: // base 10: 2 digits (with leading zero)
|
||||
std::snprintf(vToS_buf, 3, "%02d", value);
|
||||
std::ignore = std::snprintf(vToS_buf, 3, "%02d", value);
|
||||
break;
|
||||
|
||||
case Base::Fmt::_10_3: // base 10: 3 digits
|
||||
std::snprintf(vToS_buf, 4, "%3d", value);
|
||||
std::ignore = std::snprintf(vToS_buf, 4, "%3d", value);
|
||||
break;
|
||||
|
||||
case Base::Fmt::_10_4: // base 10: 4 digits
|
||||
std::snprintf(vToS_buf, 5, "%4d", value);
|
||||
std::ignore = std::snprintf(vToS_buf, 5, "%4d", value);
|
||||
break;
|
||||
|
||||
case Base::Fmt::_10_5: // base 10: 5 digits
|
||||
std::snprintf(vToS_buf, 6, "%5d", value);
|
||||
std::ignore = std::snprintf(vToS_buf, 6, "%5d", value);
|
||||
break;
|
||||
|
||||
case Base::Fmt::_10_6: // base 10: 6 digits
|
||||
std::snprintf(vToS_buf, 7, "%6d", value);
|
||||
std::ignore = std::snprintf(vToS_buf, 7, "%6d", value);
|
||||
break;
|
||||
|
||||
case Base::Fmt::_10_8: // base 10: 8 digits
|
||||
std::snprintf(vToS_buf, 9, "%8d", value);
|
||||
std::ignore = std::snprintf(vToS_buf, 9, "%8d", value);
|
||||
break;
|
||||
|
||||
case Base::Fmt::_16_1: // base 16: 1 byte wide
|
||||
std::snprintf(vToS_buf, 2, hexUppercase() ? "%1X" : "%1x", value);
|
||||
std::ignore = std::snprintf(
|
||||
vToS_buf, 2, hexUppercase() ? "%1X" : "%1x", value);
|
||||
break;
|
||||
case Base::Fmt::_16_2: // base 16: 2 bytes wide
|
||||
std::snprintf(vToS_buf, 3, hexUppercase() ? "%02X" : "%02x", value);
|
||||
std::ignore = std::snprintf(
|
||||
vToS_buf, 3, hexUppercase() ? "%02X" : "%02x", value);
|
||||
break;
|
||||
case Base::Fmt::_16_2_2:
|
||||
std::snprintf(vToS_buf, 6, hexUppercase() ? "%02X.%02X" : "%02x.%02x",
|
||||
value >> 8, value & 0xff );
|
||||
std::ignore = std::snprintf(
|
||||
vToS_buf, 6, hexUppercase() ? "%02X.%02X" : "%02x.%02x",
|
||||
value >> 8, value & 0xff );
|
||||
break;
|
||||
case Base::Fmt::_16_3_2:
|
||||
std::snprintf(vToS_buf, 7, hexUppercase() ? "%03X.%02X" : "%03x.%02x",
|
||||
value >> 8, value & 0xff );
|
||||
std::ignore = std::snprintf(
|
||||
vToS_buf, 7, hexUppercase() ? "%03X.%02X" : "%03x.%02x",
|
||||
value >> 8, value & 0xff );
|
||||
break;
|
||||
case Base::Fmt::_16_4: // base 16: 4 bytes wide
|
||||
std::snprintf(vToS_buf, 5, hexUppercase() ? "%04X" : "%04x", value);
|
||||
std::ignore = std::snprintf(
|
||||
vToS_buf, 5, hexUppercase() ? "%04X" : "%04x", value);
|
||||
break;
|
||||
case Base::Fmt::_16_8: // base 16: 8 bytes wide
|
||||
std::snprintf(vToS_buf, 9, hexUppercase() ? "%08X" : "%08x", value);
|
||||
std::ignore = std::snprintf(
|
||||
vToS_buf, 9, hexUppercase() ? "%08X" : "%08x", value);
|
||||
break;
|
||||
|
||||
case Base::Fmt::_16: // base 16: 2, 4, 8 bytes (depending on value)
|
||||
default:
|
||||
if(value < 0x100)
|
||||
std::snprintf(vToS_buf, 3, hexUppercase() ? "%02X" : "%02x", value);
|
||||
std::ignore = std::snprintf(
|
||||
vToS_buf, 3, hexUppercase() ? "%02X" : "%02x", value);
|
||||
else if(value < 0x10000)
|
||||
std::snprintf(vToS_buf, 5, hexUppercase() ? "%04X" : "%04x", value);
|
||||
std::ignore = std::snprintf(
|
||||
vToS_buf, 5, hexUppercase() ? "%04X" : "%04x", value);
|
||||
else
|
||||
std::snprintf(vToS_buf, 9, hexUppercase() ? "%08X" : "%08x", value);
|
||||
std::ignore = std::snprintf(
|
||||
vToS_buf, 9, hexUppercase() ? "%08X" : "%08x", value);
|
||||
break;
|
||||
}
|
||||
|
||||
return string(vToS_buf);
|
||||
return {vToS_buf};
|
||||
}
|
||||
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
Base::Fmt Base::myDefaultBase = Base::Fmt::_16;
|
||||
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
std::ios_base::fmtflags Base::myHexflags = std::ios_base::hex;
|
||||
std::ios_base::fmtflags Base::myHexflags = std::ios_base::hex; // NOLINT
|
||||
|
||||
} // Namespace Common
|
||||
} // namespace Common
|
||||
|
|
|
@ -8,7 +8,7 @@
|
|||
// SS SS tt ee ll ll aa aa
|
||||
// SSSS ttt eeeee llll llll aaaaa
|
||||
//
|
||||
// Copyright (c) 1995-2021 by Bradford W. Mott, Stephen Anthony
|
||||
// Copyright (c) 1995-2025 by Bradford W. Mott, Stephen Anthony
|
||||
// and the Stella Team
|
||||
//
|
||||
// See the file "License.txt" for information on usage and redistribution of
|
||||
|
@ -38,7 +38,7 @@ class Base
|
|||
// The base to use for conversion from integers to strings
|
||||
// Note that the actual number of places will be determined by
|
||||
// the magnitude of the value itself in the general case
|
||||
enum class Fmt {
|
||||
enum class Fmt: uInt8 {
|
||||
_16, // base 16: 2, 4, 8 bytes (depending on value)
|
||||
_16_1, // base 16: 1 byte wide
|
||||
_16_2, // base 16: 2 bytes wide
|
||||
|
@ -56,7 +56,7 @@ class Base
|
|||
_2, // base 2: 8 or 16 bits (depending on value)
|
||||
_2_8, // base 2: 1 byte (8 bits) wide
|
||||
_2_16, // base 2: 2 bytes (16 bits) wide
|
||||
_DEFAULT
|
||||
DEFAULT
|
||||
};
|
||||
|
||||
public:
|
||||
|
@ -72,31 +72,31 @@ class Base
|
|||
static bool hexUppercase() { return myHexflags & std::ios_base::uppercase; }
|
||||
|
||||
/** Output HEX digits in 0.5/1/2/4 byte format */
|
||||
static inline std::ostream& HEX1(std::ostream& os) {
|
||||
static std::ostream& HEX1(std::ostream& os) {
|
||||
os.flags(myHexflags);
|
||||
return os << std::setw(1);
|
||||
}
|
||||
static inline std::ostream& HEX2(std::ostream& os) {
|
||||
static std::ostream& HEX2(std::ostream& os) {
|
||||
os.flags(myHexflags);
|
||||
return os << std::setw(2) << std::setfill('0');
|
||||
}
|
||||
static inline std::ostream& HEX3(std::ostream& os)
|
||||
static std::ostream& HEX3(std::ostream& os)
|
||||
{
|
||||
os.flags(myHexflags);
|
||||
return os << std::setw(3) << std::setfill('0');
|
||||
}
|
||||
static inline std::ostream& HEX4(std::ostream& os) {
|
||||
static std::ostream& HEX4(std::ostream& os) {
|
||||
os.flags(myHexflags);
|
||||
return os << std::setw(4) << std::setfill('0');
|
||||
}
|
||||
static inline std::ostream& HEX8(std::ostream& os) {
|
||||
static std::ostream& HEX8(std::ostream& os) {
|
||||
os.flags(myHexflags);
|
||||
return os << std::setw(8) << std::setfill('0');
|
||||
}
|
||||
|
||||
/** Convert integer to a string in the given base format */
|
||||
static string toString(int value,
|
||||
Common::Base::Fmt outputBase = Common::Base::Fmt::_DEFAULT);
|
||||
Common::Base::Fmt outputBase = Common::Base::Fmt::DEFAULT);
|
||||
|
||||
private:
|
||||
// Default format to use when none is specified
|
||||
|
@ -108,6 +108,7 @@ class Base
|
|||
private:
|
||||
// Following constructors and assignment operators not supported
|
||||
Base() = delete;
|
||||
~Base() = delete;
|
||||
Base(const Base&) = delete;
|
||||
Base(Base&&) = delete;
|
||||
Base& operator=(const Base&) = delete;
|
||||
|
|
|
@ -0,0 +1,252 @@
|
|||
//============================================================================
|
||||
//
|
||||
// SSSS tt lll lll
|
||||
// SS SS tt ll ll
|
||||
// SS tttttt eeee ll ll aaaa
|
||||
// SSSS tt ee ee ll ll aa
|
||||
// SS tt eeeeee ll ll aaaaa -- "An Atari 2600 VCS Emulator"
|
||||
// SS SS tt ee ll ll aa aa
|
||||
// SSSS ttt eeeee llll llll aaaaa
|
||||
//
|
||||
// Copyright (c) 1995-2025 by Bradford W. Mott, Stephen Anthony
|
||||
// and the Stella Team
|
||||
//
|
||||
// See the file "License.txt" for information on usage and redistribution of
|
||||
// this file, and for a DISCLAIMER OF ALL WARRANTIES.
|
||||
//============================================================================
|
||||
|
||||
#include <cmath>
|
||||
|
||||
#include "OSystem.hxx"
|
||||
#include "Console.hxx"
|
||||
#include "EventHandler.hxx"
|
||||
#include "FBSurface.hxx"
|
||||
#include "PNGLibrary.hxx"
|
||||
#include "PropsSet.hxx"
|
||||
|
||||
#include "Bezel.hxx"
|
||||
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
Bezel::Bezel(OSystem& osystem)
|
||||
: myOSystem{osystem},
|
||||
myFB{osystem.frameBuffer()}
|
||||
{
|
||||
}
|
||||
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
string Bezel::getName(const string& path, const Properties& props)
|
||||
{
|
||||
string imageName;
|
||||
int index = 1; // skip property name
|
||||
|
||||
do
|
||||
{
|
||||
imageName = getName(props, index);
|
||||
if(imageName != EmptyString)
|
||||
{
|
||||
// Note: JPG does not support transparency
|
||||
const string imagePath = path + imageName + ".png";
|
||||
const FSNode node(imagePath);
|
||||
if(node.exists())
|
||||
break;
|
||||
}
|
||||
} while(index != -1);
|
||||
|
||||
return imageName;
|
||||
}
|
||||
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
string Bezel::getName(const Properties& props, int& index)
|
||||
{
|
||||
if(++index == 1)
|
||||
return props.get(PropType::Bezel_Name);
|
||||
|
||||
// Try to generate bezel name from cart name
|
||||
const string& cartName = props.get(PropType::Cart_Name);
|
||||
size_t pos = cartName.find_first_of('(');
|
||||
if(pos == std::string::npos)
|
||||
pos = cartName.length() + 1;
|
||||
if(index < 10 && pos != std::string::npos && pos > 0)
|
||||
{
|
||||
// The following suffixes are from "The Official No-Intro Convention",
|
||||
// covering all used combinations by "The Bezel Project" (except single ones)
|
||||
// (Unl) = unlicensed (Homebrews)
|
||||
const std::array<string, 8> suffixes = {
|
||||
" (USA)", " (USA) (Proto)", " (USA) (Unl)", " (USA) (Hack)",
|
||||
" (Europe)", " (Germany)", " (France) (Unl)", " (Australia)"
|
||||
};
|
||||
return cartName.substr(0, pos - 1) + suffixes[index - 2];
|
||||
}
|
||||
|
||||
if(index == 10)
|
||||
{
|
||||
return "Atari-2600";
|
||||
}
|
||||
|
||||
if(index == 11)
|
||||
{
|
||||
index = -1;
|
||||
return "default";
|
||||
}
|
||||
return "";
|
||||
}
|
||||
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
string Bezel::getName(int& index) const
|
||||
{
|
||||
return getName(myOSystem.console().properties(), index);
|
||||
}
|
||||
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
uInt32 Bezel::borderSize(uInt32 x, uInt32 y, uInt32 size, Int32 step) const
|
||||
{
|
||||
uInt32 *pixels{nullptr}, pitch{0};
|
||||
|
||||
mySurface->basePtr(pixels, pitch);
|
||||
pixels += x + y * pitch;
|
||||
|
||||
for(uInt32 i = 0; i < size; ++i, pixels += step)
|
||||
{
|
||||
uInt8 r{0}, g{0}, b{0}, a{0};
|
||||
|
||||
myFB.getRGBA(*pixels, &r, &g, &b, &a);
|
||||
if(a < 255) // transparent pixel?
|
||||
return i;
|
||||
}
|
||||
return size - 1;
|
||||
}
|
||||
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
bool Bezel::load()
|
||||
{
|
||||
const Settings& settings = myOSystem.settings();
|
||||
bool isValid = false;
|
||||
string imageName;
|
||||
|
||||
#ifdef IMAGE_SUPPORT
|
||||
const bool show = myOSystem.eventHandler().inTIAMode() &&
|
||||
settings.getBool("bezel.show") &&
|
||||
(settings.getBool("fullscreen") ||
|
||||
settings.getBool("bezel.windowed"));
|
||||
|
||||
if(show)
|
||||
{
|
||||
if(!mySurface)
|
||||
mySurface = myFB.allocateSurface(1, 1); // dummy size
|
||||
try
|
||||
{
|
||||
const string& path = myOSystem.bezelDir().getPath();
|
||||
VariantList metaData;
|
||||
int index = 0;
|
||||
|
||||
do
|
||||
{
|
||||
imageName = getName(index);
|
||||
if(imageName != EmptyString)
|
||||
{
|
||||
// Note: JPG does not support transparency
|
||||
const string imagePath = path + imageName + ".png";
|
||||
const FSNode node(imagePath);
|
||||
if(node.exists())
|
||||
{
|
||||
isValid = true;
|
||||
myOSystem.png().loadImage(imagePath, *mySurface, metaData);
|
||||
break;
|
||||
}
|
||||
}
|
||||
} while(index != -1);
|
||||
}
|
||||
catch(const runtime_error&) { cerr << "ERROR: Bezel load\n"; }
|
||||
}
|
||||
#else
|
||||
const bool show = false;
|
||||
#endif
|
||||
if(isValid)
|
||||
{
|
||||
const Int32 w = mySurface->width();
|
||||
const Int32 h = mySurface->height();
|
||||
uInt32 top{0}, bottom{0}, left{0}, right{0};
|
||||
|
||||
if(settings.getBool("bezel.win.auto"))
|
||||
{
|
||||
// Determine transparent window inside bezel image
|
||||
const uInt32 xCenter = w >> 1;
|
||||
top = borderSize(xCenter, 0, h, w);
|
||||
bottom = h - 1 - borderSize(xCenter, h - 1, h, -w);
|
||||
const uInt32 yCenter = (bottom + top) >> 1;
|
||||
left = borderSize(0, yCenter, w, 1);
|
||||
right = w - 1 - borderSize(w - 1, yCenter, w, -1);
|
||||
}
|
||||
else
|
||||
{
|
||||
// BP: 13, 13, 0, 0%
|
||||
// HY: 12, 12, 0, 0%
|
||||
// P1: 25, 25, 11, 22%
|
||||
// P2: 23, 23, 7, 20%
|
||||
left = std::min(w - 1, static_cast<Int32>(w * settings.getInt("bezel.win.left") / 100. + .5)); // NOLINT
|
||||
right = w - 1 - std::min(w - 1, static_cast<Int32>(w * settings.getInt("bezel.win.right") / 100. + .5)); // NOLINT
|
||||
top = std::min(h - 1, static_cast<Int32>(h * settings.getInt("bezel.win.top") / 100. + .5)); // NOLINT
|
||||
bottom = h - 1 - std::min(h - 1, static_cast<Int32>(h * settings.getInt("bezel.win.bottom") / 100. + .5)); // NOLINT
|
||||
}
|
||||
|
||||
//cerr << (int)(right - left + 1) << " x " << (int)(bottom - top + 1) << " = "
|
||||
// << double((int)(right - left + 1)) / double((int)(bottom - top + 1));
|
||||
|
||||
// Disable bezel is no transparent window was found
|
||||
if(left < right && top < bottom)
|
||||
myInfo = Info(Common::Size(w, h), Common::Rect(left, top, right, bottom));
|
||||
else
|
||||
{
|
||||
if(mySurface)
|
||||
myFB.deallocateSurface(mySurface);
|
||||
mySurface = nullptr;
|
||||
myInfo = Info();
|
||||
myFB.showTextMessage("Invalid bezel image ('" + imageName + "')!");
|
||||
isValid = false;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
myInfo = Info();
|
||||
if(show)
|
||||
myFB.showTextMessage("No bezel image found");
|
||||
}
|
||||
return isValid;
|
||||
}
|
||||
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
void Bezel::apply()
|
||||
{
|
||||
if(isShown())
|
||||
{
|
||||
const uInt32 bezelW =
|
||||
std::min(myFB.screenSize().w,
|
||||
static_cast<uInt32>(std::round(myFB.imageRect().w() * myInfo.ratioW())));
|
||||
const uInt32 bezelH =
|
||||
std::min(myFB.screenSize().h,
|
||||
static_cast<uInt32>(std::round(myFB.imageRect().h() * myInfo.ratioH())));
|
||||
|
||||
// Position and scale bezel
|
||||
mySurface->setDstSize(bezelW, bezelH);
|
||||
mySurface->setDstPos((myFB.screenSize().w - bezelW) / 2, // center
|
||||
(myFB.screenSize().h - bezelH) / 2);
|
||||
mySurface->setScalingInterpolation(ScalingInterpolation::sharp);
|
||||
// Note: Variable bezel window positions are handled in VideoModeHandler::Mode
|
||||
|
||||
// Enable blending to allow overlaying the bezel over the TIA output
|
||||
mySurface->attributes().blending = true;
|
||||
mySurface->attributes().blendalpha = 100;
|
||||
mySurface->applyAttributes();
|
||||
mySurface->setVisible(true);
|
||||
}
|
||||
else
|
||||
if(mySurface)
|
||||
mySurface->setVisible(false);
|
||||
}
|
||||
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
void Bezel::render()
|
||||
{
|
||||
if(mySurface)
|
||||
mySurface->render();
|
||||
}
|
|
@ -0,0 +1,151 @@
|
|||
//============================================================================
|
||||
//
|
||||
// SSSS tt lll lll
|
||||
// SS SS tt ll ll
|
||||
// SS tttttt eeee ll ll aaaa
|
||||
// SSSS tt ee ee ll ll aa
|
||||
// SS tt eeeeee ll ll aaaaa -- "An Atari 2600 VCS Emulator"
|
||||
// SS SS tt ee ll ll aa aa
|
||||
// SSSS ttt eeeee llll llll aaaaa
|
||||
//
|
||||
// Copyright (c) 1995-2025 by Bradford W. Mott, Stephen Anthony
|
||||
// and the Stella Team
|
||||
//
|
||||
// See the file "License.txt" for information on usage and redistribution of
|
||||
// this file, and for a DISCLAIMER OF ALL WARRANTIES.
|
||||
//============================================================================
|
||||
|
||||
#ifndef BEZEL_HXX
|
||||
#define BEZEL_HXX
|
||||
|
||||
class OSystem;
|
||||
class FBSurface;
|
||||
class FrameBuffer;
|
||||
class Properties;
|
||||
|
||||
#include "Rect.hxx"
|
||||
|
||||
/**
|
||||
This class handles the bezels.
|
||||
|
||||
Bezels are loaded using a file name which is either a bezel name property or
|
||||
is autogenerated from the cart name property. The bezels can be any size and
|
||||
their transparent emulation window can be at any position. The position of
|
||||
the window can be determined automatically.
|
||||
|
||||
+--------------------------------------+
|
||||
| | display.h
|
||||
+--------------------------------------+
|
||||
| |
|
||||
| +---------------+ |
|
||||
| | window | |
|
||||
| | | |
|
||||
| | tia.h * zoom | |
|
||||
| | | | bezel.h * zoom
|
||||
| | | |
|
||||
| +---------------+ |
|
||||
| |
|
||||
+--------------------------------------+ size
|
||||
| |
|
||||
+--------------------------------------+
|
||||
|
||||
The bezel and window sizes and their ratios are used for correct scaling.
|
||||
|
||||
@author Thomas Jentzsch
|
||||
*/
|
||||
|
||||
class Bezel
|
||||
{
|
||||
public:
|
||||
explicit Bezel(OSystem& osystem);
|
||||
~Bezel() = default;
|
||||
|
||||
struct Info
|
||||
{
|
||||
private:
|
||||
bool _isShown{false}; // Is bezel shown?
|
||||
Common::Size _size{1, 1}; // Bezel size
|
||||
Common::Rect _window{1, 1}; // Area of transparent TIA window inside bezel
|
||||
|
||||
public:
|
||||
explicit Info() = default;
|
||||
explicit Info(Common::Size size, Common::Rect window)
|
||||
: _isShown{true}, _size{size}, _window{window} { }
|
||||
|
||||
bool isShown() const { return _isShown; }
|
||||
Common::Size size() const { return _size; }
|
||||
Common::Rect window() const { return _window; }
|
||||
|
||||
// Ratios between bezel sizes and TIA window sizes
|
||||
double ratioW() const { return static_cast<double>(size().w) / window().w(); }
|
||||
double ratioH() const { return static_cast<double>(size().h) / window().h(); }
|
||||
};
|
||||
|
||||
// Structure access methods
|
||||
const Info& info() const { return myInfo; }
|
||||
bool isShown() const { return myInfo.isShown(); }
|
||||
Common::Size size() const { return myInfo.size(); }
|
||||
Common::Rect window() const { return myInfo.window(); }
|
||||
// Ratio between bezel size and TIA window size
|
||||
double ratioW() const { return myInfo.ratioW(); }
|
||||
double ratioH() const { return myInfo.ratioH(); }
|
||||
|
||||
/*
|
||||
Calculate size of a bezel border.
|
||||
*/
|
||||
uInt32 borderSize(uInt32 x, uInt32 y, uInt32 size, Int32 step) const;
|
||||
|
||||
/*
|
||||
Load the bezel.
|
||||
*/
|
||||
bool load();
|
||||
|
||||
/*
|
||||
Display scaled bezel.
|
||||
*/
|
||||
void apply();
|
||||
|
||||
/*
|
||||
Render bezel surface
|
||||
*/
|
||||
void render();
|
||||
|
||||
/*
|
||||
Generate bezel file name.
|
||||
*/
|
||||
static string getName(const string& path, const Properties& props);
|
||||
|
||||
private:
|
||||
/*
|
||||
Generate bezel file name.
|
||||
*/
|
||||
static string getName(const Properties& props, int& index);
|
||||
|
||||
/*
|
||||
Generate bezel file name.
|
||||
*/
|
||||
string getName(int& index) const;
|
||||
|
||||
private:
|
||||
// The parent system for the bezel
|
||||
OSystem& myOSystem;
|
||||
|
||||
// Pointer to the FrameBuffer object
|
||||
FrameBuffer& myFB;
|
||||
|
||||
// The bezel surface which blends over the TIA surface
|
||||
shared_ptr<FBSurface> mySurface;
|
||||
|
||||
// Bezel info structure
|
||||
Info myInfo;
|
||||
|
||||
private:
|
||||
// Following constructors and assignment operators not supported
|
||||
Bezel() = delete;
|
||||
Bezel(const Bezel&) = delete;
|
||||
Bezel(Bezel&&) = delete;
|
||||
Bezel& operator=(const Bezel&) = delete;
|
||||
Bezel& operator=(Bezel&&) = delete;
|
||||
};
|
||||
|
||||
#endif
|
|
@ -0,0 +1,250 @@
|
|||
//============================================================================
|
||||
//
|
||||
// SSSS tt lll lll
|
||||
// SS SS tt ll ll
|
||||
// SS tttttt eeee ll ll aaaa
|
||||
// SSSS tt ee ee ll ll aa
|
||||
// SS tt eeeeee ll ll aaaaa -- "An Atari 2600 VCS Emulator"
|
||||
// SS SS tt ee ll ll aa aa
|
||||
// SSSS ttt eeeee llll llll aaaaa
|
||||
//
|
||||
// Copyright (c) 1995-2025 by Bradford W. Mott, Stephen Anthony
|
||||
// and the Stella Team
|
||||
//
|
||||
// See the file "License.txt" for information on usage and redistribution of
|
||||
// this file, and for a DISCLAIMER OF ALL WARRANTIES.
|
||||
//============================================================================
|
||||
|
||||
#include "Console.hxx"
|
||||
#include "EventHandler.hxx"
|
||||
#include "M6502.hxx"
|
||||
#include "OSystem.hxx"
|
||||
#include "RewindManager.hxx"
|
||||
#include "Settings.hxx"
|
||||
#include "StateManager.hxx"
|
||||
#include "TIA.hxx"
|
||||
#include "Cart.hxx"
|
||||
#include "CartELF.hxx"
|
||||
|
||||
#include "DevSettingsHandler.hxx"
|
||||
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
DevSettingsHandler::DevSettingsHandler(OSystem& osystem)
|
||||
: myOSystem{osystem}
|
||||
{
|
||||
}
|
||||
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
void DevSettingsHandler::loadSettings(SettingsSet set)
|
||||
{
|
||||
const bool devSettings = set == SettingsSet::developer;
|
||||
const string& prefix = devSettings ? "dev." : "plr.";
|
||||
const Settings& settings = myOSystem.settings();
|
||||
|
||||
myFrameStats[set] = settings.getBool(prefix + "stats");
|
||||
myDetectedInfo[set] = settings.getBool(prefix + "detectedinfo");
|
||||
// AtariVox/SaveKey/PlusROM access
|
||||
myExternAccess[set] = settings.getBool(prefix + "extaccess");
|
||||
myConsole[set] = settings.getString(prefix + "console") == "7800" ? 1 : 0;
|
||||
myPlusROM[set] = devSettings ? settings.getBool("dev.plusroms.on") : true;
|
||||
// Randomization
|
||||
myRandomBank[set] = settings.getBool(prefix + "bankrandom");
|
||||
myRandomizeTIA[set] = settings.getBool(prefix + "tiarandom");
|
||||
myRandomizeRAM[set] = settings.getBool(prefix + "ramrandom");
|
||||
myRandomizeCPU[set] = settings.getString(prefix + "cpurandom");
|
||||
// Random hotspot peeks
|
||||
myRandomHotspots[set] = devSettings ? settings.getBool("dev.hsrandom") : false;
|
||||
// Undriven TIA pins
|
||||
myUndrivenPins[set] = devSettings ? settings.getBool("dev.tiadriven") : false;
|
||||
#ifdef DEBUGGER_SUPPORT
|
||||
// Read from write ports break
|
||||
myRWPortBreak[set] = devSettings ? settings.getBool("dev.rwportbreak") : false;
|
||||
// Write to read ports break
|
||||
myWRPortBreak[set] = devSettings ? settings.getBool("dev.wrportbreak") : false;
|
||||
#endif
|
||||
// Thumb ARM emulation exception
|
||||
myThumbException[set] = devSettings ? settings.getBool("dev.thumb.trapfatal") : false;
|
||||
myArmSpeed[set] = devSettings ? settings.getInt("dev.arm.mips") : CartridgeELF::MIPS_MAX;
|
||||
|
||||
// TIA tab
|
||||
myTIAType[set] = devSettings ? settings.getString("dev.tia.type") : "standard";
|
||||
myPlInvPhase[set] = devSettings ? settings.getBool("dev.tia.plinvphase") : false;
|
||||
myMsInvPhase[set] = devSettings ? settings.getBool("dev.tia.msinvphase") : false;
|
||||
myBlInvPhase[set] = devSettings ? settings.getBool("dev.tia.blinvphase") : false;
|
||||
myPlLateHMove[set] = devSettings ? settings.getBool("dev.tia.pllatehmove") : false;
|
||||
myMsLateHMove[set] = devSettings ? settings.getBool("dev.tia.mslatehmove") : false;
|
||||
myBlLateHMove[set] = devSettings ? settings.getBool("dev.tia.bllatehmove") : false;
|
||||
myPFBits[set] = devSettings ? settings.getBool("dev.tia.delaypfbits") : false;
|
||||
myPFColor[set] = devSettings ? settings.getBool("dev.tia.delaypfcolor") : false;
|
||||
myPFScore[set] = devSettings ? settings.getBool("dev.tia.pfscoreglitch") : false;
|
||||
myBKColor[set] = devSettings ? settings.getBool("dev.tia.delaybkcolor") : false;
|
||||
myPlSwap[set] = devSettings ? settings.getBool("dev.tia.delayplswap") : false;
|
||||
myBlSwap[set] = devSettings ? settings.getBool("dev.tia.delayblswap") : false;
|
||||
|
||||
// Debug colors
|
||||
myDebugColors[set] = settings.getBool(prefix + "debugcolors");
|
||||
// PAL color-loss effect
|
||||
myColorLoss[set] = settings.getBool(prefix + "colorloss");
|
||||
// Jitter
|
||||
myTVJitter[set] = settings.getBool(prefix + "tv.jitter");
|
||||
myTVJitterSense[set] = settings.getInt(prefix + "tv.jitter_sense");
|
||||
myTVJitterRec[set] = settings.getInt(prefix + "tv.jitter_recovery");
|
||||
|
||||
// States
|
||||
myTimeMachine[set] = settings.getBool(prefix + "timemachine");
|
||||
myStateSize[set] = settings.getInt(prefix + "tm.size");
|
||||
myUncompressed[set] = settings.getInt(prefix + "tm.uncompressed");
|
||||
myStateInterval[set] = settings.getString(prefix + "tm.interval");
|
||||
myStateHorizon[set] = settings.getString(prefix + "tm.horizon");
|
||||
}
|
||||
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
void DevSettingsHandler::saveSettings(SettingsSet set)
|
||||
{
|
||||
const bool devSettings = set == SettingsSet::developer;
|
||||
const string& prefix = devSettings ? "dev." : "plr.";
|
||||
Settings& settings = myOSystem.settings();
|
||||
|
||||
settings.setValue(prefix + "stats", myFrameStats[set]);
|
||||
settings.setValue(prefix + "detectedinfo", myDetectedInfo[set]);
|
||||
settings.setValue(prefix + "console", myConsole[set] == 1 ? "7800" : "2600");
|
||||
if(myOSystem.hasConsole())
|
||||
myOSystem.eventHandler().set7800Mode();
|
||||
|
||||
// Randomization
|
||||
settings.setValue(prefix + "bankrandom", myRandomBank[set]);
|
||||
settings.setValue(prefix + "tiarandom", myRandomizeTIA[set]);
|
||||
settings.setValue(prefix + "ramrandom", myRandomizeRAM[set]);
|
||||
settings.setValue(prefix + "cpurandom", myRandomizeCPU[set]);
|
||||
|
||||
if(devSettings)
|
||||
{
|
||||
settings.setValue("dev.plusroms.on", myPlusROM[set]);
|
||||
settings.setValue("dev.hsrandom", myRandomHotspots[set]);
|
||||
// Undriven TIA pins
|
||||
settings.setValue("dev.tiadriven", myUndrivenPins[set]);
|
||||
#ifdef DEBUGGER_SUPPORT
|
||||
// Read from write ports break
|
||||
settings.setValue("dev.rwportbreak", myRWPortBreak[set]);
|
||||
// Write to read ports break
|
||||
settings.setValue("dev.wrportbreak", myWRPortBreak[set]);
|
||||
#endif
|
||||
// Thumb ARM emulation exception
|
||||
settings.setValue("dev.thumb.trapfatal", myThumbException[set]);
|
||||
settings.setValue("dev.arm.mips", myArmSpeed[set]);
|
||||
}
|
||||
|
||||
// AtariVox/SaveKey/PlusROM access
|
||||
settings.setValue(prefix + "extaccess", myExternAccess[set]);
|
||||
|
||||
// TIA tab
|
||||
if(devSettings)
|
||||
{
|
||||
settings.setValue("dev.tia.type", myTIAType[set]);
|
||||
if(BSPF::equalsIgnoreCase("custom", myTIAType[set]))
|
||||
{
|
||||
settings.setValue("dev.tia.plinvphase", myPlInvPhase[set]);
|
||||
settings.setValue("dev.tia.msinvphase", myMsInvPhase[set]);
|
||||
settings.setValue("dev.tia.blinvphase", myBlInvPhase[set]);
|
||||
settings.setValue("dev.tia.pllatehmove", myPlLateHMove[set]);
|
||||
settings.setValue("dev.tia.mslatehmove", myMsLateHMove[set]);
|
||||
settings.setValue("dev.tia.bllatehmove", myBlLateHMove[set]);
|
||||
settings.setValue("dev.tia.delaypfbits", myPFBits[set]);
|
||||
settings.setValue("dev.tia.delaypfcolor", myPFColor[set]);
|
||||
settings.setValue("dev.tia.pfscoreglitch", myPFScore[set]);
|
||||
settings.setValue("dev.tia.delaybkcolor", myBKColor[set]);
|
||||
settings.setValue("dev.tia.delayplswap", myPlSwap[set]);
|
||||
settings.setValue("dev.tia.delayblswap", myBlSwap[set]);
|
||||
}
|
||||
}
|
||||
|
||||
// Debug colors
|
||||
settings.setValue(prefix + "debugcolors", myDebugColors[set]);
|
||||
// PAL color loss
|
||||
settings.setValue(prefix + "colorloss", myColorLoss[set]);
|
||||
// Jitter
|
||||
settings.setValue(prefix + "tv.jitter", myTVJitter[set]);
|
||||
settings.setValue(prefix + "tv.jitter_sense", myTVJitterSense[set]);
|
||||
settings.setValue(prefix + "tv.jitter_recovery", myTVJitterRec[set]);
|
||||
|
||||
// States
|
||||
settings.setValue(prefix + "timemachine", myTimeMachine[set]);
|
||||
settings.setValue(prefix + "tm.size", myStateSize[set]);
|
||||
settings.setValue(prefix + "tm.uncompressed", myUncompressed[set]);
|
||||
settings.setValue(prefix + "tm.interval", myStateInterval[set]);
|
||||
settings.setValue(prefix + "tm.horizon", myStateHorizon[set]);
|
||||
}
|
||||
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
void DevSettingsHandler::applySettings(SettingsSet set)
|
||||
{
|
||||
// *** Emulation tab ***
|
||||
myOSystem.frameBuffer().showFrameStats(myFrameStats[set]);
|
||||
|
||||
if(myOSystem.hasConsole())
|
||||
{
|
||||
myOSystem.console().cartridge().enableRandomHotspots(myRandomHotspots[set]);
|
||||
myOSystem.console().tia().driveUnusedPinsRandom(myUndrivenPins[set]);
|
||||
myOSystem.console().cartridge().enablePlusROM(myPlusROM[set]);
|
||||
// Notes:
|
||||
// - thumb exceptions not updated, because set in cart constructor
|
||||
// - other missing settings are used on-the-fly
|
||||
}
|
||||
|
||||
#ifdef DEBUGGER_SUPPORT
|
||||
// Read from write ports and write to read ports breaks
|
||||
if(myOSystem.hasConsole())
|
||||
{
|
||||
myOSystem.console().system().m6502().setReadFromWritePortBreak(myRWPortBreak[set]);
|
||||
myOSystem.console().system().m6502().setWriteToReadPortBreak(myWRPortBreak[set]);
|
||||
}
|
||||
#endif
|
||||
|
||||
// *** TIA tab ***
|
||||
if(myOSystem.hasConsole())
|
||||
{
|
||||
myOSystem.console().tia().setPlInvertedPhaseClock(myPlInvPhase[set]);
|
||||
myOSystem.console().tia().setMsInvertedPhaseClock(myMsInvPhase[set]);
|
||||
myOSystem.console().tia().setBlInvertedPhaseClock(myBlInvPhase[set]);
|
||||
myOSystem.console().tia().setPlShortLateHMove(myPlLateHMove[set]);
|
||||
myOSystem.console().tia().setMsShortLateHMove(myMsLateHMove[set]);
|
||||
myOSystem.console().tia().setBlShortLateHMove(myBlLateHMove[set]);
|
||||
myOSystem.console().tia().setPFBitsDelay(myPFBits[set]);
|
||||
myOSystem.console().tia().setPFColorDelay(myPFColor[set]);
|
||||
myOSystem.console().tia().setPFScoreGlitch(myPFScore[set]);
|
||||
myOSystem.console().tia().setBKColorDelay(myBKColor[set]);
|
||||
myOSystem.console().tia().setPlSwapDelay(myPlSwap[set]);
|
||||
myOSystem.console().tia().setBlSwapDelay(myBlSwap[set]);
|
||||
}
|
||||
|
||||
// *** Video tab ***
|
||||
if(myOSystem.hasConsole())
|
||||
{
|
||||
// TV Jitter
|
||||
myOSystem.console().tia().toggleJitter(myTVJitter[set] ? 1 : 0);
|
||||
myOSystem.console().tia().setJitterSensitivity(myTVJitterSense[set]);
|
||||
myOSystem.console().tia().setJitterRecoveryFactor(myTVJitterRec[set]);
|
||||
// PAL color loss
|
||||
myOSystem.console().enableColorLoss(myColorLoss[set]);
|
||||
}
|
||||
|
||||
// Debug colours
|
||||
handleEnableDebugColors(myDebugColors[set]);
|
||||
|
||||
// *** Time Machine tab ***
|
||||
// update RewindManager
|
||||
myOSystem.state().rewindManager().setup();
|
||||
myOSystem.state().setRewindMode(myTimeMachine[set] ?
|
||||
StateManager::Mode::TimeMachine : StateManager::Mode::Off);
|
||||
}
|
||||
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
void DevSettingsHandler::handleEnableDebugColors(bool enable)
|
||||
{
|
||||
if(myOSystem.hasConsole())
|
||||
{
|
||||
const bool fixed = myOSystem.console().tia().usingFixedColors();
|
||||
if(fixed != enable)
|
||||
myOSystem.console().tia().toggleFixedColors();
|
||||
}
|
||||
}
|
|
@ -0,0 +1,104 @@
|
|||
//============================================================================
|
||||
//
|
||||
// SSSS tt lll lll
|
||||
// SS SS tt ll ll
|
||||
// SS tttttt eeee ll ll aaaa
|
||||
// SSSS tt ee ee ll ll aa
|
||||
// SS tt eeeeee ll ll aaaaa -- "An Atari 2600 VCS Emulator"
|
||||
// SS SS tt ee ll ll aa aa
|
||||
// SSSS ttt eeeee llll llll aaaaa
|
||||
//
|
||||
// Copyright (c) 1995-2025 by Bradford W. Mott, Stephen Anthony
|
||||
// and the Stella Team
|
||||
//
|
||||
// See the file "License.txt" for information on usage and redistribution of
|
||||
// this file, and for a DISCLAIMER OF ALL WARRANTIES.
|
||||
//============================================================================
|
||||
|
||||
#ifndef DEV_SETTINGS_HANDLER_HXX
|
||||
#define DEV_SETTINGS_HANDLER_HXX
|
||||
|
||||
class OSystem;
|
||||
|
||||
#include <array>
|
||||
#include "bspf.hxx"
|
||||
|
||||
/**
|
||||
This class takes care of developer settings sets.
|
||||
|
||||
@author Thomas Jentzsch
|
||||
*/
|
||||
class DevSettingsHandler
|
||||
{
|
||||
public:
|
||||
enum SettingsSet: uInt8 {
|
||||
player,
|
||||
developer,
|
||||
numSets
|
||||
};
|
||||
|
||||
explicit DevSettingsHandler(OSystem& osystem);
|
||||
~DevSettingsHandler() = default;
|
||||
|
||||
void loadSettings(SettingsSet set);
|
||||
void saveSettings(SettingsSet set);
|
||||
void applySettings(SettingsSet set);
|
||||
|
||||
protected:
|
||||
OSystem& myOSystem;
|
||||
// Emulator sets
|
||||
std::array<bool, numSets> myFrameStats{};
|
||||
std::array<bool, numSets> myDetectedInfo{};
|
||||
std::array<bool, numSets> myExternAccess{};
|
||||
std::array<int, numSets> myConsole{};
|
||||
std::array<int, numSets> myPlusROM{};
|
||||
std::array<bool, numSets> myRandomBank{};
|
||||
std::array<bool, numSets> myRandomizeTIA{};
|
||||
std::array<bool, numSets> myRandomizeRAM{};
|
||||
std::array<string, numSets> myRandomizeCPU{};
|
||||
std::array<bool, numSets> myColorLoss{};
|
||||
std::array<bool, numSets> myTVJitter{};
|
||||
std::array<int, numSets> myTVJitterSense{};
|
||||
std::array<int, numSets> myTVJitterRec{};
|
||||
std::array<bool, numSets> myDebugColors{};
|
||||
std::array<bool, numSets> myRandomHotspots{};
|
||||
std::array<bool, numSets> myUndrivenPins{};
|
||||
#ifdef DEBUGGER_SUPPORT
|
||||
std::array<bool, numSets> myRWPortBreak{};
|
||||
std::array<bool, numSets> myWRPortBreak{};
|
||||
#endif
|
||||
std::array<bool, numSets> myThumbException{};
|
||||
std::array<int, numSets> myArmSpeed{};
|
||||
// TIA sets
|
||||
std::array<string, numSets> myTIAType{};
|
||||
std::array<bool, numSets> myPlInvPhase{};
|
||||
std::array<bool, numSets> myMsInvPhase{};
|
||||
std::array<bool, numSets> myBlInvPhase{};
|
||||
std::array<bool, numSets> myPlLateHMove{};
|
||||
std::array<bool, numSets> myMsLateHMove{};
|
||||
std::array<bool, numSets> myBlLateHMove{};
|
||||
std::array<bool, numSets> myPFBits{};
|
||||
std::array<bool, numSets> myPFColor{};
|
||||
std::array<bool, numSets> myPFScore{};
|
||||
std::array<bool, numSets> myBKColor{};
|
||||
std::array<bool, numSets> myPlSwap{};
|
||||
std::array<bool, numSets> myBlSwap{};
|
||||
// States sets
|
||||
std::array<bool, numSets> myTimeMachine{};
|
||||
std::array<int, numSets> myStateSize{};
|
||||
std::array<int, numSets> myUncompressed{};
|
||||
std::array<string, numSets> myStateInterval{};
|
||||
std::array<string, numSets> myStateHorizon{};
|
||||
|
||||
private:
|
||||
void handleEnableDebugColors(bool enable);
|
||||
|
||||
// Following constructors and assignment operators not supported
|
||||
DevSettingsHandler() = delete;
|
||||
DevSettingsHandler(const DevSettingsHandler&) = delete;
|
||||
DevSettingsHandler(DevSettingsHandler&&) = delete;
|
||||
DevSettingsHandler& operator=(const DevSettingsHandler&) = delete;
|
||||
DevSettingsHandler& operator=(DevSettingsHandler&&) = delete;
|
||||
};
|
||||
|
||||
#endif
|
|
@ -8,7 +8,7 @@
|
|||
// SS SS tt ee ll ll aa aa
|
||||
// SSSS ttt eeeee llll llll aaaaa
|
||||
//
|
||||
// Copyright (c) 1995-2021 by Bradford W. Mott, Stephen Anthony
|
||||
// Copyright (c) 1995-2025 by Bradford W. Mott, Stephen Anthony
|
||||
// and the Stella Team
|
||||
//
|
||||
// See the file "License.txt" for information on usage and redistribution of
|
||||
|
@ -30,9 +30,10 @@ EventHandlerSDL2::EventHandlerSDL2(OSystem& osystem)
|
|||
#ifdef GUI_SUPPORT
|
||||
{
|
||||
ostringstream buf;
|
||||
myQwertz = int('y') == int(SDL_GetKeyFromScancode(SDL_Scancode(KBDK_Z)));
|
||||
myQwertz = int{'y'} == static_cast<int>
|
||||
(SDL_GetKeyFromScancode(static_cast<SDL_Scancode>(KBDK_Z)));
|
||||
buf << "Keyboard: " << (myQwertz ? "QWERTZ" : "QWERTY");
|
||||
Logger::debug(buf.str());
|
||||
Logger::debug(buf.view());
|
||||
}
|
||||
#endif
|
||||
|
||||
|
@ -40,8 +41,9 @@ EventHandlerSDL2::EventHandlerSDL2(OSystem& osystem)
|
|||
if(SDL_InitSubSystem(SDL_INIT_JOYSTICK) < 0)
|
||||
{
|
||||
ostringstream buf;
|
||||
buf << "ERROR: Couldn't initialize SDL joystick support: " << SDL_GetError() << endl;
|
||||
Logger::error(buf.str());
|
||||
buf << "ERROR: Couldn't initialize SDL joystick support: "
|
||||
<< SDL_GetError() << '\n';
|
||||
Logger::error(buf.view());
|
||||
}
|
||||
Logger::debug("EventHandlerSDL2::EventHandlerSDL2 SDL_INIT_JOYSTICK");
|
||||
#endif
|
||||
|
@ -99,8 +101,8 @@ void EventHandlerSDL2::pollEvent()
|
|||
case SDL_KEYUP:
|
||||
case SDL_KEYDOWN:
|
||||
{
|
||||
handleKeyEvent(StellaKey(myEvent.key.keysym.scancode),
|
||||
StellaMod(myEvent.key.keysym.mod),
|
||||
handleKeyEvent(static_cast<StellaKey>(myEvent.key.keysym.scancode),
|
||||
static_cast<StellaMod>(myEvent.key.keysym.mod),
|
||||
myEvent.key.type == SDL_KEYDOWN,
|
||||
myEvent.key.repeat);
|
||||
break;
|
||||
|
@ -123,23 +125,29 @@ void EventHandlerSDL2::pollEvent()
|
|||
case SDL_MOUSEBUTTONUP:
|
||||
{
|
||||
// ToDo: check support of more buttons and double-click
|
||||
MouseButton b{MouseButton::NONE};
|
||||
switch(myEvent.button.button)
|
||||
{
|
||||
case SDL_BUTTON_LEFT:
|
||||
handleMouseButtonEvent(MouseButton::LEFT, myEvent.button.type == SDL_MOUSEBUTTONDOWN,
|
||||
myEvent.button.x, myEvent.button.y);
|
||||
b = MouseButton::LEFT;
|
||||
break;
|
||||
case SDL_BUTTON_RIGHT:
|
||||
handleMouseButtonEvent(MouseButton::RIGHT, myEvent.button.type == SDL_MOUSEBUTTONDOWN,
|
||||
myEvent.button.x, myEvent.button.y);
|
||||
b = MouseButton::RIGHT;
|
||||
break;
|
||||
case SDL_BUTTON_MIDDLE:
|
||||
b = MouseButton::MIDDLE;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
handleMouseButtonEvent(b, myEvent.button.type == SDL_MOUSEBUTTONDOWN,
|
||||
myEvent.button.x, myEvent.button.y);
|
||||
break;
|
||||
}
|
||||
|
||||
case SDL_MOUSEWHEEL:
|
||||
{
|
||||
int x, y;
|
||||
int x{0}, y{0};
|
||||
SDL_GetMouseState(&x, &y); // we need mouse position too
|
||||
if(myEvent.wheel.y < 0)
|
||||
handleMouseButtonEvent(MouseButton::WHEELDOWN, true, x, y);
|
||||
|
@ -166,7 +174,8 @@ void EventHandlerSDL2::pollEvent()
|
|||
|
||||
case SDL_JOYHATMOTION:
|
||||
{
|
||||
int v = myEvent.jhat.value, value = 0;
|
||||
int value = 0;
|
||||
const int v = myEvent.jhat.value;
|
||||
if(v == SDL_HAT_CENTERED)
|
||||
value = EVENT_HATCENTER_M;
|
||||
else
|
||||
|
@ -240,8 +249,13 @@ void EventHandlerSDL2::pollEvent()
|
|||
case SDL_WINDOWEVENT_FOCUS_LOST:
|
||||
handleSystemEvent(SystemEvent::WINDOW_FOCUS_LOST);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
break; // SDL_WINDOWEVENT
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -251,6 +265,7 @@ EventHandlerSDL2::JoystickSDL2::JoystickSDL2(int idx)
|
|||
{
|
||||
ASSERT_MAIN_THREAD;
|
||||
|
||||
// NOLINTNEXTLINE: we want to initialize here, not in the member list
|
||||
myStick = SDL_JoystickOpen(idx);
|
||||
if(myStick)
|
||||
{
|
||||
|
@ -259,7 +274,7 @@ EventHandlerSDL2::JoystickSDL2::JoystickSDL2(int idx)
|
|||
// it also appends " #x", where x seems to vary. Obviously this wreaks
|
||||
// havoc with the idea that a joystick will always have the same name.
|
||||
// So we truncate the number.
|
||||
const char* sdlname = SDL_JoystickName(myStick);
|
||||
const char* const sdlname = SDL_JoystickName(myStick);
|
||||
const string& desc = BSPF::startsWithIgnoreCase(sdlname, "XInput Controller")
|
||||
? "XInput Controller" : sdlname;
|
||||
|
||||
|
|