Compare commits
310 Commits
v0.16.7-li
...
master
Author | SHA1 | Date |
---|---|---|
![]() |
8a234a25a3 | |
![]() |
5b88346537 | |
![]() |
20e5e18122 | |
![]() |
b948a1f3fd | |
![]() |
8215c03d62 | |
![]() |
8b2af8adf1 | |
![]() |
00f772b29d | |
![]() |
4107198548 | |
![]() |
e997ce0ce7 | |
![]() |
58c946f249 | |
![]() |
0b57886491 | |
![]() |
2db60c2b3f | |
![]() |
f54bfae01f | |
![]() |
c40221abb6 | |
![]() |
eb38034b76 | |
![]() |
c6a968ed74 | |
![]() |
e69f6b8579 | |
![]() |
cfbc7b481a | |
![]() |
1dfcdffa71 | |
![]() |
5b983bc7ad | |
![]() |
634b90e4fc | |
![]() |
b31cca77be | |
![]() |
5b17b41e07 | |
![]() |
239e0462c3 | |
![]() |
8505f00cdf | |
![]() |
08d58aa992 | |
![]() |
8cce6f7b13 | |
![]() |
ec8baa6329 | |
![]() |
9bd84978cf | |
![]() |
aa0fe30d5c | |
![]() |
6d6aafe887 | |
![]() |
003e8914b1 | |
![]() |
d7e1672ae7 | |
![]() |
1157ff0f36 | |
![]() |
bdd4522ca9 | |
![]() |
4abb5f3539 | |
![]() |
aff7f1706c | |
![]() |
33d237706e | |
![]() |
a39efd31cf | |
![]() |
69bb4c3e95 | |
![]() |
ae2d68aaf3 | |
![]() |
e381ebd1ea | |
![]() |
34c29b052e | |
![]() |
4ebb108ae1 | |
![]() |
d1da91da7c | |
![]() |
490d63b26f | |
![]() |
be63d7eaa3 | |
![]() |
15588a065f | |
![]() |
d52a50353d | |
![]() |
5d70f93920 | |
![]() |
f3cbc1990e | |
![]() |
583c234953 | |
![]() |
3f744254fd | |
![]() |
7abedaed4c | |
![]() |
42ffbd18d0 | |
![]() |
8508eb7b7c | |
![]() |
00000971d7 | |
![]() |
58bd40b833 | |
![]() |
cbaf5c4c4a | |
![]() |
67d338164b | |
![]() |
7bf8145a91 | |
![]() |
e043279500 | |
![]() |
9d6f378d21 | |
![]() |
bfb1092cbb | |
![]() |
282140822e | |
![]() |
19a1e3ec1a | |
![]() |
1ad8bad18c | |
![]() |
9577cbce85 | |
![]() |
6dd2f609f2 | |
![]() |
976fe7a337 | |
![]() |
1400bd40e8 | |
![]() |
6a97192e8c | |
![]() |
42732b20eb | |
![]() |
f0a672c39e | |
![]() |
d211120312 | |
![]() |
6ab1be654b | |
![]() |
f706988171 | |
![]() |
bed9f8220c | |
![]() |
750112f6dd | |
![]() |
63a02d90bc | |
![]() |
795fba1320 | |
![]() |
1923c324d9 | |
![]() |
6a24b9206f | |
![]() |
30a8c4bf42 | |
![]() |
152e242485 | |
![]() |
c4e6161959 | |
![]() |
1951df3476 | |
![]() |
1cf84a5436 | |
![]() |
81c29fa371 | |
![]() |
8b27952680 | |
![]() |
3c58deb46f | |
![]() |
0fc08d93be | |
![]() |
cd82311c54 | |
![]() |
bf9212bcff | |
![]() |
dfd3b42929 | |
![]() |
18edb65680 | |
![]() |
3468d5de7e | |
![]() |
d146b3a309 | |
![]() |
71d4e60c57 | |
![]() |
8f21c8ed66 | |
![]() |
3ad28b7a8d | |
![]() |
edce971d8c | |
![]() |
6d9ab972d0 | |
![]() |
ed7d0546a3 | |
![]() |
474caaccd5 | |
![]() |
1d7ecb7f1b | |
![]() |
8c30a7c90c | |
![]() |
2b89923a6f | |
![]() |
8a0ff891bd | |
![]() |
9359f7a2d9 | |
![]() |
f1d52c53d3 | |
![]() |
9096f629c9 | |
![]() |
d50f9df974 | |
![]() |
15215000f9 | |
![]() |
4e35048f46 | |
![]() |
e2b22a0df6 | |
![]() |
9c958a1cb4 | |
![]() |
3cb04e88d1 | |
![]() |
917b62785c | |
![]() |
7b511dd76b | |
![]() |
04cd94de3f | |
![]() |
da0380c32d | |
![]() |
e76088cde2 | |
![]() |
abf108f6b8 | |
![]() |
fab91444dd | |
![]() |
9442a2a8e8 | |
![]() |
9793e15f4d | |
![]() |
670540116a | |
![]() |
1354b77373 | |
![]() |
63e081e9c2 | |
![]() |
4d28af4fcf | |
![]() |
a659de9960 | |
![]() |
d6b7157a0c | |
![]() |
48cc359f0c | |
![]() |
6549684e1f | |
![]() |
150855f2e9 | |
![]() |
215a690e92 | |
![]() |
1d5cb77464 | |
![]() |
b5761c29d5 | |
![]() |
7994869b1f | |
![]() |
ac54d5b7ec | |
![]() |
9df4f22873 | |
![]() |
d049dfe983 | |
![]() |
4c904d11ff | |
![]() |
aa5fc484d1 | |
![]() |
849ae42b99 | |
![]() |
fe72561a8f | |
![]() |
e5950aa4ef | |
![]() |
5180e8e03b | |
![]() |
67dee21804 | |
![]() |
007d3b2555 | |
![]() |
9ff3bffddd | |
![]() |
12859683b7 | |
![]() |
27a064caff | |
![]() |
b4fc2ff7ba | |
![]() |
fe2c868d6c | |
![]() |
150f0fcad4 | |
![]() |
a39b1913b8 | |
![]() |
1ab690ba18 | |
![]() |
c3d83eae22 | |
![]() |
117da602ca | |
![]() |
a0c5b6f97a | |
![]() |
7e071e463d | |
![]() |
ad2360b5c3 | |
![]() |
ee3f37b39c | |
![]() |
ebfc877c1c | |
![]() |
8f9e1e9ea5 | |
![]() |
1bf57ece70 | |
![]() |
29d8cca511 | |
![]() |
14cf76776a | |
![]() |
f1f97f0692 | |
![]() |
0b5be876b3 | |
![]() |
fdc39f9bd6 | |
![]() |
14e486017a | |
![]() |
3bee0deda5 | |
![]() |
101e894314 | |
![]() |
2e6ff5fd9f | |
![]() |
2b3ec9d991 | |
![]() |
375fb4388c | |
![]() |
fc76063ec0 | |
![]() |
6568cca6bb | |
![]() |
d386ca8726 | |
![]() |
f21761338c | |
![]() |
41af62d793 | |
![]() |
2dfde867a9 | |
![]() |
6efefab526 | |
![]() |
207dc993d4 | |
![]() |
52d5169cc8 | |
![]() |
73a6d35f73 | |
![]() |
2498456bcc | |
![]() |
ec65cfd942 | |
![]() |
122549d3cd | |
![]() |
e13048d07b | |
![]() |
6eeba2f6f6 | |
![]() |
1fac8870d4 | |
![]() |
741637e625 | |
![]() |
73168aa7f2 | |
![]() |
7e5996df82 | |
![]() |
52de44049c | |
![]() |
f5c7c4443d | |
![]() |
db5fa8df4c | |
![]() |
177859bec6 | |
![]() |
bd3799d431 | |
![]() |
e533b59759 | |
![]() |
38e2760531 | |
![]() |
447cdf2672 | |
![]() |
062d44e065 | |
![]() |
f33f3f6951 | |
![]() |
291887cd10 | |
![]() |
8ded1ca3b3 | |
![]() |
2aa4726e01 | |
![]() |
3a7e5ecac5 | |
![]() |
5d952565c9 | |
![]() |
42be4ef827 | |
![]() |
1931c2830f | |
![]() |
8cb94e7a8b | |
![]() |
8c8e59cd81 | |
![]() |
ece40bcf0e | |
![]() |
392bc8c0d9 | |
![]() |
8e3d8c4a18 | |
![]() |
92f425655d | |
![]() |
50a56a4b68 | |
![]() |
11f70c09af | |
![]() |
a372b2ec0f | |
![]() |
7127e3e068 | |
![]() |
f1b187d512 | |
![]() |
11b9c4fab7 | |
![]() |
b88a3a02a9 | |
![]() |
619792db7f | |
![]() |
bd5d01c0a4 | |
![]() |
4647c55949 | |
![]() |
d97c2fb701 | |
![]() |
d4c715b5f0 | |
![]() |
8dda5ee098 | |
![]() |
5b33cebca9 | |
![]() |
6178ff2a78 | |
![]() |
fc508427b8 | |
![]() |
430e42fa72 | |
![]() |
c7c54abb6b | |
![]() |
b6c6b9ed54 | |
![]() |
f0bab07f26 | |
![]() |
645ef429bc | |
![]() |
a7d977a5c5 | |
![]() |
795d772c83 | |
![]() |
2b2bb3569b | |
![]() |
fb8508ea20 | |
![]() |
461083523a | |
![]() |
b8e32e6d53 | |
![]() |
d5c6ed9510 | |
![]() |
47cdefd3d0 | |
![]() |
53fc5a74ed | |
![]() |
035291b955 | |
![]() |
5f71ec4974 | |
![]() |
5eb0e5d605 | |
![]() |
b1ea179513 | |
![]() |
d34579e3bb | |
![]() |
64cf389edf | |
![]() |
0c9cf8d594 | |
![]() |
44b70bf275 | |
![]() |
06c6ce7d65 | |
![]() |
9d4d535758 | |
![]() |
136e11cc13 | |
![]() |
18206718e3 | |
![]() |
c3e3fb91cc | |
![]() |
a4525c3336 | |
![]() |
5dbddb344d | |
![]() |
a66d4ea64c | |
![]() |
3dad68618e | |
![]() |
366c374461 | |
![]() |
6e1112157c | |
![]() |
488f17941f | |
![]() |
1dde5c1ce1 | |
![]() |
17f1b91b8c | |
![]() |
4f25521cba | |
![]() |
64ad67d5a5 | |
![]() |
a26c57d582 | |
![]() |
64d45dd23a | |
![]() |
8e2769b946 | |
![]() |
4cc34f97ec | |
![]() |
323f3e89b7 | |
![]() |
482b9a1562 | |
![]() |
c6103d23fa | |
![]() |
0b6a73f380 | |
![]() |
d873abfadf | |
![]() |
446fc15521 | |
![]() |
b3cecf2413 | |
![]() |
e4ceb3d93b | |
![]() |
cee486ab11 | |
![]() |
407e540638 | |
![]() |
8db2490077 | |
![]() |
d42aad2b84 | |
![]() |
3bf94d281a | |
![]() |
66da5fd530 | |
![]() |
5c21c5e985 | |
![]() |
25576899d8 | |
![]() |
d07b199668 | |
![]() |
ad5ca0dcf0 | |
![]() |
9991c3b0b4 | |
![]() |
c9dfc86291 | |
![]() |
2bf5819c36 | |
![]() |
08178c9f3a | |
![]() |
3581945d85 | |
![]() |
77b7f861f3 | |
![]() |
9588cf44aa | |
![]() |
3116f63e37 | |
![]() |
496baafbf9 | |
![]() |
7f110c4415 | |
![]() |
ee3878e43a | |
![]() |
d267d83cec | |
![]() |
cead58471d |
|
@ -7,4 +7,5 @@ HexFiend/* linguist-vendored
|
||||||
Core/*.h linguist-language=C
|
Core/*.h linguist-language=C
|
||||||
SDL/*.h linguist-language=C
|
SDL/*.h linguist-language=C
|
||||||
Windows/*.h linguist-language=C
|
Windows/*.h linguist-language=C
|
||||||
|
XdgThumbnailer/*.h linguist-language=C
|
||||||
Cocoa/*.h linguist-language=Objective-C
|
Cocoa/*.h linguist-language=Objective-C
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
case `echo $1 | cut -d '-' -f 1` in
|
case `echo $1 | cut -d '-' -f 1` in
|
||||||
ubuntu)
|
ubuntu)
|
||||||
sudo apt-get -qq update
|
sudo apt-get -qq update
|
||||||
sudo apt-get install -yq bison libpng-dev pkg-config libsdl2-dev
|
sudo apt-get install -yq bison libpng-dev pkg-config libsdl2-dev libgdk-pixbuf2.0-dev
|
||||||
(
|
(
|
||||||
cd `mktemp -d`
|
cd `mktemp -d`
|
||||||
curl -L https://github.com/rednex/rgbds/archive/v0.6.0.zip > rgbds.zip
|
curl -L https://github.com/rednex/rgbds/archive/v0.6.0.zip > rgbds.zip
|
||||||
|
|
|
@ -11,7 +11,7 @@ jobs:
|
||||||
strategy:
|
strategy:
|
||||||
fail-fast: false
|
fail-fast: false
|
||||||
matrix:
|
matrix:
|
||||||
os: [macos-latest, ubuntu-latest, ubuntu-20.04]
|
os: [macos-latest, ubuntu-latest, ubuntu-22.04]
|
||||||
cc: [gcc, clang]
|
cc: [gcc, clang]
|
||||||
include:
|
include:
|
||||||
- os: macos-latest
|
- os: macos-latest
|
||||||
|
@ -35,7 +35,7 @@ jobs:
|
||||||
run: |
|
run: |
|
||||||
./.github/actions/sanity_tests.sh
|
./.github/actions/sanity_tests.sh
|
||||||
- name: Upload binaries
|
- name: Upload binaries
|
||||||
uses: actions/upload-artifact@v3
|
uses: actions/upload-artifact@v4
|
||||||
with:
|
with:
|
||||||
name: sameboy-canary-${{ matrix.os }}-${{ matrix.cc }}
|
name: sameboy-canary-${{ matrix.os }}-${{ matrix.cc }}
|
||||||
path: |
|
path: |
|
||||||
|
|
|
@ -5,8 +5,8 @@
|
||||||
@property (nonatomic, strong) void (^renderBlock)(UInt32 sampleRate, UInt32 nFrames, GB_sample_t *buffer);
|
@property (nonatomic, strong) void (^renderBlock)(UInt32 sampleRate, UInt32 nFrames, GB_sample_t *buffer);
|
||||||
@property (nonatomic, readonly) UInt32 rate;
|
@property (nonatomic, readonly) UInt32 rate;
|
||||||
@property (nonatomic, readonly, getter=isPlaying) bool playing;
|
@property (nonatomic, readonly, getter=isPlaying) bool playing;
|
||||||
-(void) start;
|
- (void)start;
|
||||||
-(void) stop;
|
- (void)stop;
|
||||||
-(id) initWithRendererBlock:(void (^)(UInt32 sampleRate, UInt32 nFrames, GB_sample_t *buffer)) block
|
- (id)initWithRendererBlock:(void (^)(UInt32 sampleRate, UInt32 nFrames, GB_sample_t *buffer)) block
|
||||||
andSampleRate:(UInt32) rate;
|
andSampleRate:(UInt32) rate;
|
||||||
@end
|
@end
|
||||||
|
|
|
@ -23,7 +23,7 @@ static OSStatus render(
|
||||||
AudioComponentInstance audioUnit;
|
AudioComponentInstance audioUnit;
|
||||||
}
|
}
|
||||||
|
|
||||||
-(id) initWithRendererBlock:(void (^)(UInt32 sampleRate, UInt32 nFrames, GB_sample_t *buffer)) block
|
- (id)initWithRendererBlock:(void (^)(UInt32 sampleRate, UInt32 nFrames, GB_sample_t *buffer)) block
|
||||||
andSampleRate:(UInt32) rate
|
andSampleRate:(UInt32) rate
|
||||||
{
|
{
|
||||||
if (!(self = [super init])) {
|
if (!(self = [super init])) {
|
||||||
|
|
|
@ -32,5 +32,5 @@ typedef enum {
|
||||||
- (void) createInternalView;
|
- (void) createInternalView;
|
||||||
- (uint32_t *)currentBuffer;
|
- (uint32_t *)currentBuffer;
|
||||||
- (uint32_t *)previousBuffer;
|
- (uint32_t *)previousBuffer;
|
||||||
|
- (instancetype)mirroredView;
|
||||||
@end
|
@end
|
||||||
|
|
|
@ -6,10 +6,13 @@
|
||||||
unsigned _currentBuffer;
|
unsigned _currentBuffer;
|
||||||
GB_frame_blending_mode_t _frameBlendingMode;
|
GB_frame_blending_mode_t _frameBlendingMode;
|
||||||
bool _oddFrame;
|
bool _oddFrame;
|
||||||
|
GBViewBase *_parent;
|
||||||
|
__weak GBViewBase *_child;
|
||||||
}
|
}
|
||||||
|
|
||||||
- (void)screenSizeChanged
|
- (void)screenSizeChanged
|
||||||
{
|
{
|
||||||
|
if (_parent) return;
|
||||||
if (_imageBuffers[0]) free(_imageBuffers[0]);
|
if (_imageBuffers[0]) free(_imageBuffers[0]);
|
||||||
if (_imageBuffers[1]) free(_imageBuffers[1]);
|
if (_imageBuffers[1]) free(_imageBuffers[1]);
|
||||||
if (_imageBuffers[2]) free(_imageBuffers[2]);
|
if (_imageBuffers[2]) free(_imageBuffers[2]);
|
||||||
|
@ -23,12 +26,15 @@
|
||||||
|
|
||||||
- (void)flip
|
- (void)flip
|
||||||
{
|
{
|
||||||
|
if (_parent) return;
|
||||||
_currentBuffer = (_currentBuffer + 1) % self.numberOfBuffers;
|
_currentBuffer = (_currentBuffer + 1) % self.numberOfBuffers;
|
||||||
_oddFrame = GB_is_odd_frame(_gb);
|
_oddFrame = GB_is_odd_frame(_gb);
|
||||||
|
[_child flip];
|
||||||
}
|
}
|
||||||
|
|
||||||
- (unsigned) numberOfBuffers
|
- (unsigned) numberOfBuffers
|
||||||
{
|
{
|
||||||
|
assert(!_parent);
|
||||||
return _frameBlendingMode? 3 : 2;
|
return _frameBlendingMode? 3 : 2;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -39,16 +45,23 @@
|
||||||
|
|
||||||
- (uint32_t *)currentBuffer
|
- (uint32_t *)currentBuffer
|
||||||
{
|
{
|
||||||
|
if (GB_unlikely(_parent)) {
|
||||||
|
return [_parent currentBuffer];
|
||||||
|
}
|
||||||
return _imageBuffers[_currentBuffer];
|
return _imageBuffers[_currentBuffer];
|
||||||
}
|
}
|
||||||
|
|
||||||
- (uint32_t *)previousBuffer
|
- (uint32_t *)previousBuffer
|
||||||
{
|
{
|
||||||
|
if (GB_unlikely(_parent)) {
|
||||||
|
return [_parent previousBuffer];
|
||||||
|
}
|
||||||
return _imageBuffers[(_currentBuffer + 2) % self.numberOfBuffers];
|
return _imageBuffers[(_currentBuffer + 2) % self.numberOfBuffers];
|
||||||
}
|
}
|
||||||
|
|
||||||
- (uint32_t *) pixels
|
- (uint32_t *) pixels
|
||||||
{
|
{
|
||||||
|
assert(!_parent);
|
||||||
return _imageBuffers[(_currentBuffer + 1) % self.numberOfBuffers];
|
return _imageBuffers[(_currentBuffer + 1) % self.numberOfBuffers];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -56,10 +69,14 @@
|
||||||
{
|
{
|
||||||
_frameBlendingMode = frameBlendingMode;
|
_frameBlendingMode = frameBlendingMode;
|
||||||
[self setNeedsDisplay];
|
[self setNeedsDisplay];
|
||||||
|
[_child setNeedsDisplay];
|
||||||
}
|
}
|
||||||
|
|
||||||
- (GB_frame_blending_mode_t)frameBlendingMode
|
- (GB_frame_blending_mode_t)frameBlendingMode
|
||||||
{
|
{
|
||||||
|
if (GB_unlikely(_parent)) {
|
||||||
|
return [_parent frameBlendingMode];
|
||||||
|
}
|
||||||
if (_frameBlendingMode == GB_FRAME_BLENDING_MODE_ACCURATE) {
|
if (_frameBlendingMode == GB_FRAME_BLENDING_MODE_ACCURATE) {
|
||||||
if (!_gb || GB_is_sgb(_gb)) {
|
if (!_gb || GB_is_sgb(_gb)) {
|
||||||
return GB_FRAME_BLENDING_MODE_SIMPLE;
|
return GB_FRAME_BLENDING_MODE_SIMPLE;
|
||||||
|
@ -71,6 +88,7 @@
|
||||||
|
|
||||||
- (void)dealloc
|
- (void)dealloc
|
||||||
{
|
{
|
||||||
|
if (_parent) return;
|
||||||
free(_imageBuffers[0]);
|
free(_imageBuffers[0]);
|
||||||
free(_imageBuffers[1]);
|
free(_imageBuffers[1]);
|
||||||
free(_imageBuffers[2]);
|
free(_imageBuffers[2]);
|
||||||
|
@ -82,4 +100,22 @@
|
||||||
[self setNeedsDisplay:true];
|
[self setNeedsDisplay:true];
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
- (void)setGb:(GB_gameboy_t *)gb
|
||||||
|
{
|
||||||
|
assert(!_parent);
|
||||||
|
_gb = gb;
|
||||||
|
if (_child) {
|
||||||
|
_child->_gb = gb;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
- (instancetype)mirroredView
|
||||||
|
{
|
||||||
|
if (_child) return _child;
|
||||||
|
GBViewBase *ret = [[self.class alloc] initWithFrame:self.bounds];
|
||||||
|
ret->_parent = self;
|
||||||
|
ret->_gb = _gb;
|
||||||
|
return _child = ret;
|
||||||
|
}
|
||||||
@end
|
@end
|
||||||
|
|
|
@ -25,6 +25,7 @@ static const vector_float2 rect[] =
|
||||||
vector_float2 _outputResolution;
|
vector_float2 _outputResolution;
|
||||||
id<MTLCommandBuffer> _commandBuffer;
|
id<MTLCommandBuffer> _commandBuffer;
|
||||||
bool _waitedForFrame;
|
bool _waitedForFrame;
|
||||||
|
_Atomic unsigned _pendingFrames;
|
||||||
}
|
}
|
||||||
|
|
||||||
+ (bool)isSupported
|
+ (bool)isSupported
|
||||||
|
@ -236,8 +237,11 @@ static const vector_float2 rect[] =
|
||||||
- (void)flip
|
- (void)flip
|
||||||
{
|
{
|
||||||
[super flip];
|
[super flip];
|
||||||
|
if (_pendingFrames == 2) return;
|
||||||
|
_pendingFrames++;
|
||||||
dispatch_async(dispatch_get_main_queue(), ^{
|
dispatch_async(dispatch_get_main_queue(), ^{
|
||||||
[(MTKView *)self.internalView draw];
|
[(MTKView *)self.internalView draw];
|
||||||
|
_pendingFrames--;
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
8
BESS.md
|
@ -22,9 +22,9 @@ BESS works by appending a detectable footer at the end of an existing save state
|
||||||
BESS uses a block format where each block contains the following header:
|
BESS uses a block format where each block contains the following header:
|
||||||
|
|
||||||
| Offset | Content |
|
| Offset | Content |
|
||||||
|--------|---------------------------------------|
|
|--------|-----------------------------------------------------------|
|
||||||
| 0 | A four-letter ASCII identifier |
|
| 0 | A four-letter ASCII identifier |
|
||||||
| 4 | Length of the block, excluding header |
|
| 4 | Length of the block as a 32-bit integer, excluding header |
|
||||||
|
|
||||||
Every block is followed by another block, until the END block is reached. If an implementation encounters an unsupported block, it should be completely ignored (Should not have any effect and should not trigger a failure).
|
Every block is followed by another block, until the END block is reached. If an implementation encounters an unsupported block, it should be completely ignored (Should not have any effect and should not trigger a failure).
|
||||||
|
|
||||||
|
@ -256,4 +256,4 @@ Other than previously specified required fail conditions, an implementation is f
|
||||||
* An invalid length of MBC (not a multiple of 3)
|
* An invalid length of MBC (not a multiple of 3)
|
||||||
* A write outside the $0000-$7FFF and $A000-$BFFF ranges in the MBC block
|
* A write outside the $0000-$7FFF and $A000-$BFFF ranges in the MBC block
|
||||||
* An SGB block on a save state targeting another model
|
* An SGB block on a save state targeting another model
|
||||||
* An END block with non-zero length
|
* An END block with non-zero length
|
||||||
|
|
|
@ -1,2 +1,2 @@
|
||||||
DEF AGB = 1
|
DEF AGB = 1
|
||||||
include "cgb_boot.asm"
|
include "cgb_boot.asm"
|
||||||
|
|
|
@ -1,2 +1,2 @@
|
||||||
DEF CGB0 = 1
|
DEF CGB0 = 1
|
||||||
include "cgb_boot.asm"
|
include "cgb_boot.asm"
|
||||||
|
|
|
@ -1,2 +1,2 @@
|
||||||
DEF FAST = 1
|
DEF FAST = 1
|
||||||
include "cgb_boot.asm"
|
include "cgb_boot.asm"
|
||||||
|
|
|
@ -1,14 +1,14 @@
|
||||||
; SameBoy DMG bootstrap ROM
|
; SameBoy DMG bootstrap ROM
|
||||||
|
|
||||||
INCLUDE "hardware.inc"
|
include "sameboot.inc"
|
||||||
|
|
||||||
SECTION "BootCode", ROM0[$0]
|
SECTION "BootCode", ROM0[$0000]
|
||||||
Start:
|
Start:
|
||||||
; Init stack pointer
|
; Init stack pointer
|
||||||
ld sp, $fffe
|
ld sp, $FFFE
|
||||||
|
|
||||||
; Clear memory VRAM
|
; Clear memory VRAM
|
||||||
ld hl, $8000
|
ld hl, _VRAM
|
||||||
xor a
|
xor a
|
||||||
|
|
||||||
.clearVRAMLoop
|
.clearVRAMLoop
|
||||||
|
@ -17,24 +17,25 @@ Start:
|
||||||
jr z, .clearVRAMLoop
|
jr z, .clearVRAMLoop
|
||||||
|
|
||||||
; Init Audio
|
; Init Audio
|
||||||
ld a, $80
|
ld a, AUDENA_ON
|
||||||
ldh [rNR52], a
|
ldh [rNR52], a
|
||||||
|
assert AUDENA_ON == AUDLEN_DUTY_50
|
||||||
ldh [rNR11], a
|
ldh [rNR11], a
|
||||||
ld a, $f3
|
ld a, $F3
|
||||||
ldh [rNR12], a
|
ldh [rNR12], a ; Envelope $F, decreasing, sweep $3
|
||||||
ldh [rNR51], a
|
ldh [rNR51], a ; Channels 1+2+3+4 left, channels 1+2 right
|
||||||
ld a, $77
|
ld a, $77
|
||||||
ldh [rNR50], a
|
ldh [rNR50], a ; Volume $7, left and right
|
||||||
|
|
||||||
; Init BG palette
|
; Init BG palette
|
||||||
ld a, $54
|
ld a, %01_01_01_00
|
||||||
ldh [rBGP], a
|
ldh [rBGP], a
|
||||||
|
|
||||||
; Load logo from ROM.
|
; Load logo from ROM.
|
||||||
; A nibble represents a 4-pixels line, 2 bytes represent a 4x4 tile, scaled to 8x8.
|
; A nibble represents a 4-pixels line, 2 bytes represent a 4x4 tile, scaled to 8x8.
|
||||||
; Tiles are ordered left to right, top to bottom.
|
; Tiles are ordered left to right, top to bottom.
|
||||||
ld de, $104 ; Logo start
|
ld de, NintendoLogo
|
||||||
ld hl, $8010 ; This is where we load the tiles in VRAM
|
ld hl, _VRAM + $10 ; This is where we load the tiles in VRAM
|
||||||
|
|
||||||
.loadLogoLoop
|
.loadLogoLoop
|
||||||
ld a, [de] ; Read 2 rows
|
ld a, [de] ; Read 2 rows
|
||||||
|
@ -43,45 +44,45 @@ Start:
|
||||||
call DoubleBitsAndWriteRow
|
call DoubleBitsAndWriteRow
|
||||||
inc de
|
inc de
|
||||||
ld a, e
|
ld a, e
|
||||||
xor $34 ; End of logo
|
xor LOW(NintendoLogoEnd)
|
||||||
jr nz, .loadLogoLoop
|
jr nz, .loadLogoLoop
|
||||||
|
|
||||||
; Load trademark symbol
|
; Load trademark symbol
|
||||||
ld de, TrademarkSymbol
|
ld de, TrademarkSymbol
|
||||||
ld c,$08
|
ld c, TrademarkSymbolEnd - TrademarkSymbol
|
||||||
.loadTrademarkSymbolLoop:
|
.loadTrademarkSymbolLoop:
|
||||||
ld a,[de]
|
ld a, [de]
|
||||||
inc de
|
inc de
|
||||||
ldi [hl],a
|
ldi [hl], a
|
||||||
inc hl
|
inc hl
|
||||||
dec c
|
dec c
|
||||||
jr nz, .loadTrademarkSymbolLoop
|
jr nz, .loadTrademarkSymbolLoop
|
||||||
|
|
||||||
; Set up tilemap
|
; Set up tilemap
|
||||||
ld a,$19 ; Trademark symbol
|
ld a, $19 ; Trademark symbol tile ID
|
||||||
ld [$9910], a ; ... put in the superscript position
|
ld [_SCRN0 + 8 * SCRN_VX_B + 16], a ; ... put in the superscript position
|
||||||
ld hl,$992f ; Bottom right corner of the logo
|
ld hl, _SCRN0 + 9 * SCRN_VX_B + 15 ; Bottom right corner of the logo
|
||||||
ld c,$c ; Tiles in a logo row
|
ld c, 12 ; Tiles in a logo row
|
||||||
.tilemapLoop
|
.tilemapLoop
|
||||||
dec a
|
dec a
|
||||||
jr z, .tilemapDone
|
jr z, .tilemapDone
|
||||||
ldd [hl], a
|
ldd [hl], a
|
||||||
dec c
|
dec c
|
||||||
jr nz, .tilemapLoop
|
jr nz, .tilemapLoop
|
||||||
ld l,$0f ; Jump to top row
|
ld l, $0F ; Jump to top row
|
||||||
jr .tilemapLoop
|
jr .tilemapLoop
|
||||||
.tilemapDone
|
.tilemapDone
|
||||||
|
|
||||||
ld a, 30
|
ld a, 30
|
||||||
ldh [rSCY], a
|
ldh [rSCY], a
|
||||||
|
|
||||||
; Turn on LCD
|
; Turn on LCD
|
||||||
ld a, $91
|
ld a, LCDCF_ON | LCDCF_BLK01 | LCDCF_BGON
|
||||||
ldh [rLCDC], a
|
ldh [rLCDC], a
|
||||||
|
|
||||||
ld d, (-119) & $FF
|
ld d, LOW(-119)
|
||||||
ld c, 15
|
ld c, 15
|
||||||
|
|
||||||
.animate
|
.animate
|
||||||
call WaitFrame
|
call WaitFrame
|
||||||
ld a, d
|
ld a, d
|
||||||
|
@ -94,41 +95,41 @@ Start:
|
||||||
ld a, c
|
ld a, c
|
||||||
cp 8
|
cp 8
|
||||||
jr nz, .noPaletteChange
|
jr nz, .noPaletteChange
|
||||||
ld a, $A8
|
ld a, %10_10_10_00
|
||||||
ldh [rBGP], a
|
ldh [rBGP], a
|
||||||
.noPaletteChange
|
.noPaletteChange
|
||||||
dec c
|
dec c
|
||||||
jr nz, .animate
|
jr nz, .animate
|
||||||
ld a, $fc
|
ld a, %11_11_11_00
|
||||||
ldh [rBGP], a
|
ldh [rBGP], a
|
||||||
|
|
||||||
; Play first sound
|
; Play first sound
|
||||||
ld a, $83
|
ld a, $83
|
||||||
call PlaySound
|
call PlaySound
|
||||||
ld b, 5
|
ld b, 5
|
||||||
call WaitBFrames
|
call WaitBFrames
|
||||||
; Play second sound
|
; Play second sound
|
||||||
ld a, $c1
|
ld a, $C1
|
||||||
call PlaySound
|
call PlaySound
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
; Wait ~1 second
|
; Wait ~1 second
|
||||||
ld b, 60
|
ld b, 60
|
||||||
call WaitBFrames
|
call WaitBFrames
|
||||||
|
|
||||||
; Set registers to match the original DMG boot
|
; Set registers to match the original DMG boot
|
||||||
IF DEF(MGB)
|
IF DEF(MGB)
|
||||||
ld hl, $FFB0
|
lb hl, BOOTUP_A_MGB, %10110000
|
||||||
ELSE
|
ELSE
|
||||||
ld hl, $01B0
|
lb hl, BOOTUP_A_DMG, %10110000
|
||||||
ENDC
|
ENDC
|
||||||
push hl
|
push hl
|
||||||
pop af
|
pop af
|
||||||
ld hl, $014D
|
ld hl, HeaderChecksum
|
||||||
ld bc, $0013
|
lb bc, 0, LOW(rNR13) ; $0013
|
||||||
ld de, $00D8
|
lb de, 0, $D8 ; $00D8
|
||||||
|
|
||||||
; Boot the game
|
; Boot the game
|
||||||
jp BootGame
|
jp BootGame
|
||||||
|
|
||||||
|
@ -155,7 +156,7 @@ DoubleBitsAndWriteRow:
|
||||||
|
|
||||||
WaitFrame:
|
WaitFrame:
|
||||||
push hl
|
push hl
|
||||||
ld hl, $FF0F
|
ld hl, rIF
|
||||||
res 0, [hl]
|
res 0, [hl]
|
||||||
.wait
|
.wait
|
||||||
bit 0, [hl]
|
bit 0, [hl]
|
||||||
|
@ -171,14 +172,25 @@ WaitBFrames:
|
||||||
|
|
||||||
PlaySound:
|
PlaySound:
|
||||||
ldh [rNR13], a
|
ldh [rNR13], a
|
||||||
ld a, $87
|
ld a, AUDHIGH_RESTART | $7
|
||||||
ldh [rNR14], a
|
ldh [rNR14], a
|
||||||
ret
|
ret
|
||||||
|
|
||||||
|
|
||||||
TrademarkSymbol:
|
TrademarkSymbol:
|
||||||
db $3c,$42,$b9,$a5,$b9,$a5,$42,$3c
|
pusho
|
||||||
|
opt b.X
|
||||||
|
db %..XXXX..
|
||||||
|
db %.X....X.
|
||||||
|
db %X.XXX..X
|
||||||
|
db %X.X..X.X
|
||||||
|
db %X.XXX..X
|
||||||
|
db %X.X..X.X
|
||||||
|
db %.X....X.
|
||||||
|
db %..XXXX..
|
||||||
|
popo
|
||||||
|
TrademarkSymbolEnd:
|
||||||
|
|
||||||
SECTION "BootGame", ROM0[$fe]
|
SECTION "BootGame", ROM0[$00FE]
|
||||||
BootGame:
|
BootGame:
|
||||||
ldh [rBANK], a ; unmap boot ROM
|
ldh [rBANK], a ; unmap boot ROM
|
||||||
|
|
|
@ -1,9 +1,16 @@
|
||||||
;*
|
;*
|
||||||
;* Gameboy Hardware definitions
|
;* Gameboy Hardware definitions
|
||||||
|
;* https://github.com/gbdev/hardware.inc
|
||||||
;*
|
;*
|
||||||
;* Based on Jones' hardware.inc
|
;* Based on Jones' hardware.inc
|
||||||
;* And based on Carsten Sorensen's ideas.
|
;* And based on Carsten Sorensen's ideas.
|
||||||
;*
|
;*
|
||||||
|
;* To the extent possible under law, the authors of this work have
|
||||||
|
;* waived all copyright and related or neighboring rights to the work.
|
||||||
|
;* See https://creativecommons.org/publicdomain/zero/1.0/ for details.
|
||||||
|
;*
|
||||||
|
;* SPDX-License-Identifier: CC0-1.0
|
||||||
|
;*
|
||||||
;* Rev 1.1 - 15-Jul-97 : Added define check
|
;* Rev 1.1 - 15-Jul-97 : Added define check
|
||||||
;* Rev 1.2 - 18-Jul-97 : Added revision check macro
|
;* Rev 1.2 - 18-Jul-97 : Added revision check macro
|
||||||
;* Rev 1.3 - 19-Jul-97 : Modified for RGBASM V1.05
|
;* Rev 1.3 - 19-Jul-97 : Modified for RGBASM V1.05
|
||||||
|
@ -31,6 +38,17 @@
|
||||||
;* Rev 4.3 - 07-Nov-21 : Deprecate VRAM address constants (Eievui)
|
;* Rev 4.3 - 07-Nov-21 : Deprecate VRAM address constants (Eievui)
|
||||||
;* Rev 4.4 - 11-Jan-22 : Deprecate VRAM CART_SRAM_2KB constant (avivace)
|
;* Rev 4.4 - 11-Jan-22 : Deprecate VRAM CART_SRAM_2KB constant (avivace)
|
||||||
;* Rev 4.5 - 03-Mar-22 : Added bit number definitions for OCPS, BCPS and LCDC (sukus)
|
;* Rev 4.5 - 03-Mar-22 : Added bit number definitions for OCPS, BCPS and LCDC (sukus)
|
||||||
|
;* Rev 4.6 - 15-Jun-22 : Added MBC3 registers and special values
|
||||||
|
;* Rev 4.7.0 - 27-Jun-22 : Added alternate names for some constants
|
||||||
|
;* Rev 4.7.1 - 05-Jul-22 : Added RPB_LED_ON constant
|
||||||
|
;* Rev 4.8.0 - 25-Oct-22 : Changed background addressing constants (zlago)
|
||||||
|
;* Rev 4.8.1 - 29-Apr-23 : Added rOPRI (rbong)
|
||||||
|
;* Rev 4.9.0 - 24-Jun-23 : Added definitions for interrupt vectors (sukus)
|
||||||
|
;* Rev 4.9.1 - 11-Sep-23 : Added repository link and CC0 waiver notice
|
||||||
|
|
||||||
|
|
||||||
|
; NOTE: REVISION NUMBER CHANGES MUST BE REFLECTED
|
||||||
|
; IN `rev_Check_hardware_inc` BELOW!
|
||||||
|
|
||||||
IF __RGBDS_MAJOR__ == 0 && __RGBDS_MINOR__ < 5
|
IF __RGBDS_MAJOR__ == 0 && __RGBDS_MINOR__ < 5
|
||||||
FAIL "This version of 'hardware.inc' requires RGBDS version 0.5.0 or later."
|
FAIL "This version of 'hardware.inc' requires RGBDS version 0.5.0 or later."
|
||||||
|
@ -41,14 +59,31 @@ ENDC
|
||||||
IF !DEF(HARDWARE_INC)
|
IF !DEF(HARDWARE_INC)
|
||||||
DEF HARDWARE_INC EQU 1
|
DEF HARDWARE_INC EQU 1
|
||||||
|
|
||||||
|
; Usage: rev_Check_hardware_inc <min_ver>
|
||||||
|
; Examples: rev_Check_hardware_inc 4.1.2
|
||||||
|
; rev_Check_hardware_inc 4.1 (equivalent to 4.1.0)
|
||||||
|
; rev_Check_hardware_inc 4 (equivalent to 4.0.0)
|
||||||
MACRO rev_Check_hardware_inc
|
MACRO rev_Check_hardware_inc
|
||||||
;NOTE: REVISION NUMBER CHANGES MUST BE ADDED
|
DEF CUR_VER equs "4,9,1" ; ** UPDATE THIS LINE WHEN CHANGING THE REVISION NUMBER **
|
||||||
;TO SECOND PARAMETER IN FOLLOWING LINE.
|
|
||||||
IF \1 > 4.5 ;PUT REVISION NUMBER HERE
|
DEF MIN_VER equs STRRPL("\1", ".", ",")
|
||||||
WARN "Version \1 or later of 'hardware.inc' is required."
|
DEF INTERNAL_CHK equs """MACRO ___internal
|
||||||
|
IF \\1 != \\4 || \\2 < \\5 || (\\2 == \\5 && \\3 < \\6)
|
||||||
|
FAIL "Version \\1.\\2.\\3 of 'hardware.inc' is incompatible with requested version \\4.\\5.\\6"
|
||||||
ENDC
|
ENDC
|
||||||
|
\nENDM"""
|
||||||
|
INTERNAL_CHK
|
||||||
|
___internal {CUR_VER}, {MIN_VER},0,0
|
||||||
|
PURGE CUR_VER, MIN_VER, INTERNAL_CHK, ___internal
|
||||||
ENDM
|
ENDM
|
||||||
|
|
||||||
|
|
||||||
|
;***************************************************************************
|
||||||
|
;*
|
||||||
|
;* General memory region constants
|
||||||
|
;*
|
||||||
|
;***************************************************************************
|
||||||
|
|
||||||
DEF _VRAM EQU $8000 ; $8000->$9FFF
|
DEF _VRAM EQU $8000 ; $8000->$9FFF
|
||||||
DEF _SCRN0 EQU $9800 ; $9800->$9BFF
|
DEF _SCRN0 EQU $9800 ; $9800->$9BFF
|
||||||
DEF _SCRN1 EQU $9C00 ; $9C00->$9FFF
|
DEF _SCRN1 EQU $9C00 ; $9C00->$9FFF
|
||||||
|
@ -60,17 +95,80 @@ DEF _IO EQU $FF00 ; $FF00->$FF7F,$FFFF
|
||||||
DEF _AUD3WAVERAM EQU $FF30 ; $FF30->$FF3F
|
DEF _AUD3WAVERAM EQU $FF30 ; $FF30->$FF3F
|
||||||
DEF _HRAM EQU $FF80 ; $FF80->$FFFE
|
DEF _HRAM EQU $FF80 ; $FF80->$FFFE
|
||||||
|
|
||||||
; *** MBC5 Equates ***
|
|
||||||
|
|
||||||
DEF rRAMG EQU $0000 ; $0000->$1fff
|
;***************************************************************************
|
||||||
DEF rROMB0 EQU $2000 ; $2000->$2fff
|
;*
|
||||||
DEF rROMB1 EQU $3000 ; $3000->$3fff - If more than 256 ROM banks are present.
|
;* MBC registers
|
||||||
DEF rRAMB EQU $4000 ; $4000->$5fff - Bit 3 enables rumble (if present)
|
;*
|
||||||
|
;***************************************************************************
|
||||||
|
|
||||||
|
; *** Common ***
|
||||||
|
|
||||||
|
; --
|
||||||
|
; -- RAMG ($0000-$1FFF)
|
||||||
|
; -- Controls whether access to SRAM (and the MBC3 RTC registers) is allowed (W)
|
||||||
|
; --
|
||||||
|
DEF rRAMG EQU $0000
|
||||||
|
|
||||||
|
DEF CART_SRAM_ENABLE EQU $0A
|
||||||
|
DEF CART_SRAM_DISABLE EQU $00
|
||||||
|
|
||||||
|
|
||||||
|
; --
|
||||||
|
; -- ROMB0 ($2000-$3FFF)
|
||||||
|
; -- Selects which ROM bank is mapped to the ROMX space ($4000-$7FFF) (W)
|
||||||
|
; --
|
||||||
|
; -- The range of accepted values, as well as the behavior of writing $00,
|
||||||
|
; -- varies depending on the MBC.
|
||||||
|
; --
|
||||||
|
DEF rROMB0 EQU $2000
|
||||||
|
|
||||||
|
; --
|
||||||
|
; -- RAMB ($4000-$5FFF)
|
||||||
|
; -- Selects which SRAM bank is mapped to the SRAM space ($A000-$BFFF) (W)
|
||||||
|
; --
|
||||||
|
; -- The range of accepted values varies depending on the cartridge configuration.
|
||||||
|
; --
|
||||||
|
DEF rRAMB EQU $4000
|
||||||
|
|
||||||
|
|
||||||
|
; *** MBC3-specific registers ***
|
||||||
|
|
||||||
|
; Write one of these to rRAMG to map the corresponding RTC register to all SRAM space
|
||||||
|
DEF RTC_S EQU $08 ; Seconds (0-59)
|
||||||
|
DEF RTC_M EQU $09 ; Minutes (0-59)
|
||||||
|
DEF RTC_H EQU $0A ; Hours (0-23)
|
||||||
|
DEF RTC_DL EQU $0B ; Lower 8 bits of Day Counter ($00-$FF)
|
||||||
|
DEF RTC_DH EQU $0C ; Bit 7 - Day Counter Carry Bit (1=Counter Overflow)
|
||||||
|
; Bit 6 - Halt (0=Active, 1=Stop Timer)
|
||||||
|
; Bit 0 - Most significant bit of Day Counter (Bit 8)
|
||||||
|
|
||||||
|
|
||||||
|
; --
|
||||||
|
; -- RTCLATCH ($6000-$7FFF)
|
||||||
|
; -- Write $00 then $01 to latch the current time into the RTC registers (W)
|
||||||
|
; --
|
||||||
|
DEF rRTCLATCH EQU $6000
|
||||||
|
|
||||||
|
|
||||||
|
; *** MBC5-specific register ***
|
||||||
|
|
||||||
|
; --
|
||||||
|
; -- ROMB1 ($3000-$3FFF)
|
||||||
|
; -- A 9th bit that "extends" ROMB0 if more than 256 banks are present (W)
|
||||||
|
; --
|
||||||
|
; -- Also note that rROMB0 thus only spans $2000-$2FFF.
|
||||||
|
; --
|
||||||
|
DEF rROMB1 EQU $3000
|
||||||
|
|
||||||
|
|
||||||
|
; Bit 3 of RAMB enables the rumble motor (if any)
|
||||||
|
DEF CART_RUMBLE_ON EQU 1 << 3
|
||||||
|
|
||||||
|
|
||||||
;***************************************************************************
|
;***************************************************************************
|
||||||
;*
|
;*
|
||||||
;* Custom registers
|
;* Memory-mapped registers
|
||||||
;*
|
;*
|
||||||
;***************************************************************************
|
;***************************************************************************
|
||||||
|
|
||||||
|
@ -105,9 +203,9 @@ DEF rSB EQU $FF01
|
||||||
; --
|
; --
|
||||||
DEF rSC EQU $FF02
|
DEF rSC EQU $FF02
|
||||||
|
|
||||||
DEF SCF_START EQU %10000000 ;Transfer Start Flag (1=Transfer in progress, or requested)
|
DEF SCF_START EQU %10000000 ; Transfer Start Flag (1=Transfer in progress, or requested)
|
||||||
DEF SCF_SPEED EQU %00000010 ;Clock Speed (0=Normal, 1=Fast) ** CGB Mode Only **
|
DEF SCF_SPEED EQU %00000010 ; Clock Speed (0=Normal, 1=Fast) ** CGB Mode Only **
|
||||||
DEF SCF_SOURCE EQU %00000001 ;Shift Clock (0=External Clock, 1=Internal Clock)
|
DEF SCF_SOURCE EQU %00000001 ; Shift Clock (0=External Clock, 1=Internal Clock)
|
||||||
|
|
||||||
DEF SCB_START EQU 7
|
DEF SCB_START EQU 7
|
||||||
DEF SCB_SPEED EQU 1
|
DEF SCB_SPEED EQU 1
|
||||||
|
@ -444,8 +542,8 @@ DEF LCDCF_WIN9800 EQU %00000000 ; Window Tile Map Display Select
|
||||||
DEF LCDCF_WIN9C00 EQU %01000000 ; Window Tile Map Display Select
|
DEF LCDCF_WIN9C00 EQU %01000000 ; Window Tile Map Display Select
|
||||||
DEF LCDCF_WINOFF EQU %00000000 ; Window Display
|
DEF LCDCF_WINOFF EQU %00000000 ; Window Display
|
||||||
DEF LCDCF_WINON EQU %00100000 ; Window Display
|
DEF LCDCF_WINON EQU %00100000 ; Window Display
|
||||||
DEF LCDCF_BG8800 EQU %00000000 ; BG & Window Tile Data Select
|
DEF LCDCF_BLK21 EQU %00000000 ; BG & Window Tile Data Select
|
||||||
DEF LCDCF_BG8000 EQU %00010000 ; BG & Window Tile Data Select
|
DEF LCDCF_BLK01 EQU %00010000 ; BG & Window Tile Data Select
|
||||||
DEF LCDCF_BG9800 EQU %00000000 ; BG Tile Map Display Select
|
DEF LCDCF_BG9800 EQU %00000000 ; BG Tile Map Display Select
|
||||||
DEF LCDCF_BG9C00 EQU %00001000 ; BG Tile Map Display Select
|
DEF LCDCF_BG9C00 EQU %00001000 ; BG Tile Map Display Select
|
||||||
DEF LCDCF_OBJ8 EQU %00000000 ; OBJ Construction
|
DEF LCDCF_OBJ8 EQU %00000000 ; OBJ Construction
|
||||||
|
@ -458,7 +556,7 @@ DEF LCDCF_BGON EQU %00000001 ; BG Display
|
||||||
DEF LCDCB_ON EQU 7 ; LCD Control Operation
|
DEF LCDCB_ON EQU 7 ; LCD Control Operation
|
||||||
DEF LCDCB_WIN9C00 EQU 6 ; Window Tile Map Display Select
|
DEF LCDCB_WIN9C00 EQU 6 ; Window Tile Map Display Select
|
||||||
DEF LCDCB_WINON EQU 5 ; Window Display
|
DEF LCDCB_WINON EQU 5 ; Window Display
|
||||||
DEF LCDCB_BG8000 EQU 4 ; BG & Window Tile Data Select
|
DEF LCDCB_BLKS EQU 4 ; BG & Window Tile Data Select
|
||||||
DEF LCDCB_BG9C00 EQU 3 ; BG Tile Map Display Select
|
DEF LCDCB_BG9C00 EQU 3 ; BG Tile Map Display Select
|
||||||
DEF LCDCB_OBJ16 EQU 2 ; OBJ Construction
|
DEF LCDCB_OBJ16 EQU 2 ; OBJ Construction
|
||||||
DEF LCDCB_OBJON EQU 1 ; OBJ Display
|
DEF LCDCB_OBJON EQU 1 ; OBJ Display
|
||||||
|
@ -661,39 +759,65 @@ DEF RPF_DATAIN EQU %00000010 ; 0=Receiving IR Signal, 1=Normal
|
||||||
DEF RPF_WRITE_HI EQU %00000001
|
DEF RPF_WRITE_HI EQU %00000001
|
||||||
DEF RPF_WRITE_LO EQU %00000000
|
DEF RPF_WRITE_LO EQU %00000000
|
||||||
|
|
||||||
|
DEF RPB_LED_ON EQU 0
|
||||||
|
DEF RPB_DATAIN EQU 1
|
||||||
|
|
||||||
|
|
||||||
; --
|
; --
|
||||||
; -- BCPS ($FF68)
|
; -- BCPS/BGPI ($FF68)
|
||||||
; -- Background Color Palette Specification (R/W)
|
; -- Background Color Palette Specification (aka Background Palette Index) (R/W)
|
||||||
; --
|
; --
|
||||||
DEF rBCPS EQU $FF68
|
DEF rBCPS EQU $FF68
|
||||||
|
DEF rBGPI EQU rBCPS
|
||||||
|
|
||||||
DEF BCPSF_AUTOINC EQU %10000000 ; Auto Increment (0=Disabled, 1=Increment after Writing)
|
DEF BCPSF_AUTOINC EQU %10000000 ; Auto Increment (0=Disabled, 1=Increment after Writing)
|
||||||
DEF BCPSB_AUTOINC EQU 7
|
DEF BCPSB_AUTOINC EQU 7
|
||||||
|
DEF BGPIF_AUTOINC EQU BCPSF_AUTOINC
|
||||||
|
DEF BGPIB_AUTOINC EQU BCPSB_AUTOINC
|
||||||
|
|
||||||
|
|
||||||
; --
|
; --
|
||||||
; -- BCPD ($FF69)
|
; -- BCPD/BGPD ($FF69)
|
||||||
; -- Background Color Palette Data (R/W)
|
; -- Background Color Palette Data (aka Background Palette Data) (R/W)
|
||||||
; --
|
; --
|
||||||
DEF rBCPD EQU $FF69
|
DEF rBCPD EQU $FF69
|
||||||
|
DEF rBGPD EQU rBCPD
|
||||||
|
|
||||||
|
|
||||||
; --
|
; --
|
||||||
; -- OCPS ($FF6A)
|
; -- OCPS/OBPI ($FF6A)
|
||||||
; -- Object Color Palette Specification (R/W)
|
; -- Object Color Palette Specification (aka Object Background Palette Index) (R/W)
|
||||||
; --
|
; --
|
||||||
DEF rOCPS EQU $FF6A
|
DEF rOCPS EQU $FF6A
|
||||||
|
DEF rOBPI EQU rOCPS
|
||||||
|
|
||||||
DEF OCPSF_AUTOINC EQU %10000000 ; Auto Increment (0=Disabled, 1=Increment after Writing)
|
DEF OCPSF_AUTOINC EQU %10000000 ; Auto Increment (0=Disabled, 1=Increment after Writing)
|
||||||
DEF OCPSB_AUTOINC EQU 7
|
DEF OCPSB_AUTOINC EQU 7
|
||||||
|
DEF OBPIF_AUTOINC EQU OCPSF_AUTOINC
|
||||||
|
DEF OBPIB_AUTOINC EQU OCPSB_AUTOINC
|
||||||
|
|
||||||
|
|
||||||
; --
|
; --
|
||||||
; -- OCPD ($FF6B)
|
; -- OCPD/OBPD ($FF6B)
|
||||||
; -- Object Color Palette Data (R/W)
|
; -- Object Color Palette Data (aka Object Background Palette Data) (R/W)
|
||||||
; --
|
; --
|
||||||
DEF rOCPD EQU $FF6B
|
DEF rOCPD EQU $FF6B
|
||||||
|
DEF rOBPD EQU rOCPD
|
||||||
|
|
||||||
|
|
||||||
|
; --
|
||||||
|
; -- OPRI ($FF6C)
|
||||||
|
; -- Object Priority Mode (R/W)
|
||||||
|
; -- CGB Only
|
||||||
|
|
||||||
|
; --
|
||||||
|
; -- Priority can be changed only from the boot ROM
|
||||||
|
; --
|
||||||
|
DEF rOPRI EQU $FF6C
|
||||||
|
|
||||||
|
DEF OPRI_OAM EQU 0 ; Prioritize objects by location in OAM (CGB Mode default)
|
||||||
|
DEF OPRI_COORD EQU 1 ; Prioritize objects by x-coordinate (Non-CGB Mode default)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
; --
|
; --
|
||||||
|
@ -726,17 +850,6 @@ DEF rPCM12 EQU $FF76
|
||||||
DEF rPCM34 EQU $FF77
|
DEF rPCM34 EQU $FF77
|
||||||
|
|
||||||
|
|
||||||
; SameBoy additions
|
|
||||||
DEF rKEY0 EQU $FF4C
|
|
||||||
DEF rBANK EQU $FF50
|
|
||||||
DEF rOPRI EQU $FF6C
|
|
||||||
|
|
||||||
DEF rJOYP EQU rP1
|
|
||||||
DEF rBGPI EQU rBCPS
|
|
||||||
DEF rBGPD EQU rBCPD
|
|
||||||
DEF rOBPI EQU rOCPS
|
|
||||||
DEF rOBPD EQU rOCPD
|
|
||||||
|
|
||||||
; --
|
; --
|
||||||
; -- IE ($FFFF)
|
; -- IE ($FFFF)
|
||||||
; -- Interrupt Enable (R/W)
|
; -- Interrupt Enable (R/W)
|
||||||
|
@ -790,7 +903,6 @@ DEF AUDENV_DOWN EQU %00000000
|
||||||
; -- Can be used with AUD1HIGH, AUD2HIGH, AUD3HIGH
|
; -- Can be used with AUD1HIGH, AUD2HIGH, AUD3HIGH
|
||||||
; -- See AUD1HIGH for more info
|
; -- See AUD1HIGH for more info
|
||||||
; --
|
; --
|
||||||
|
|
||||||
DEF AUDHIGH_RESTART EQU %10000000
|
DEF AUDHIGH_RESTART EQU %10000000
|
||||||
DEF AUDHIGH_LENGTH_ON EQU %01000000
|
DEF AUDHIGH_LENGTH_ON EQU %01000000
|
||||||
DEF AUDHIGH_LENGTH_OFF EQU %00000000
|
DEF AUDHIGH_LENGTH_OFF EQU %00000000
|
||||||
|
@ -814,10 +926,33 @@ DEF BOOTUP_B_AGB EQU %00000001 ; GBA, GBA SP, Game Boy Player, or New GBA S
|
||||||
|
|
||||||
;***************************************************************************
|
;***************************************************************************
|
||||||
;*
|
;*
|
||||||
;* Cart related
|
;* Interrupt vector addresses
|
||||||
;*
|
;*
|
||||||
;***************************************************************************
|
;***************************************************************************
|
||||||
|
|
||||||
|
DEF INT_HANDLER_VBLANK EQU $0040
|
||||||
|
DEF INT_HANDLER_STAT EQU $0048
|
||||||
|
DEF INT_HANDLER_TIMER EQU $0050
|
||||||
|
DEF INT_HANDLER_SERIAL EQU $0058
|
||||||
|
DEF INT_HANDLER_JOYPAD EQU $0060
|
||||||
|
|
||||||
|
|
||||||
|
;***************************************************************************
|
||||||
|
;*
|
||||||
|
;* Header
|
||||||
|
;*
|
||||||
|
;***************************************************************************
|
||||||
|
|
||||||
|
;*
|
||||||
|
;* Nintendo scrolling logo
|
||||||
|
;* (Code won't work on a real GameBoy)
|
||||||
|
;* (if next lines are altered.)
|
||||||
|
MACRO NINTENDO_LOGO
|
||||||
|
DB $CE,$ED,$66,$66,$CC,$0D,$00,$0B,$03,$73,$00,$83,$00,$0C,$00,$0D
|
||||||
|
DB $00,$08,$11,$1F,$88,$89,$00,$0E,$DC,$CC,$6E,$E6,$DD,$DD,$D9,$99
|
||||||
|
DB $BB,$BB,$67,$63,$6E,$0E,$EC,$CC,$DD,$DC,$99,$9F,$BB,$B9,$33,$3E
|
||||||
|
ENDM
|
||||||
|
|
||||||
; $0143 Color GameBoy compatibility code
|
; $0143 Color GameBoy compatibility code
|
||||||
DEF CART_COMPATIBLE_DMG EQU $00
|
DEF CART_COMPATIBLE_DMG EQU $00
|
||||||
DEF CART_COMPATIBLE_DMG_GBC EQU $80
|
DEF CART_COMPATIBLE_DMG_GBC EQU $80
|
||||||
|
@ -878,9 +1013,6 @@ DEF CART_SRAM_8KB EQU 2 ; 1 bank
|
||||||
DEF CART_SRAM_32KB EQU 3 ; 4 banks
|
DEF CART_SRAM_32KB EQU 3 ; 4 banks
|
||||||
DEF CART_SRAM_128KB EQU 4 ; 16 banks
|
DEF CART_SRAM_128KB EQU 4 ; 16 banks
|
||||||
|
|
||||||
DEF CART_SRAM_ENABLE EQU $0A
|
|
||||||
DEF CART_SRAM_DISABLE EQU $00
|
|
||||||
|
|
||||||
; $014A Destination code
|
; $014A Destination code
|
||||||
DEF CART_DEST_JAPANESE EQU $00
|
DEF CART_DEST_JAPANESE EQU $00
|
||||||
DEF CART_DEST_NON_JAPANESE EQU $01
|
DEF CART_DEST_NON_JAPANESE EQU $01
|
||||||
|
@ -918,7 +1050,7 @@ DEF PADB_A EQU $0
|
||||||
;***************************************************************************
|
;***************************************************************************
|
||||||
|
|
||||||
DEF SCRN_X EQU 160 ; Width of screen in pixels
|
DEF SCRN_X EQU 160 ; Width of screen in pixels
|
||||||
DEF SCRN_Y EQU 144 ; Height of screen in pixels
|
DEF SCRN_Y EQU 144 ; Height of screen in pixels. Also corresponds to the value in LY at the beginning of VBlank.
|
||||||
DEF SCRN_X_B EQU 20 ; Width of screen in bytes
|
DEF SCRN_X_B EQU 20 ; Width of screen in bytes
|
||||||
DEF SCRN_Y_B EQU 18 ; Height of screen in bytes
|
DEF SCRN_Y_B EQU 18 ; Height of screen in bytes
|
||||||
|
|
||||||
|
@ -966,16 +1098,6 @@ DEF OAMB_PAL1 EQU 4 ; Palette number; 0,1 (DMG)
|
||||||
DEF OAMB_BANK1 EQU 3 ; Bank number; 0,1 (GBC)
|
DEF OAMB_BANK1 EQU 3 ; Bank number; 0,1 (GBC)
|
||||||
|
|
||||||
|
|
||||||
;*
|
|
||||||
;* Nintendo scrolling logo
|
|
||||||
;* (Code won't work on a real GameBoy)
|
|
||||||
;* (if next lines are altered.)
|
|
||||||
MACRO NINTENDO_LOGO
|
|
||||||
DB $CE,$ED,$66,$66,$CC,$0D,$00,$0B,$03,$73,$00,$83,$00,$0C,$00,$0D
|
|
||||||
DB $00,$08,$11,$1F,$88,$89,$00,$0E,$DC,$CC,$6E,$E6,$DD,$DD,$D9,$99
|
|
||||||
DB $BB,$BB,$67,$63,$6E,$0E,$EC,$CC,$DD,$DC,$99,$9F,$BB,$B9,$33,$3E
|
|
||||||
ENDM
|
|
||||||
|
|
||||||
; Deprecated constants. Please avoid using.
|
; Deprecated constants. Please avoid using.
|
||||||
|
|
||||||
DEF IEF_LCDC EQU %00000010 ; LCDC (see STAT)
|
DEF IEF_LCDC EQU %00000010 ; LCDC (see STAT)
|
||||||
|
@ -983,6 +1105,9 @@ DEF _VRAM8000 EQU _VRAM
|
||||||
DEF _VRAM8800 EQU _VRAM+$800
|
DEF _VRAM8800 EQU _VRAM+$800
|
||||||
DEF _VRAM9000 EQU _VRAM+$1000
|
DEF _VRAM9000 EQU _VRAM+$1000
|
||||||
DEF CART_SRAM_2KB EQU 1 ; 1 incomplete bank
|
DEF CART_SRAM_2KB EQU 1 ; 1 incomplete bank
|
||||||
|
DEF LCDCF_BG8800 EQU %00000000 ; BG & Window Tile Data Select
|
||||||
|
DEF LCDCF_BG8000 EQU %00010000 ; BG & Window Tile Data Select
|
||||||
|
DEF LCDCB_BG8000 EQU 4 ; BG & Window Tile Data Select
|
||||||
|
|
||||||
|
|
||||||
ENDC ;HARDWARE_INC
|
ENDC ;HARDWARE_INC
|
||||||
|
|
|
@ -1,2 +1,2 @@
|
||||||
DEF MGB = 1
|
DEF MGB = 1
|
||||||
include "dmg_boot.asm"
|
include "dmg_boot.asm"
|
||||||
|
|
|
@ -0,0 +1,40 @@
|
||||||
|
IF !DEF(SAMEBOY_INC)
|
||||||
|
DEF SAMEBOY_INC EQU 1
|
||||||
|
|
||||||
|
include "hardware.inc"
|
||||||
|
|
||||||
|
DEF rKEY0 EQU $FF4C
|
||||||
|
DEF rBANK EQU $FF50
|
||||||
|
|
||||||
|
DEF rJOYP EQU rP1
|
||||||
|
|
||||||
|
|
||||||
|
MACRO lb ; r16, high, low
|
||||||
|
ld \1, LOW(\2) << 8 | LOW(\3)
|
||||||
|
ENDM
|
||||||
|
|
||||||
|
|
||||||
|
MACRO header_section ; name, address
|
||||||
|
PUSHS
|
||||||
|
SECTION "\1", ROM0[\2]
|
||||||
|
\1:
|
||||||
|
POPS
|
||||||
|
ENDM
|
||||||
|
header_section EntryPoint, $0100
|
||||||
|
header_section NintendoLogo, $0104
|
||||||
|
header_section NintendoLogoEnd, $0134
|
||||||
|
header_section Title, $0134
|
||||||
|
header_section ManufacturerCode, $013F
|
||||||
|
header_section CGBFlag, $0143
|
||||||
|
header_section NewLicenseeCode, $0144
|
||||||
|
header_section SGBFlag, $0146
|
||||||
|
header_section CartridgeType, $0147
|
||||||
|
header_section ROMSize, $0148
|
||||||
|
header_section RAMSize, $0149
|
||||||
|
header_section DestinationCode, $014A
|
||||||
|
header_section OldLicenseeCode, $014B
|
||||||
|
header_section MaskRomVersion, $014C
|
||||||
|
header_section HeaderChecksum, $014D
|
||||||
|
header_section GlobalChecksum, $014E
|
||||||
|
|
||||||
|
ENDC
|
|
@ -1,2 +1,2 @@
|
||||||
DEF SGB2 = 1
|
DEF SGB2 = 1
|
||||||
include "sgb_boot.asm"
|
include "sgb_boot.asm"
|
||||||
|
|
|
@ -1,14 +1,14 @@
|
||||||
; SameBoy SGB bootstrap ROM
|
; SameBoy SGB bootstrap ROM
|
||||||
|
|
||||||
INCLUDE "hardware.inc"
|
include "sameboot.inc"
|
||||||
|
|
||||||
SECTION "BootCode", ROM0[$0]
|
SECTION "BootCode", ROM0[$0000]
|
||||||
Start:
|
Start:
|
||||||
; Init stack pointer
|
; Init stack pointer
|
||||||
ld sp, $fffe
|
ld sp, $FFFE
|
||||||
|
|
||||||
; Clear memory VRAM
|
; Clear memory VRAM
|
||||||
ld hl, $8000
|
ld hl, _VRAM
|
||||||
xor a
|
xor a
|
||||||
|
|
||||||
.clearVRAMLoop
|
.clearVRAMLoop
|
||||||
|
@ -17,24 +17,25 @@ Start:
|
||||||
jr z, .clearVRAMLoop
|
jr z, .clearVRAMLoop
|
||||||
|
|
||||||
; Init Audio
|
; Init Audio
|
||||||
ld a, $80
|
ld a, AUDENA_ON
|
||||||
ldh [rNR52], a
|
ldh [rNR52], a
|
||||||
|
assert AUDENA_ON == AUDLEN_DUTY_50
|
||||||
ldh [rNR11], a
|
ldh [rNR11], a
|
||||||
ld a, $f3
|
ld a, $F3
|
||||||
ldh [rNR12], a
|
ldh [rNR12], a ; Envelope $F, decreasing, sweep $3
|
||||||
ldh [rNR51], a
|
ldh [rNR51], a ; Channels 1+2+3+4 left, channels 1+2 right
|
||||||
ld a, $77
|
ld a, $77
|
||||||
ldh [rNR50], a
|
ldh [rNR50], a ; Volume $7, left and right
|
||||||
|
|
||||||
; Init BG palette to white
|
; Init BG palette to white
|
||||||
ld a, $0
|
ld a, %00_00_00_00
|
||||||
ldh [rBGP], a
|
ldh [rBGP], a
|
||||||
|
|
||||||
; Load logo from ROM.
|
; Load logo from ROM.
|
||||||
; A nibble represents a 4-pixels line, 2 bytes represent a 4x4 tile, scaled to 8x8.
|
; A nibble represents a 4-pixels line, 2 bytes represent a 4x4 tile, scaled to 8x8.
|
||||||
; Tiles are ordered left to right, top to bottom.
|
; Tiles are ordered left to right, top to bottom.
|
||||||
ld de, $104 ; Logo start
|
ld de, NintendoLogo
|
||||||
ld hl, $8010 ; This is where we load the tiles in VRAM
|
ld hl, _VRAM + $10 ; This is where we load the tiles in VRAM
|
||||||
|
|
||||||
.loadLogoLoop
|
.loadLogoLoop
|
||||||
ld a, [de] ; Read 2 rows
|
ld a, [de] ; Read 2 rows
|
||||||
|
@ -43,82 +44,82 @@ Start:
|
||||||
call DoubleBitsAndWriteRow
|
call DoubleBitsAndWriteRow
|
||||||
inc de
|
inc de
|
||||||
ld a, e
|
ld a, e
|
||||||
xor $34 ; End of logo
|
xor LOW(NintendoLogoEnd)
|
||||||
jr nz, .loadLogoLoop
|
jr nz, .loadLogoLoop
|
||||||
|
|
||||||
; Load trademark symbol
|
; Load trademark symbol
|
||||||
ld de, TrademarkSymbol
|
ld de, TrademarkSymbol
|
||||||
ld c,$08
|
ld c, TrademarkSymbolEnd - TrademarkSymbol
|
||||||
.loadTrademarkSymbolLoop:
|
.loadTrademarkSymbolLoop:
|
||||||
ld a,[de]
|
ld a, [de]
|
||||||
inc de
|
inc de
|
||||||
ldi [hl],a
|
ldi [hl], a
|
||||||
inc hl
|
inc hl
|
||||||
dec c
|
dec c
|
||||||
jr nz, .loadTrademarkSymbolLoop
|
jr nz, .loadTrademarkSymbolLoop
|
||||||
|
|
||||||
; Set up tilemap
|
; Set up tilemap
|
||||||
ld a,$19 ; Trademark symbol
|
ld a, $19 ; Trademark symbol tile ID
|
||||||
ld [$9910], a ; ... put in the superscript position
|
ld [_SCRN0 + 8 * SCRN_VX_B + 16], a ; ... put in the superscript position
|
||||||
ld hl,$992f ; Bottom right corner of the logo
|
ld hl, _SCRN0 + 9 * SCRN_VX_B + 15 ; Bottom right corner of the logo
|
||||||
ld c,$c ; Tiles in a logo row
|
ld c, 12 ; Tiles in a logo row
|
||||||
.tilemapLoop
|
.tilemapLoop
|
||||||
dec a
|
dec a
|
||||||
jr z, .tilemapDone
|
jr z, .tilemapDone
|
||||||
ldd [hl], a
|
ldd [hl], a
|
||||||
dec c
|
dec c
|
||||||
jr nz, .tilemapLoop
|
jr nz, .tilemapLoop
|
||||||
ld l,$0f ; Jump to top row
|
ld l, $0F ; Jump to top row
|
||||||
jr .tilemapLoop
|
jr .tilemapLoop
|
||||||
.tilemapDone
|
.tilemapDone
|
||||||
|
|
||||||
; Turn on LCD
|
; Turn on LCD
|
||||||
ld a, $91
|
ld a, LCDCF_ON | LCDCF_BLK01 | LCDCF_BGON
|
||||||
ldh [rLCDC], a
|
ldh [rLCDC], a
|
||||||
|
|
||||||
ld a, $f1 ; Packet magic, increases by 2 for every packet
|
ld a, $F1 ; Packet magic, increases by 2 for every packet
|
||||||
ldh [_HRAM], a
|
ldh [hCommand], a
|
||||||
ld hl, $104 ; Header start
|
ld hl, NintendoLogo ; Header start
|
||||||
|
|
||||||
xor a
|
xor a
|
||||||
ld c, a ; JOYP
|
ld c, a ; JOYP
|
||||||
|
|
||||||
.sendCommand
|
.sendCommand
|
||||||
xor a
|
xor a
|
||||||
ld [c], a
|
ldh [c], a
|
||||||
ld a, $30
|
ld a, $30
|
||||||
ld [c], a
|
ldh [c], a
|
||||||
|
|
||||||
ldh a, [_HRAM]
|
ldh a, [hCommand]
|
||||||
call SendByte
|
call SendByte
|
||||||
push hl
|
push hl
|
||||||
ld b, $e
|
|
||||||
|
ld b, 14
|
||||||
ld d, 0
|
ld d, 0
|
||||||
|
|
||||||
.checksumLoop
|
.checksumLoop
|
||||||
call ReadHeaderByte
|
call ReadHeaderByte
|
||||||
add d
|
add d
|
||||||
ld d, a
|
ld d, a
|
||||||
dec b
|
dec b
|
||||||
jr nz, .checksumLoop
|
jr nz, .checksumLoop
|
||||||
|
|
||||||
; Send checksum
|
; Send checksum
|
||||||
call SendByte
|
call SendByte
|
||||||
pop hl
|
pop hl
|
||||||
|
|
||||||
ld b, $e
|
ld b, 14
|
||||||
.sendLoop
|
.sendLoop
|
||||||
call ReadHeaderByte
|
call ReadHeaderByte
|
||||||
call SendByte
|
call SendByte
|
||||||
dec b
|
dec b
|
||||||
jr nz, .sendLoop
|
jr nz, .sendLoop
|
||||||
|
|
||||||
; Done bit
|
; Done bit
|
||||||
ld a, $20
|
ld a, $20
|
||||||
ld [c], a
|
ldh [c], a
|
||||||
ld a, $30
|
ld a, $30
|
||||||
ld [c], a
|
ldh [c], a
|
||||||
|
|
||||||
; Wait 4 frames
|
; Wait 4 frames
|
||||||
ld e, 4
|
ld e, 4
|
||||||
ld a, 1
|
ld a, 1
|
||||||
|
@ -126,41 +127,41 @@ Start:
|
||||||
xor a
|
xor a
|
||||||
.waitLoop
|
.waitLoop
|
||||||
ldh [rIF], a
|
ldh [rIF], a
|
||||||
db $76 ; halt, compatible with rgbds 0.5-0.8
|
halt
|
||||||
nop
|
nop
|
||||||
dec e
|
dec e
|
||||||
jr nz, .waitLoop
|
jr nz, .waitLoop
|
||||||
ldh [rIE], a
|
ldh [rIE], a
|
||||||
|
|
||||||
; Update command
|
; Update command
|
||||||
ldh a, [_HRAM]
|
ldh a, [hCommand]
|
||||||
add 2
|
add 2
|
||||||
ldh [_HRAM], a
|
ldh [hCommand], a
|
||||||
|
|
||||||
ld a, $58
|
ld a, $58
|
||||||
cp l
|
cp l
|
||||||
jr nz, .sendCommand
|
jr nz, .sendCommand
|
||||||
|
|
||||||
; Write to sound registers for DMG compatibility
|
; Write to sound registers for DMG compatibility
|
||||||
ld c, $13
|
ld c, LOW(rNR13)
|
||||||
ld a, $c1
|
ld a, $C1
|
||||||
ld [c], a
|
ldh [c], a
|
||||||
inc c
|
inc c
|
||||||
ld a, 7
|
ld a, $7
|
||||||
ld [c], a
|
ldh [c], a
|
||||||
|
|
||||||
; Init BG palette
|
; Init BG palette
|
||||||
ld a, $fc
|
ld a, %11_11_11_00
|
||||||
ldh [rBGP], a
|
ldh [rBGP], a
|
||||||
|
|
||||||
; Set registers to match the original SGB boot
|
; Set registers to match the original SGB boot
|
||||||
IF DEF(SGB2)
|
IF DEF(SGB2)
|
||||||
ld a, $FF
|
ld a, BOOTUP_A_MGB
|
||||||
ELSE
|
ELSE
|
||||||
ld a, 1
|
ld a, BOOTUP_A_DMG
|
||||||
ENDC
|
ENDC
|
||||||
ld hl, $c060
|
ld hl, $C060
|
||||||
|
|
||||||
; Boot the game
|
; Boot the game
|
||||||
jp BootGame
|
jp BootGame
|
||||||
|
|
||||||
|
@ -184,9 +185,9 @@ SendByte:
|
||||||
jr c, .zeroBit
|
jr c, .zeroBit
|
||||||
add a ; 10 -> 20
|
add a ; 10 -> 20
|
||||||
.zeroBit
|
.zeroBit
|
||||||
ld [c], a
|
ldh [c], a
|
||||||
ld a, $30
|
ld a, $30
|
||||||
ld [c], a
|
ldh [c], a
|
||||||
dec d
|
dec d
|
||||||
ret z
|
ret z
|
||||||
jr .loop
|
jr .loop
|
||||||
|
@ -212,8 +213,23 @@ DoubleBitsAndWriteRow:
|
||||||
ret
|
ret
|
||||||
|
|
||||||
TrademarkSymbol:
|
TrademarkSymbol:
|
||||||
db $3c,$42,$b9,$a5,$b9,$a5,$42,$3c
|
pusho
|
||||||
|
opt b.X
|
||||||
|
db %..XXXX..
|
||||||
|
db %.X....X.
|
||||||
|
db %X.XXX..X
|
||||||
|
db %X.X..X.X
|
||||||
|
db %X.XXX..X
|
||||||
|
db %X.X..X.X
|
||||||
|
db %.X....X.
|
||||||
|
db %..XXXX..
|
||||||
|
popo
|
||||||
|
TrademarkSymbolEnd:
|
||||||
|
|
||||||
SECTION "BootGame", ROM0[$fe]
|
SECTION "BootGame", ROM0[$00FE]
|
||||||
BootGame:
|
BootGame:
|
||||||
ldh [rBANK], a
|
ldh [rBANK], a
|
||||||
|
|
||||||
|
SECTION "HRAM", HRAM[_HRAM]
|
||||||
|
hCommand:
|
||||||
|
ds 1
|
||||||
|
|
BIN
Cocoa/CPU@2x.png
Before Width: | Height: | Size: 1.8 KiB After Width: | Height: | Size: 1.8 KiB |
Before Width: | Height: | Size: 283 B After Width: | Height: | Size: 199 B |
Before Width: | Height: | Size: 565 B After Width: | Height: | Size: 431 B |
Before Width: | Height: | Size: 290 B After Width: | Height: | Size: 202 B |
Before Width: | Height: | Size: 584 B After Width: | Height: | Size: 420 B |
|
@ -0,0 +1,253 @@
|
||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<document type="com.apple.InterfaceBuilder3.Cocoa.XIB" version="3.0" toolsVersion="24093.7" targetRuntime="MacOSX.Cocoa" propertyAccessControl="none" useAutolayout="YES" customObjectInstantitationMethod="direct">
|
||||||
|
<dependencies>
|
||||||
|
<deployment identifier="macosx"/>
|
||||||
|
<plugIn identifier="com.apple.InterfaceBuilder.CocoaPlugin" version="24093.7"/>
|
||||||
|
<capability name="documents saved in the Xcode 8 format" minToolsVersion="8.0"/>
|
||||||
|
</dependencies>
|
||||||
|
<objects>
|
||||||
|
<customObject id="-2" userLabel="File's Owner" customClass="GBCheatSearchController">
|
||||||
|
<connections>
|
||||||
|
<outlet property="addCheatButton" destination="o1I-5D-V4k" id="lRE-uQ-vul"/>
|
||||||
|
<outlet property="conditionField" destination="XN7-BO-THS" id="vzh-y2-CcN"/>
|
||||||
|
<outlet property="conditionTypeButton" destination="6RO-h8-lZ8" id="5wx-NY-lbK"/>
|
||||||
|
<outlet property="dataTypeButton" destination="5Db-vP-S60" id="wdR-m7-fEI"/>
|
||||||
|
<outlet property="operandField" destination="Q42-Vu-TJW" id="hRn-67-UmU"/>
|
||||||
|
<outlet property="resultsLabel" destination="wbN-MX-lEy" id="gJB-fD-eKK"/>
|
||||||
|
<outlet property="tableView" destination="fSU-85-fVM" id="1kO-kP-yBb"/>
|
||||||
|
<outlet property="window" destination="QvC-M9-y7g" id="g09-DO-GsE"/>
|
||||||
|
</connections>
|
||||||
|
</customObject>
|
||||||
|
<customObject id="-1" userLabel="First Responder" customClass="FirstResponder"/>
|
||||||
|
<customObject id="-3" userLabel="Application" customClass="NSObject"/>
|
||||||
|
<window title="Cheat Search" allowsToolTipsWhenApplicationIsInactive="NO" autorecalculatesKeyViewLoop="NO" releasedWhenClosed="NO" animationBehavior="default" id="QvC-M9-y7g" customClass="GBPanel">
|
||||||
|
<windowStyleMask key="styleMask" titled="YES" closable="YES" miniaturizable="YES" resizable="YES"/>
|
||||||
|
<rect key="contentRect" x="196" y="240" width="480" height="372"/>
|
||||||
|
<rect key="screenRect" x="0.0" y="0.0" width="2560" height="1415"/>
|
||||||
|
<value key="minSize" type="size" width="480" height="372"/>
|
||||||
|
<value key="maxSize" type="size" width="480" height="99999"/>
|
||||||
|
<view key="contentView" wantsLayer="YES" id="EiT-Mj-1SZ">
|
||||||
|
<rect key="frame" x="0.0" y="0.0" width="480" height="372"/>
|
||||||
|
<autoresizingMask key="autoresizingMask"/>
|
||||||
|
<subviews>
|
||||||
|
<scrollView fixedFrame="YES" autohidesScrollers="YES" horizontalLineScroll="24" horizontalPageScroll="10" verticalLineScroll="24" verticalPageScroll="10" usesPredominantAxisScrolling="NO" translatesAutoresizingMaskIntoConstraints="NO" id="Fvf-Co-5Ga">
|
||||||
|
<rect key="frame" x="-1" y="155" width="482" height="218"/>
|
||||||
|
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
|
||||||
|
<clipView key="contentView" drawsBackground="NO" id="1kJ-HR-keu">
|
||||||
|
<rect key="frame" x="1" y="1" width="480" height="216"/>
|
||||||
|
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
|
||||||
|
<subviews>
|
||||||
|
<tableView verticalHuggingPriority="750" allowsExpansionToolTips="YES" tableStyle="plain" alternatingRowBackgroundColors="YES" columnReordering="NO" columnResizing="NO" multipleSelection="NO" autosaveColumns="NO" rowHeight="24" headerView="oyv-sh-ulk" id="fSU-85-fVM">
|
||||||
|
<rect key="frame" x="0.0" y="0.0" width="480" height="188"/>
|
||||||
|
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
|
||||||
|
<size key="intercellSpacing" width="17" height="0.0"/>
|
||||||
|
<color key="backgroundColor" name="controlBackgroundColor" catalog="System" colorSpace="catalog"/>
|
||||||
|
<color key="gridColor" name="gridColor" catalog="System" colorSpace="catalog"/>
|
||||||
|
<tableColumns>
|
||||||
|
<tableColumn identifier="AutomaticTableColumnIdentifier.0" editable="NO" width="143" minWidth="40" maxWidth="1000" id="8z0-o5-dNI">
|
||||||
|
<tableHeaderCell key="headerCell" lineBreakMode="truncatingTail" borderStyle="border" title="Address">
|
||||||
|
<color key="textColor" name="headerTextColor" catalog="System" colorSpace="catalog"/>
|
||||||
|
<color key="backgroundColor" name="headerColor" catalog="System" colorSpace="catalog"/>
|
||||||
|
</tableHeaderCell>
|
||||||
|
<textFieldCell key="dataCell" controlSize="large" scrollable="YES" lineBreakMode="clipping" selectable="YES" editable="YES" title="Text Cell" id="bmG-fw-HDR" customClass="GBCenteredTextCell">
|
||||||
|
<font key="font" metaFont="system"/>
|
||||||
|
<color key="textColor" name="controlTextColor" catalog="System" colorSpace="catalog"/>
|
||||||
|
<color key="backgroundColor" name="controlBackgroundColor" catalog="System" colorSpace="catalog"/>
|
||||||
|
</textFieldCell>
|
||||||
|
<tableColumnResizingMask key="resizingMask" resizeWithTable="YES" userResizable="YES"/>
|
||||||
|
</tableColumn>
|
||||||
|
<tableColumn identifier="AutomaticTableColumnIdentifier.1" editable="NO" width="143" minWidth="40" maxWidth="1000" id="mBc-yv-f00">
|
||||||
|
<tableHeaderCell key="headerCell" lineBreakMode="truncatingTail" borderStyle="border" title="Previous Value">
|
||||||
|
<color key="textColor" name="headerTextColor" catalog="System" colorSpace="catalog"/>
|
||||||
|
<color key="backgroundColor" name="headerColor" catalog="System" colorSpace="catalog"/>
|
||||||
|
</tableHeaderCell>
|
||||||
|
<textFieldCell key="dataCell" controlSize="large" scrollable="YES" lineBreakMode="clipping" selectable="YES" editable="YES" title="Text Cell" id="BSe-S3-KNH" customClass="GBCenteredTextCell">
|
||||||
|
<font key="font" metaFont="system"/>
|
||||||
|
<color key="textColor" name="controlTextColor" catalog="System" colorSpace="catalog"/>
|
||||||
|
<color key="backgroundColor" name="controlBackgroundColor" catalog="System" colorSpace="catalog"/>
|
||||||
|
</textFieldCell>
|
||||||
|
<tableColumnResizingMask key="resizingMask" resizeWithTable="YES" userResizable="YES"/>
|
||||||
|
</tableColumn>
|
||||||
|
<tableColumn width="143" minWidth="10" maxWidth="3.4028234663852886e+38" id="F7j-ck-3H0">
|
||||||
|
<tableHeaderCell key="headerCell" lineBreakMode="truncatingTail" borderStyle="border" alignment="left" title="Current Value">
|
||||||
|
<color key="textColor" name="headerTextColor" catalog="System" colorSpace="catalog"/>
|
||||||
|
<color key="backgroundColor" white="0.0" alpha="0.0" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/>
|
||||||
|
</tableHeaderCell>
|
||||||
|
<textFieldCell key="dataCell" controlSize="large" scrollable="YES" lineBreakMode="clipping" selectable="YES" editable="YES" alignment="left" title="Text Cell" id="wjH-Ei-6hv" customClass="GBCenteredTextCell">
|
||||||
|
<font key="font" metaFont="system"/>
|
||||||
|
<color key="textColor" name="controlTextColor" catalog="System" colorSpace="catalog"/>
|
||||||
|
<color key="backgroundColor" name="controlBackgroundColor" catalog="System" colorSpace="catalog"/>
|
||||||
|
</textFieldCell>
|
||||||
|
<tableColumnResizingMask key="resizingMask" resizeWithTable="YES" userResizable="YES"/>
|
||||||
|
</tableColumn>
|
||||||
|
</tableColumns>
|
||||||
|
<connections>
|
||||||
|
<outlet property="dataSource" destination="-2" id="Yqt-V5-OkG"/>
|
||||||
|
<outlet property="delegate" destination="-2" id="TRM-gh-TG4"/>
|
||||||
|
</connections>
|
||||||
|
</tableView>
|
||||||
|
</subviews>
|
||||||
|
<nil key="backgroundColor"/>
|
||||||
|
</clipView>
|
||||||
|
<scroller key="horizontalScroller" hidden="YES" wantsLayer="YES" verticalHuggingPriority="750" horizontal="YES" id="ZbQ-IG-kyP">
|
||||||
|
<rect key="frame" x="1" y="201" width="480" height="16"/>
|
||||||
|
<autoresizingMask key="autoresizingMask"/>
|
||||||
|
</scroller>
|
||||||
|
<scroller key="verticalScroller" hidden="YES" wantsLayer="YES" verticalHuggingPriority="750" horizontal="NO" id="wK3-8v-kAQ">
|
||||||
|
<rect key="frame" x="224" y="17" width="15" height="102"/>
|
||||||
|
<autoresizingMask key="autoresizingMask"/>
|
||||||
|
</scroller>
|
||||||
|
<tableHeaderView key="headerView" wantsLayer="YES" id="oyv-sh-ulk">
|
||||||
|
<rect key="frame" x="0.0" y="0.0" width="480" height="28"/>
|
||||||
|
<autoresizingMask key="autoresizingMask"/>
|
||||||
|
</tableHeaderView>
|
||||||
|
</scrollView>
|
||||||
|
<button verticalHuggingPriority="750" fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="KdM-lW-WbP">
|
||||||
|
<rect key="frame" x="371" y="24" width="96" height="32"/>
|
||||||
|
<autoresizingMask key="autoresizingMask" flexibleMinX="YES" flexibleMaxY="YES"/>
|
||||||
|
<buttonCell key="cell" type="push" title="Search" bezelStyle="rounded" alignment="center" borderStyle="border" imageScaling="proportionallyDown" inset="2" id="t4Y-Ud-mJm">
|
||||||
|
<behavior key="behavior" pushIn="YES" lightByBackground="YES" lightByGray="YES"/>
|
||||||
|
<font key="font" metaFont="system"/>
|
||||||
|
</buttonCell>
|
||||||
|
<connections>
|
||||||
|
<action selector="search:" target="-2" id="7pG-JY-vEF"/>
|
||||||
|
</connections>
|
||||||
|
</button>
|
||||||
|
<textField focusRingType="none" horizontalHuggingPriority="251" verticalHuggingPriority="750" fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="fTv-nr-5FT">
|
||||||
|
<rect key="frame" x="6" y="95" width="124" height="17"/>
|
||||||
|
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMaxY="YES"/>
|
||||||
|
<textFieldCell key="cell" scrollable="YES" lineBreakMode="clipping" alignment="right" title="Search Condition:" id="9C2-Xp-JIA">
|
||||||
|
<font key="font" metaFont="system"/>
|
||||||
|
<color key="textColor" name="labelColor" catalog="System" colorSpace="catalog"/>
|
||||||
|
<color key="backgroundColor" name="textBackgroundColor" catalog="System" colorSpace="catalog"/>
|
||||||
|
</textFieldCell>
|
||||||
|
</textField>
|
||||||
|
<textField focusRingType="none" horizontalHuggingPriority="251" verticalHuggingPriority="750" fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="vMd-zb-8jT">
|
||||||
|
<rect key="frame" x="6" y="64" width="124" height="17"/>
|
||||||
|
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMaxY="YES"/>
|
||||||
|
<textFieldCell key="cell" scrollable="YES" lineBreakMode="clipping" alignment="right" title="Expression:" id="Jgg-sA-jjs">
|
||||||
|
<font key="font" metaFont="system"/>
|
||||||
|
<color key="textColor" name="labelColor" catalog="System" colorSpace="catalog"/>
|
||||||
|
<color key="backgroundColor" name="textBackgroundColor" catalog="System" colorSpace="catalog"/>
|
||||||
|
</textFieldCell>
|
||||||
|
</textField>
|
||||||
|
<popUpButton verticalHuggingPriority="750" fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="5Db-vP-S60">
|
||||||
|
<rect key="frame" x="133" y="120" width="197" height="25"/>
|
||||||
|
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMaxY="YES"/>
|
||||||
|
<popUpButtonCell key="cell" type="push" title="8-Bit" bezelStyle="rounded" alignment="left" lineBreakMode="truncatingTail" state="on" borderStyle="borderAndBezel" imageScaling="proportionallyDown" inset="2" selectedItem="al4-Jb-OJB" id="dkg-V5-wsX">
|
||||||
|
<behavior key="behavior" lightByBackground="YES" lightByGray="YES"/>
|
||||||
|
<font key="font" metaFont="message"/>
|
||||||
|
<menu key="menu" id="e5r-qR-pg7">
|
||||||
|
<items>
|
||||||
|
<menuItem title="8-Bit" state="on" id="al4-Jb-OJB"/>
|
||||||
|
<menuItem title="16-Bit" tag="1" id="G2m-fU-8Lt"/>
|
||||||
|
<menuItem title="16-Bit (Big Endian)" tag="3" id="JRa-DB-dyG"/>
|
||||||
|
</items>
|
||||||
|
</menu>
|
||||||
|
</popUpButtonCell>
|
||||||
|
</popUpButton>
|
||||||
|
<popUpButton verticalHuggingPriority="750" fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="6RO-h8-lZ8">
|
||||||
|
<rect key="frame" x="133" y="89" width="197" height="25"/>
|
||||||
|
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMaxY="YES"/>
|
||||||
|
<popUpButtonCell key="cell" type="push" title="Is Equal To…" bezelStyle="rounded" alignment="left" lineBreakMode="truncatingTail" state="on" borderStyle="borderAndBezel" imageScaling="proportionallyDown" inset="2" selectedItem="Vfb-Dg-Jkb" id="DPm-QO-c64">
|
||||||
|
<behavior key="behavior" lightByBackground="YES" lightByGray="YES"/>
|
||||||
|
<font key="font" metaFont="message"/>
|
||||||
|
<menu key="menu" id="Kg9-Rd-1GQ">
|
||||||
|
<items>
|
||||||
|
<menuItem title="Any" id="cEg-eI-4hb"/>
|
||||||
|
<menuItem title="Is Equal To…" state="on" id="Vfb-Dg-Jkb"/>
|
||||||
|
<menuItem title="Is Different From…" id="JDg-d9-5Ux"/>
|
||||||
|
<menuItem title="Is Greater Than…" id="Rir-w0-737"/>
|
||||||
|
<menuItem title="Is Equal or Greater Than…" id="Lvo-pV-Syt"/>
|
||||||
|
<menuItem title="Is Less Than…" id="VUW-DY-2cI"/>
|
||||||
|
<menuItem title="Is Equal or Less Than…" id="rDN-UF-tIo"/>
|
||||||
|
<menuItem title="Did Change" id="JdI-CW-E8H"/>
|
||||||
|
<menuItem title="Did Not Change" id="sWc-Yz-Cve"/>
|
||||||
|
<menuItem title="Did Increase" id="LHF-Lf-7tK"/>
|
||||||
|
<menuItem title="Did Decrease" id="8s2-8n-aQO"/>
|
||||||
|
<menuItem title="Custom…" id="8xc-2v-YQj"/>
|
||||||
|
</items>
|
||||||
|
</menu>
|
||||||
|
</popUpButtonCell>
|
||||||
|
<connections>
|
||||||
|
<action selector="conditionChanged:" target="-2" id="KF9-vz-yNC"/>
|
||||||
|
</connections>
|
||||||
|
</popUpButton>
|
||||||
|
<textField focusRingType="none" verticalHuggingPriority="750" fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="Q42-Vu-TJW">
|
||||||
|
<rect key="frame" x="334" y="93" width="126" height="21"/>
|
||||||
|
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMaxY="YES"/>
|
||||||
|
<textFieldCell key="cell" scrollable="YES" lineBreakMode="clipping" selectable="YES" editable="YES" continuous="YES" sendsActionOnEndEditing="YES" borderStyle="bezel" title="$0" drawsBackground="YES" usesSingleLineMode="YES" id="WDs-GG-7Lc">
|
||||||
|
<font key="font" metaFont="system"/>
|
||||||
|
<color key="textColor" name="controlTextColor" catalog="System" colorSpace="catalog"/>
|
||||||
|
<color key="backgroundColor" name="textBackgroundColor" catalog="System" colorSpace="catalog"/>
|
||||||
|
<allowedInputSourceLocales>
|
||||||
|
<string>NSAllRomanInputSourcesLocaleIdentifier</string>
|
||||||
|
</allowedInputSourceLocales>
|
||||||
|
</textFieldCell>
|
||||||
|
<connections>
|
||||||
|
<action selector="search:" target="-2" id="BDa-5j-qEz"/>
|
||||||
|
<outlet property="delegate" destination="-2" id="1bO-hp-igc"/>
|
||||||
|
</connections>
|
||||||
|
</textField>
|
||||||
|
<textField focusRingType="none" verticalHuggingPriority="750" fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="XN7-BO-THS">
|
||||||
|
<rect key="frame" x="136" y="62" width="324" height="21"/>
|
||||||
|
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMaxY="YES"/>
|
||||||
|
<textFieldCell key="cell" scrollable="YES" lineBreakMode="clipping" selectable="YES" editable="YES" enabled="NO" sendsActionOnEndEditing="YES" borderStyle="bezel" title="new == ($0)" drawsBackground="YES" usesSingleLineMode="YES" id="Krh-8w-4ug">
|
||||||
|
<font key="font" metaFont="system"/>
|
||||||
|
<color key="textColor" name="controlTextColor" catalog="System" colorSpace="catalog"/>
|
||||||
|
<color key="backgroundColor" name="textBackgroundColor" catalog="System" colorSpace="catalog"/>
|
||||||
|
<allowedInputSourceLocales>
|
||||||
|
<string>NSAllRomanInputSourcesLocaleIdentifier</string>
|
||||||
|
</allowedInputSourceLocales>
|
||||||
|
</textFieldCell>
|
||||||
|
<connections>
|
||||||
|
<action selector="search:" target="-2" id="sv5-eX-Kb9"/>
|
||||||
|
</connections>
|
||||||
|
</textField>
|
||||||
|
<button verticalHuggingPriority="750" fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="tBa-6c-9AY">
|
||||||
|
<rect key="frame" x="13" y="24" width="96" height="32"/>
|
||||||
|
<autoresizingMask key="autoresizingMask" flexibleMinX="YES" flexibleMaxY="YES"/>
|
||||||
|
<buttonCell key="cell" type="push" title="Reset" bezelStyle="rounded" alignment="center" borderStyle="border" imageScaling="proportionallyDown" inset="2" id="Pge-SU-Y1n">
|
||||||
|
<behavior key="behavior" pushIn="YES" lightByBackground="YES" lightByGray="YES"/>
|
||||||
|
<font key="font" metaFont="system"/>
|
||||||
|
</buttonCell>
|
||||||
|
<connections>
|
||||||
|
<action selector="reset:" target="-2" id="KCy-Ob-tlg"/>
|
||||||
|
</connections>
|
||||||
|
</button>
|
||||||
|
<textField focusRingType="none" horizontalHuggingPriority="251" verticalHuggingPriority="750" fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="wbN-MX-lEy">
|
||||||
|
<rect key="frame" x="-3" y="4" width="486" height="14"/>
|
||||||
|
<autoresizingMask key="autoresizingMask" widthSizable="YES" flexibleMaxY="YES"/>
|
||||||
|
<textFieldCell key="cell" controlSize="small" lineBreakMode="clipping" alignment="center" title="Status" id="CM3-4U-qao">
|
||||||
|
<font key="font" metaFont="smallSystem"/>
|
||||||
|
<color key="textColor" name="labelColor" catalog="System" colorSpace="catalog"/>
|
||||||
|
<color key="backgroundColor" name="textBackgroundColor" catalog="System" colorSpace="catalog"/>
|
||||||
|
</textFieldCell>
|
||||||
|
</textField>
|
||||||
|
<button verticalHuggingPriority="750" fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="o1I-5D-V4k">
|
||||||
|
<rect key="frame" x="264" y="24" width="110" height="32"/>
|
||||||
|
<autoresizingMask key="autoresizingMask" flexibleMinX="YES" flexibleMaxY="YES"/>
|
||||||
|
<buttonCell key="cell" type="push" title="Add Cheat" bezelStyle="rounded" alignment="center" enabled="NO" borderStyle="border" imageScaling="proportionallyDown" inset="2" id="GGV-nm-ASn">
|
||||||
|
<behavior key="behavior" pushIn="YES" lightByBackground="YES" lightByGray="YES"/>
|
||||||
|
<font key="font" metaFont="system"/>
|
||||||
|
</buttonCell>
|
||||||
|
<connections>
|
||||||
|
<action selector="addCheat:" target="-2" id="7ax-kM-TeV"/>
|
||||||
|
</connections>
|
||||||
|
</button>
|
||||||
|
<textField focusRingType="none" horizontalHuggingPriority="251" verticalHuggingPriority="750" fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="veO-Qn-0Sz">
|
||||||
|
<rect key="frame" x="6" y="126" width="124" height="17"/>
|
||||||
|
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMaxY="YES"/>
|
||||||
|
<textFieldCell key="cell" scrollable="YES" lineBreakMode="clipping" sendsActionOnEndEditing="YES" alignment="right" title="Data Type:" id="KuT-rz-eHm">
|
||||||
|
<font key="font" metaFont="system"/>
|
||||||
|
<color key="textColor" name="labelColor" catalog="System" colorSpace="catalog"/>
|
||||||
|
<color key="backgroundColor" name="textBackgroundColor" catalog="System" colorSpace="catalog"/>
|
||||||
|
</textFieldCell>
|
||||||
|
</textField>
|
||||||
|
</subviews>
|
||||||
|
</view>
|
||||||
|
<contentBorderThickness minY="22"/>
|
||||||
|
<point key="canvasLocation" x="161" y="182"/>
|
||||||
|
</window>
|
||||||
|
</objects>
|
||||||
|
</document>
|
Before Width: | Height: | Size: 231 B After Width: | Height: | Size: 132 B |
Before Width: | Height: | Size: 435 B After Width: | Height: | Size: 461 B |
Before Width: | Height: | Size: 234 B After Width: | Height: | Size: 120 B |
Before Width: | Height: | Size: 433 B After Width: | Height: | Size: 448 B |
|
@ -3,9 +3,22 @@
|
||||||
#import "GBImageView.h"
|
#import "GBImageView.h"
|
||||||
#import "GBSplitView.h"
|
#import "GBSplitView.h"
|
||||||
#import "GBVisualizerView.h"
|
#import "GBVisualizerView.h"
|
||||||
|
#import "GBCPUView.h"
|
||||||
#import "GBOSDView.h"
|
#import "GBOSDView.h"
|
||||||
#import "GBDebuggerButton.h"
|
#import "GBDebuggerButton.h"
|
||||||
|
|
||||||
|
enum model {
|
||||||
|
MODEL_NONE,
|
||||||
|
MODEL_DMG,
|
||||||
|
MODEL_CGB,
|
||||||
|
MODEL_AGB,
|
||||||
|
MODEL_SGB,
|
||||||
|
MODEL_MGB,
|
||||||
|
MODEL_AUTO,
|
||||||
|
|
||||||
|
MODEL_QUICK_RESET = -1,
|
||||||
|
};
|
||||||
|
|
||||||
@class GBCheatWindowController;
|
@class GBCheatWindowController;
|
||||||
@class GBPaletteView;
|
@class GBPaletteView;
|
||||||
@class GBObjectView;
|
@class GBObjectView;
|
||||||
|
@ -67,14 +80,19 @@
|
||||||
@property IBOutlet GBDebuggerButton *debuggerNextButton;
|
@property IBOutlet GBDebuggerButton *debuggerNextButton;
|
||||||
@property IBOutlet GBDebuggerButton *debuggerStepButton;
|
@property IBOutlet GBDebuggerButton *debuggerStepButton;
|
||||||
@property IBOutlet GBDebuggerButton *debuggerFinishButton;
|
@property IBOutlet GBDebuggerButton *debuggerFinishButton;
|
||||||
@property (strong) IBOutlet GBDebuggerButton *debuggerBackstepButton;
|
@property IBOutlet GBDebuggerButton *debuggerBackstepButton;
|
||||||
|
|
||||||
|
@property IBOutlet NSScrollView *debuggerScrollView;
|
||||||
|
@property IBOutlet NSView *debugBar;
|
||||||
|
|
||||||
|
@property IBOutlet GBCPUView *cpuView;
|
||||||
|
@property IBOutlet NSTextField *cpuCounter;
|
||||||
|
|
||||||
+ (NSImage *) imageFromData:(NSData *)data width:(NSUInteger) width height:(NSUInteger) height scale:(double) scale;
|
+ (NSImage *) imageFromData:(NSData *)data width:(NSUInteger) width height:(NSUInteger) height scale:(double) scale;
|
||||||
-(uint8_t) readMemory:(uint16_t) addr;
|
- (void) performAtomicBlock: (void (^)())block;
|
||||||
-(void) writeMemory:(uint16_t) addr value:(uint8_t)value;
|
- (void) connectLinkCable:(NSMenuItem *)sender;
|
||||||
-(void) performAtomicBlock: (void (^)())block;
|
- (int)loadStateFile:(const char *)path noErrorOnNotFound:(bool)noErrorOnFileNotFound;
|
||||||
-(void) connectLinkCable:(NSMenuItem *)sender;
|
- (NSString *)captureOutputForBlock: (void (^)())block;
|
||||||
-(int)loadStateFile:(const char *)path noErrorOnNotFound:(bool)noErrorOnFileNotFound;
|
- (NSFont *)debuggerFontOfSize:(unsigned)size;
|
||||||
@end
|
@end
|
||||||
|
|
||||||
|
|
536
Cocoa/Document.m
|
@ -11,6 +11,7 @@
|
||||||
#import "GBTerminalTextFieldCell.h"
|
#import "GBTerminalTextFieldCell.h"
|
||||||
#import "BigSurToolbar.h"
|
#import "BigSurToolbar.h"
|
||||||
#import "GBPaletteEditorController.h"
|
#import "GBPaletteEditorController.h"
|
||||||
|
#import "GBCheatSearchController.h"
|
||||||
#import "GBObjectView.h"
|
#import "GBObjectView.h"
|
||||||
#import "GBPaletteView.h"
|
#import "GBPaletteView.h"
|
||||||
#import "GBHexStatusBarRepresenter.h"
|
#import "GBHexStatusBarRepresenter.h"
|
||||||
|
@ -48,16 +49,6 @@
|
||||||
/* Todo: The general Objective-C coding style conflicts with SameBoy's. This file needs a cleanup. */
|
/* Todo: The general Objective-C coding style conflicts with SameBoy's. This file needs a cleanup. */
|
||||||
/* Todo: Split into category files! This is so messy!!! */
|
/* Todo: Split into category files! This is so messy!!! */
|
||||||
|
|
||||||
enum model {
|
|
||||||
MODEL_NONE,
|
|
||||||
MODEL_DMG,
|
|
||||||
MODEL_CGB,
|
|
||||||
MODEL_AGB,
|
|
||||||
MODEL_SGB,
|
|
||||||
MODEL_MGB,
|
|
||||||
|
|
||||||
MODEL_QUICK_RESET = -1,
|
|
||||||
};
|
|
||||||
|
|
||||||
@interface Document ()
|
@interface Document ()
|
||||||
@property GBAudioClient *audioClient;
|
@property GBAudioClient *audioClient;
|
||||||
|
@ -100,6 +91,7 @@ enum model {
|
||||||
bool _logToSideView;
|
bool _logToSideView;
|
||||||
bool _shouldClearSideView;
|
bool _shouldClearSideView;
|
||||||
enum model _currentModel;
|
enum model _currentModel;
|
||||||
|
bool _usesAutoModel;
|
||||||
|
|
||||||
bool _rewind;
|
bool _rewind;
|
||||||
bool _modelsChanging;
|
bool _modelsChanging;
|
||||||
|
@ -126,6 +118,8 @@ enum model {
|
||||||
|
|
||||||
NSDate *_fileModificationTime;
|
NSDate *_fileModificationTime;
|
||||||
__weak NSThread *_emulationThread;
|
__weak NSThread *_emulationThread;
|
||||||
|
|
||||||
|
GBCheatSearchController *_cheatSearchController;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void boot_rom_load(GB_gameboy_t *gb, GB_boot_rom_t type)
|
static void boot_rom_load(GB_gameboy_t *gb, GB_boot_rom_t type)
|
||||||
|
@ -140,7 +134,7 @@ static void vblank(GB_gameboy_t *gb, GB_vblank_type_t type)
|
||||||
[self vblankWithType:type];
|
[self vblankWithType:type];
|
||||||
}
|
}
|
||||||
|
|
||||||
static void consoleLog(GB_gameboy_t *gb, const char *string, GB_log_attributes attributes)
|
static void consoleLog(GB_gameboy_t *gb, const char *string, GB_log_attributes_t attributes)
|
||||||
{
|
{
|
||||||
Document *self = (__bridge Document *)GB_get_user_data(gb);
|
Document *self = (__bridge Document *)GB_get_user_data(gb);
|
||||||
[self log:string withAttributes: attributes];
|
[self log:string withAttributes: attributes];
|
||||||
|
@ -263,6 +257,7 @@ static void debuggerReloadCallback(GB_gameboy_t *gb)
|
||||||
|
|
||||||
case MODEL_NONE:
|
case MODEL_NONE:
|
||||||
case MODEL_QUICK_RESET:
|
case MODEL_QUICK_RESET:
|
||||||
|
case MODEL_AUTO:
|
||||||
case MODEL_CGB:
|
case MODEL_CGB:
|
||||||
return (GB_model_t)[[NSUserDefaults standardUserDefaults] integerForKey:@"GBCGBModel"];
|
return (GB_model_t)[[NSUserDefaults standardUserDefaults] integerForKey:@"GBCGBModel"];
|
||||||
|
|
||||||
|
@ -293,6 +288,7 @@ static void debuggerReloadCallback(GB_gameboy_t *gb)
|
||||||
GB_set_user_data(&_gb, (__bridge void *)(self));
|
GB_set_user_data(&_gb, (__bridge void *)(self));
|
||||||
GB_set_boot_rom_load_callback(&_gb, (GB_boot_rom_load_callback_t)boot_rom_load);
|
GB_set_boot_rom_load_callback(&_gb, (GB_boot_rom_load_callback_t)boot_rom_load);
|
||||||
GB_set_vblank_callback(&_gb, (GB_vblank_callback_t) vblank);
|
GB_set_vblank_callback(&_gb, (GB_vblank_callback_t) vblank);
|
||||||
|
GB_set_enable_skipped_frame_vblank_callbacks(&_gb, true);
|
||||||
GB_set_log_callback(&_gb, (GB_log_callback_t) consoleLog);
|
GB_set_log_callback(&_gb, (GB_log_callback_t) consoleLog);
|
||||||
GB_set_input_callback(&_gb, (GB_input_callback_t) consoleInput);
|
GB_set_input_callback(&_gb, (GB_input_callback_t) consoleInput);
|
||||||
GB_set_async_input_callback(&_gb, (GB_input_callback_t) asyncConsoleInput);
|
GB_set_async_input_callback(&_gb, (GB_input_callback_t) asyncConsoleInput);
|
||||||
|
@ -303,7 +299,7 @@ static void debuggerReloadCallback(GB_gameboy_t *gb)
|
||||||
GB_apu_set_sample_callback(&_gb, audioCallback);
|
GB_apu_set_sample_callback(&_gb, audioCallback);
|
||||||
GB_set_rumble_callback(&_gb, rumbleCallback);
|
GB_set_rumble_callback(&_gb, rumbleCallback);
|
||||||
GB_set_infrared_callback(&_gb, infraredStateChanged);
|
GB_set_infrared_callback(&_gb, infraredStateChanged);
|
||||||
GB_set_debugger_reload_callback(&_gb, debuggerReloadCallback);
|
GB_debugger_set_reload_callback(&_gb, debuggerReloadCallback);
|
||||||
|
|
||||||
GB_gameboy_t *gb = &_gb;
|
GB_gameboy_t *gb = &_gb;
|
||||||
__unsafe_unretained Document *weakSelf = self;
|
__unsafe_unretained Document *weakSelf = self;
|
||||||
|
@ -322,7 +318,7 @@ static void debuggerReloadCallback(GB_gameboy_t *gb)
|
||||||
|
|
||||||
GB_set_border_mode(&_gb, (GB_border_mode_t) [[NSUserDefaults standardUserDefaults] integerForKey:@"GBBorderMode"]);
|
GB_set_border_mode(&_gb, (GB_border_mode_t) [[NSUserDefaults standardUserDefaults] integerForKey:@"GBBorderMode"]);
|
||||||
[self observeStandardDefaultsKey:@"GBBorderMode" withBlock:^(NSNumber *value) {
|
[self observeStandardDefaultsKey:@"GBBorderMode" withBlock:^(NSNumber *value) {
|
||||||
_borderModeChanged = true;
|
weakSelf->_borderModeChanged = true;
|
||||||
}];
|
}];
|
||||||
|
|
||||||
[self observeStandardDefaultsKey:@"GBHighpassFilter" withBlock:^(NSNumber *value) {
|
[self observeStandardDefaultsKey:@"GBHighpassFilter" withBlock:^(NSNumber *value) {
|
||||||
|
@ -342,6 +338,20 @@ static void debuggerReloadCallback(GB_gameboy_t *gb)
|
||||||
[self observeStandardDefaultsKey:@"GBRumbleMode" withBlock:^(NSNumber *value) {
|
[self observeStandardDefaultsKey:@"GBRumbleMode" withBlock:^(NSNumber *value) {
|
||||||
GB_set_rumble_mode(gb, value.unsignedIntValue);
|
GB_set_rumble_mode(gb, value.unsignedIntValue);
|
||||||
}];
|
}];
|
||||||
|
|
||||||
|
[self observeStandardDefaultsKey:@"GBDebuggerFont" withBlock:^(NSString *value) {
|
||||||
|
[weakSelf updateFonts];
|
||||||
|
}];
|
||||||
|
|
||||||
|
[self observeStandardDefaultsKey:@"GBDebuggerFontSize" withBlock:^(NSString *value) {
|
||||||
|
[weakSelf updateFonts];
|
||||||
|
}];
|
||||||
|
|
||||||
|
[self observeStandardDefaultsKey:@"GBTurboCap" withBlock:^(NSNumber *value) {
|
||||||
|
if (!_master) {
|
||||||
|
GB_set_turbo_cap(gb, value.doubleValue);
|
||||||
|
}
|
||||||
|
}];
|
||||||
}
|
}
|
||||||
|
|
||||||
- (void)updateMinSize
|
- (void)updateMinSize
|
||||||
|
@ -356,11 +366,29 @@ static void debuggerReloadCallback(GB_gameboy_t *gb)
|
||||||
|
|
||||||
- (void)vblankWithType:(GB_vblank_type_t)type
|
- (void)vblankWithType:(GB_vblank_type_t)type
|
||||||
{
|
{
|
||||||
|
if (type == GB_VBLANK_TYPE_SKIPPED_FRAME) {
|
||||||
|
double frameUsage = GB_debugger_get_frame_cpu_usage(&_gb);
|
||||||
|
[_cpuView addSample:frameUsage];
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
if (_gbsVisualizer) {
|
if (_gbsVisualizer) {
|
||||||
dispatch_async(dispatch_get_main_queue(), ^{
|
dispatch_async(dispatch_get_main_queue(), ^{
|
||||||
[_gbsVisualizer setNeedsDisplay:true];
|
[_gbsVisualizer setNeedsDisplay:true];
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
double frameUsage = GB_debugger_get_frame_cpu_usage(&_gb);
|
||||||
|
[_cpuView addSample:frameUsage];
|
||||||
|
|
||||||
|
if (self.consoleWindow.visible) {
|
||||||
|
double secondUsage = GB_debugger_get_second_cpu_usage(&_gb);
|
||||||
|
dispatch_async(dispatch_get_main_queue(), ^{
|
||||||
|
[_cpuView setNeedsDisplay:true];
|
||||||
|
_cpuCounter.stringValue = [NSString stringWithFormat:@"%.2f%%", secondUsage * 100];
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
if (type != GB_VBLANK_TYPE_REPEAT) {
|
if (type != GB_VBLANK_TYPE_REPEAT) {
|
||||||
[self.view flip];
|
[self.view flip];
|
||||||
if (_borderModeChanged) {
|
if (_borderModeChanged) {
|
||||||
|
@ -677,15 +705,46 @@ static unsigned *multiplication_table_for_frequency(unsigned frequency)
|
||||||
GB_load_boot_rom(&_gb, [path UTF8String]);
|
GB_load_boot_rom(&_gb, [path UTF8String]);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
- (enum model)bestModelForROM
|
||||||
|
{
|
||||||
|
uint8_t *rom = GB_get_direct_access(&_gb, GB_DIRECT_ACCESS_ROM, NULL, NULL);
|
||||||
|
if (!rom) return MODEL_CGB;
|
||||||
|
|
||||||
|
if (rom[0x143] & 0x80) { // Has CGB features
|
||||||
|
return MODEL_CGB;
|
||||||
|
}
|
||||||
|
if (rom[0x146] == 3) { // Has SGB features
|
||||||
|
return MODEL_SGB;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (rom[0x14B] == 1) { // Nintendo-licensed (most likely has boot ROM palettes)
|
||||||
|
return MODEL_CGB;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (rom[0x14B] == 0x33 &&
|
||||||
|
rom[0x144] == '0' &&
|
||||||
|
rom[0x145] == '1') { // Ditto
|
||||||
|
return MODEL_CGB;
|
||||||
|
}
|
||||||
|
|
||||||
|
return MODEL_DMG;
|
||||||
|
}
|
||||||
|
|
||||||
- (IBAction)reset:(id)sender
|
- (IBAction)reset:(id)sender
|
||||||
{
|
{
|
||||||
[self stop];
|
[self stop];
|
||||||
size_t old_width = GB_get_screen_width(&_gb);
|
size_t old_width = GB_get_screen_width(&_gb);
|
||||||
|
|
||||||
if ([sender tag] != MODEL_NONE) {
|
if ([sender tag] > MODEL_NONE) {
|
||||||
|
/* User explictly selected a model, save the preference */
|
||||||
_currentModel = (enum model)[sender tag];
|
_currentModel = (enum model)[sender tag];
|
||||||
|
_usesAutoModel = _currentModel == MODEL_AUTO;
|
||||||
|
[[NSUserDefaults standardUserDefaults] setInteger:_currentModel forKey:@"GBEmulatedModel"];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Reload the ROM, SAV and SYM files */
|
||||||
|
[self loadROM];
|
||||||
|
|
||||||
if ([sender tag] == MODEL_QUICK_RESET) {
|
if ([sender tag] == MODEL_QUICK_RESET) {
|
||||||
GB_quick_reset(&_gb);
|
GB_quick_reset(&_gb);
|
||||||
}
|
}
|
||||||
|
@ -696,21 +755,12 @@ static unsigned *multiplication_table_for_frequency(unsigned frequency)
|
||||||
if (old_width != GB_get_screen_width(&_gb)) {
|
if (old_width != GB_get_screen_width(&_gb)) {
|
||||||
[self.view screenSizeChanged];
|
[self.view screenSizeChanged];
|
||||||
}
|
}
|
||||||
|
|
||||||
[self updateMinSize];
|
[self updateMinSize];
|
||||||
|
|
||||||
if ([sender tag] > MODEL_NONE) {
|
|
||||||
/* User explictly selected a model, save the preference */
|
|
||||||
[[NSUserDefaults standardUserDefaults] setBool:_currentModel == MODEL_DMG forKey:@"EmulateDMG"];
|
|
||||||
[[NSUserDefaults standardUserDefaults] setBool:_currentModel == MODEL_SGB forKey:@"EmulateSGB"];
|
|
||||||
[[NSUserDefaults standardUserDefaults] setBool:_currentModel == MODEL_AGB forKey:@"EmulateAGB"];
|
|
||||||
[[NSUserDefaults standardUserDefaults] setBool:_currentModel == MODEL_MGB forKey:@"EmulateMGB"];
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Reload the ROM, SAV and SYM files */
|
|
||||||
[self loadROM];
|
|
||||||
|
|
||||||
[self start];
|
[self start];
|
||||||
|
if (_gbsTracks) {
|
||||||
|
[self changeGBSTrack:sender];
|
||||||
|
}
|
||||||
|
|
||||||
if (_hexController) {
|
if (_hexController) {
|
||||||
/* Verify bank sanity, especially when switching models. */
|
/* Verify bank sanity, especially when switching models. */
|
||||||
|
@ -750,11 +800,92 @@ static unsigned *multiplication_table_for_frequency(unsigned frequency)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
- (NSFont *)debuggerFontOfSize:(unsigned)size
|
||||||
|
{
|
||||||
|
if (!size) {
|
||||||
|
size = [[NSUserDefaults standardUserDefaults] integerForKey:@"GBDebuggerFontSize"];
|
||||||
|
}
|
||||||
|
|
||||||
|
bool retry = false;
|
||||||
|
|
||||||
|
again:;
|
||||||
|
NSString *selectedFont = [[NSUserDefaults standardUserDefaults] stringForKey:@"GBDebuggerFont"];
|
||||||
|
if (@available(macOS 10.15, *)) {
|
||||||
|
if ([selectedFont isEqual:@"SF Mono"]) {
|
||||||
|
return [NSFont monospacedSystemFontOfSize:size weight:NSFontWeightRegular];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
NSFont *ret = [NSFont fontWithName:selectedFont size:size];
|
||||||
|
if (ret) return ret;
|
||||||
|
|
||||||
|
if (retry) {
|
||||||
|
return [NSFont userFixedPitchFontOfSize:size];
|
||||||
|
}
|
||||||
|
[[NSUserDefaults standardUserDefaults] removeObjectForKey:@"GBDebuggerFont"];
|
||||||
|
retry = true;
|
||||||
|
goto again;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
- (void)updateFonts
|
||||||
|
{
|
||||||
|
_hexController.font = [self debuggerFontOfSize:12];
|
||||||
|
[self.paletteView reloadData:self];
|
||||||
|
[self.objectView reloadData:self];
|
||||||
|
|
||||||
|
NSFont *newFont = [self debuggerFontOfSize:0];
|
||||||
|
NSFont *newBoldFont = [[NSFontManager sharedFontManager] convertFont:newFont toHaveTrait:NSBoldFontMask];
|
||||||
|
self.debuggerSideViewInput.font = newFont;
|
||||||
|
|
||||||
|
unsigned inputHeight = MAX(ceil([@" " sizeWithAttributes:@{
|
||||||
|
NSFontAttributeName: newFont
|
||||||
|
}].height) + 6, 26);
|
||||||
|
|
||||||
|
|
||||||
|
NSRect frame = _consoleInput.frame;
|
||||||
|
unsigned oldHeight = frame.size.height;
|
||||||
|
frame.size.height = inputHeight;
|
||||||
|
_consoleInput.frame = frame;
|
||||||
|
|
||||||
|
frame = _debugBar.frame;
|
||||||
|
frame.origin.y += (signed)(inputHeight - oldHeight);
|
||||||
|
_debugBar.frame = frame;
|
||||||
|
|
||||||
|
frame = _debuggerScrollView.frame;
|
||||||
|
frame.origin.y += (signed)(inputHeight - oldHeight);
|
||||||
|
frame.size.height -= (signed)(inputHeight - oldHeight);
|
||||||
|
_debuggerScrollView.frame = frame;
|
||||||
|
|
||||||
|
_consoleInput.font = newFont;
|
||||||
|
|
||||||
|
for (NSTextView *view in @[_debuggerSideView, _consoleOutput]) {
|
||||||
|
NSMutableAttributedString *newString = view.attributedString.mutableCopy;
|
||||||
|
[view.attributedString enumerateAttribute:NSFontAttributeName
|
||||||
|
inRange:NSMakeRange(0, view.attributedString.length)
|
||||||
|
options:0
|
||||||
|
usingBlock:^(NSFont *value, NSRange range, BOOL *stop) {
|
||||||
|
if ([[NSFontManager sharedFontManager] fontNamed:value.fontName hasTraits:NSBoldFontMask]) {
|
||||||
|
[newString addAttributes:@{
|
||||||
|
NSFontAttributeName: newBoldFont
|
||||||
|
} range:range];
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
[newString addAttributes:@{
|
||||||
|
NSFontAttributeName: newFont
|
||||||
|
} range:range];
|
||||||
|
}
|
||||||
|
}];
|
||||||
|
[view.textStorage setAttributedString:newString];
|
||||||
|
}
|
||||||
|
[_consoleOutput scrollToEndOfDocument:nil];
|
||||||
|
}
|
||||||
|
|
||||||
- (void)windowControllerDidLoadNib:(NSWindowController *)aController
|
- (void)windowControllerDidLoadNib:(NSWindowController *)aController
|
||||||
{
|
{
|
||||||
[super windowControllerDidLoadNib:aController];
|
[super windowControllerDidLoadNib:aController];
|
||||||
// Interface Builder bug?
|
// Interface Builder bug?
|
||||||
[self.consoleWindow setContentSize:self.consoleWindow.minSize];
|
[self.consoleWindow setContentSize:self.consoleWindow.frame.size];
|
||||||
/* Close Open Panels, if any */
|
/* Close Open Panels, if any */
|
||||||
for (NSWindow *window in [[NSApplication sharedApplication] windows]) {
|
for (NSWindow *window in [[NSApplication sharedApplication] windows]) {
|
||||||
if ([window isKindOfClass:[NSOpenPanel class]]) {
|
if ([window isKindOfClass:[NSOpenPanel class]]) {
|
||||||
|
@ -765,7 +896,7 @@ static unsigned *multiplication_table_for_frequency(unsigned frequency)
|
||||||
NSMutableParagraphStyle *paragraph_style = [[NSMutableParagraphStyle alloc] init];
|
NSMutableParagraphStyle *paragraph_style = [[NSMutableParagraphStyle alloc] init];
|
||||||
[paragraph_style setLineSpacing:2];
|
[paragraph_style setLineSpacing:2];
|
||||||
|
|
||||||
self.debuggerSideViewInput.font = [NSFont userFixedPitchFontOfSize:12];
|
self.debuggerSideViewInput.font = [self debuggerFontOfSize:0];
|
||||||
self.debuggerSideViewInput.textColor = [NSColor whiteColor];
|
self.debuggerSideViewInput.textColor = [NSColor whiteColor];
|
||||||
self.debuggerSideViewInput.defaultParagraphStyle = paragraph_style;
|
self.debuggerSideViewInput.defaultParagraphStyle = paragraph_style;
|
||||||
[self.debuggerSideViewInput setString:@"registers\nbacktrace\n"];
|
[self.debuggerSideViewInput setString:@"registers\nbacktrace\n"];
|
||||||
|
@ -792,9 +923,16 @@ static unsigned *multiplication_table_for_frequency(unsigned frequency)
|
||||||
[self.vramWindow setFrame:vram_window_rect display:true animate:false];
|
[self.vramWindow setFrame:vram_window_rect display:true animate:false];
|
||||||
|
|
||||||
|
|
||||||
self.consoleWindow.title = [NSString stringWithFormat:@"Debug Console – %@", [self.fileURL.path lastPathComponent]];
|
if (@available(macOS 11.0, *)) {
|
||||||
self.memoryWindow.title = [NSString stringWithFormat:@"Memory – %@", [self.fileURL.path lastPathComponent]];
|
self.consoleWindow.subtitle = [self.fileURL.path lastPathComponent];
|
||||||
self.vramWindow.title = [NSString stringWithFormat:@"VRAM Viewer – %@", [self.fileURL.path lastPathComponent]];
|
self.memoryWindow.subtitle = [self.fileURL.path lastPathComponent];
|
||||||
|
self.vramWindow.subtitle = [self.fileURL.path lastPathComponent];
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
self.consoleWindow.title = [NSString stringWithFormat:@"Debug Console – %@", [self.fileURL.path lastPathComponent]];
|
||||||
|
self.memoryWindow.title = [NSString stringWithFormat:@"Memory – %@", [self.fileURL.path lastPathComponent]];
|
||||||
|
self.vramWindow.title = [NSString stringWithFormat:@"VRAM Viewer – %@", [self.fileURL.path lastPathComponent]];
|
||||||
|
}
|
||||||
|
|
||||||
self.consoleWindow.level = NSNormalWindowLevel;
|
self.consoleWindow.level = NSNormalWindowLevel;
|
||||||
|
|
||||||
|
@ -871,19 +1009,10 @@ static unsigned *multiplication_table_for_frequency(unsigned frequency)
|
||||||
[self observeStandardDefaultsKey:@"GBVolume" withBlock:^(id newValue) {
|
[self observeStandardDefaultsKey:@"GBVolume" withBlock:^(id newValue) {
|
||||||
weakSelf->_volume = [[NSUserDefaults standardUserDefaults] doubleForKey:@"GBVolume"];
|
weakSelf->_volume = [[NSUserDefaults standardUserDefaults] doubleForKey:@"GBVolume"];
|
||||||
}];
|
}];
|
||||||
|
|
||||||
if ([[NSUserDefaults standardUserDefaults] boolForKey:@"EmulateDMG"]) {
|
|
||||||
_currentModel = MODEL_DMG;
|
_currentModel = [[NSUserDefaults standardUserDefaults] integerForKey:@"GBEmulatedModel"];
|
||||||
}
|
_usesAutoModel = _currentModel == MODEL_AUTO;
|
||||||
else if ([[NSUserDefaults standardUserDefaults] boolForKey:@"EmulateSGB"]) {
|
|
||||||
_currentModel = MODEL_SGB;
|
|
||||||
}
|
|
||||||
else if ([[NSUserDefaults standardUserDefaults] boolForKey:@"EmulateMGB"]) {
|
|
||||||
_currentModel = MODEL_MGB;
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
_currentModel = [[NSUserDefaults standardUserDefaults] boolForKey:@"EmulateAGB"]? MODEL_AGB : MODEL_CGB;
|
|
||||||
}
|
|
||||||
|
|
||||||
[self initCommon];
|
[self initCommon];
|
||||||
self.view.gb = &_gb;
|
self.view.gb = &_gb;
|
||||||
|
@ -900,9 +1029,10 @@ static unsigned *multiplication_table_for_frequency(unsigned frequency)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
- (void) initMemoryView
|
- (void)initMemoryView
|
||||||
{
|
{
|
||||||
_hexController = [[HFController alloc] init];
|
_hexController = [[HFController alloc] init];
|
||||||
|
_hexController.font = [self debuggerFontOfSize:12];
|
||||||
[_hexController setBytesPerColumn:1];
|
[_hexController setBytesPerColumn:1];
|
||||||
[_hexController setEditMode:HFOverwriteMode];
|
[_hexController setEditMode:HFOverwriteMode];
|
||||||
|
|
||||||
|
@ -946,6 +1076,16 @@ static unsigned *multiplication_table_for_frequency(unsigned frequency)
|
||||||
[self.memoryView addSubview:layoutView];
|
[self.memoryView addSubview:layoutView];
|
||||||
self.memoryView = layoutView;
|
self.memoryView = layoutView;
|
||||||
|
|
||||||
|
CGSize contentSize = _memoryWindow.contentView.frame.size;
|
||||||
|
while (_hexController.bytesPerLine < 16) {
|
||||||
|
contentSize.width += 4;
|
||||||
|
[_memoryWindow setContentSize:contentSize];
|
||||||
|
}
|
||||||
|
while (_hexController.bytesPerLine > 16) {
|
||||||
|
contentSize.width -= 4;
|
||||||
|
[_memoryWindow setContentSize:contentSize];
|
||||||
|
}
|
||||||
|
|
||||||
self.memoryBankItem.enabled = false;
|
self.memoryBankItem.enabled = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1045,6 +1185,17 @@ static unsigned *multiplication_table_for_frequency(unsigned frequency)
|
||||||
if (@available(macOS 10.10, *)) {
|
if (@available(macOS 10.10, *)) {
|
||||||
_mainWindow.titlebarAppearsTransparent = true;
|
_mainWindow.titlebarAppearsTransparent = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (@available(macOS 26.0, *)) {
|
||||||
|
// There's a new minimum width for segmented controls in Solarium
|
||||||
|
NSRect frame = _gbsNextPrevButton.frame;
|
||||||
|
frame.origin.x -= 16;
|
||||||
|
_gbsNextPrevButton.frame = frame;
|
||||||
|
|
||||||
|
frame = _gbsTracks.frame;
|
||||||
|
frame.size.width -= 16;
|
||||||
|
_gbsTracks.frame = frame;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
- (bool)isCartContainer
|
- (bool)isCartContainer
|
||||||
|
@ -1125,7 +1276,7 @@ static bool is_path_writeable(const char *path)
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
- (int) loadROM
|
- (int)loadROM
|
||||||
{
|
{
|
||||||
__block int ret = 0;
|
__block int ret = 0;
|
||||||
NSString *fileName = self.romPath;
|
NSString *fileName = self.romPath;
|
||||||
|
@ -1159,7 +1310,7 @@ static bool is_path_writeable(const char *path)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
GB_load_battery(&_gb, self.savPath.UTF8String);
|
GB_load_battery(&_gb, self.savPath.UTF8String);
|
||||||
GB_load_cheats(&_gb, self.chtPath.UTF8String);
|
GB_load_cheats(&_gb, self.chtPath.UTF8String, true);
|
||||||
dispatch_async(dispatch_get_main_queue(), ^{
|
dispatch_async(dispatch_get_main_queue(), ^{
|
||||||
[self.cheatWindowController cheatsUpdated];
|
[self.cheatWindowController cheatsUpdated];
|
||||||
});
|
});
|
||||||
|
@ -1177,6 +1328,9 @@ static bool is_path_writeable(const char *path)
|
||||||
[GBWarningPopover popoverWithContents:rom_warnings onWindow:self.mainWindow];
|
[GBWarningPopover popoverWithContents:rom_warnings onWindow:self.mainWindow];
|
||||||
}
|
}
|
||||||
_fileModificationTime = [[NSFileManager defaultManager] attributesOfItemAtPath:fileName error:nil][NSFileModificationDate];
|
_fileModificationTime = [[NSFileManager defaultManager] attributesOfItemAtPath:fileName error:nil][NSFileModificationDate];
|
||||||
|
if (_usesAutoModel) {
|
||||||
|
_currentModel = [self bestModelForROM];
|
||||||
|
}
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1206,6 +1360,7 @@ static bool is_path_writeable(const char *path)
|
||||||
[self.vramWindow close];
|
[self.vramWindow close];
|
||||||
[self.printerFeedWindow close];
|
[self.printerFeedWindow close];
|
||||||
[self.cheatsWindow close];
|
[self.cheatsWindow close];
|
||||||
|
[_cheatSearchController.window close];
|
||||||
[super close];
|
[super close];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1215,6 +1370,8 @@ static bool is_path_writeable(const char *path)
|
||||||
GB_debugger_break(&_gb);
|
GB_debugger_break(&_gb);
|
||||||
[self start];
|
[self start];
|
||||||
[self.consoleWindow makeKeyAndOrderFront:nil];
|
[self.consoleWindow makeKeyAndOrderFront:nil];
|
||||||
|
double secondUsage = GB_debugger_get_second_cpu_usage(&_gb);
|
||||||
|
_cpuCounter.stringValue = [NSString stringWithFormat:@"%.2f%%", secondUsage * 100];
|
||||||
[self.consoleInput becomeFirstResponder];
|
[self.consoleInput becomeFirstResponder];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1243,14 +1400,19 @@ static bool is_path_writeable(const char *path)
|
||||||
- (BOOL)validateUserInterfaceItem:(id<NSValidatedUserInterfaceItem>)anItem
|
- (BOOL)validateUserInterfaceItem:(id<NSValidatedUserInterfaceItem>)anItem
|
||||||
{
|
{
|
||||||
if ([anItem action] == @selector(mute:)) {
|
if ([anItem action] == @selector(mute:)) {
|
||||||
[(NSMenuItem *)anItem setState:!_audioClient.isPlaying];
|
if (_running) {
|
||||||
|
[(NSMenuItem *)anItem setState:!_audioClient.isPlaying];
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
[(NSMenuItem *)anItem setState:[[NSUserDefaults standardUserDefaults] boolForKey:@"Mute"]];
|
||||||
|
}
|
||||||
}
|
}
|
||||||
else if ([anItem action] == @selector(togglePause:)) {
|
else if ([anItem action] == @selector(togglePause:)) {
|
||||||
[(NSMenuItem *)anItem setState:self.isPaused];
|
[(NSMenuItem *)anItem setState:self.isPaused];
|
||||||
return !GB_debugger_is_stopped(&_gb);
|
return !GB_debugger_is_stopped(&_gb);
|
||||||
}
|
}
|
||||||
else if ([anItem action] == @selector(reset:) && anItem.tag != MODEL_NONE && anItem.tag != MODEL_QUICK_RESET) {
|
else if ([anItem action] == @selector(reset:) && anItem.tag != MODEL_NONE && anItem.tag != MODEL_QUICK_RESET) {
|
||||||
[(NSMenuItem *)anItem setState:anItem.tag == _currentModel];
|
[(NSMenuItem *)anItem setState:(anItem.tag == _currentModel) || (anItem.tag == MODEL_AUTO && _usesAutoModel)];
|
||||||
}
|
}
|
||||||
else if ([anItem action] == @selector(interrupt:)) {
|
else if ([anItem action] == @selector(interrupt:)) {
|
||||||
if (![[NSUserDefaults standardUserDefaults] boolForKey:@"DeveloperMode"]) {
|
if (![[NSUserDefaults standardUserDefaults] boolForKey:@"DeveloperMode"]) {
|
||||||
|
@ -1291,6 +1453,9 @@ static bool is_path_writeable(const char *path)
|
||||||
else if ([anItem action] == @selector(decreaseWindowSize:)) {
|
else if ([anItem action] == @selector(decreaseWindowSize:)) {
|
||||||
return [self newRect:NULL forWindow:_mainWindow action:GBWindowResizeActionDecrease];
|
return [self newRect:NULL forWindow:_mainWindow action:GBWindowResizeActionDecrease];
|
||||||
}
|
}
|
||||||
|
else if ([anItem action] == @selector(reloadROM:)) {
|
||||||
|
return !_gbsTracks;
|
||||||
|
}
|
||||||
|
|
||||||
return [super validateUserInterfaceItem:anItem];
|
return [super validateUserInterfaceItem:anItem];
|
||||||
}
|
}
|
||||||
|
@ -1432,7 +1597,9 @@ enum GBWindowResizeAction
|
||||||
[self reloadVRAMData: nil];
|
[self reloadVRAMData: nil];
|
||||||
|
|
||||||
[textView.textStorage appendAttributedString:_pendingConsoleOutput];
|
[textView.textStorage appendAttributedString:_pendingConsoleOutput];
|
||||||
[textView scrollToEndOfDocument:nil];
|
if (!_logToSideView) {
|
||||||
|
[textView scrollToEndOfDocument:nil];
|
||||||
|
}
|
||||||
if ([[NSUserDefaults standardUserDefaults] boolForKey:@"DeveloperMode"]) {
|
if ([[NSUserDefaults standardUserDefaults] boolForKey:@"DeveloperMode"]) {
|
||||||
[self.consoleWindow orderFront:nil];
|
[self.consoleWindow orderFront:nil];
|
||||||
}
|
}
|
||||||
|
@ -1441,7 +1608,7 @@ enum GBWindowResizeAction
|
||||||
[_consoleOutputLock unlock];
|
[_consoleOutputLock unlock];
|
||||||
}
|
}
|
||||||
|
|
||||||
- (void) log: (const char *) string withAttributes: (GB_log_attributes) attributes
|
- (void)log:(const char *)string withAttributes:(GB_log_attributes_t)attributes
|
||||||
{
|
{
|
||||||
NSString *nsstring = @(string); // For ref-counting
|
NSString *nsstring = @(string); // For ref-counting
|
||||||
if (_capturedOutput) {
|
if (_capturedOutput) {
|
||||||
|
@ -1450,7 +1617,7 @@ enum GBWindowResizeAction
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
NSFont *font = [NSFont userFixedPitchFontOfSize:12];
|
NSFont *font = [self debuggerFontOfSize:0];
|
||||||
NSUnderlineStyle underline = NSUnderlineStyleNone;
|
NSUnderlineStyle underline = NSUnderlineStyleNone;
|
||||||
if (attributes & GB_LOG_BOLD) {
|
if (attributes & GB_LOG_BOLD) {
|
||||||
font = [[NSFontManager sharedFontManager] convertFont:font toHaveTrait:NSBoldFontMask];
|
font = [[NSFontManager sharedFontManager] convertFont:font toHaveTrait:NSBoldFontMask];
|
||||||
|
@ -1490,7 +1657,9 @@ enum GBWindowResizeAction
|
||||||
|
|
||||||
- (IBAction)showConsoleWindow:(id)sender
|
- (IBAction)showConsoleWindow:(id)sender
|
||||||
{
|
{
|
||||||
[self.consoleWindow orderBack:nil];
|
[self.consoleWindow orderFront:nil];
|
||||||
|
double secondUsage = GB_debugger_get_second_cpu_usage(&_gb);
|
||||||
|
_cpuCounter.stringValue = [NSString stringWithFormat:@"%.2f%%", secondUsage * 100];
|
||||||
}
|
}
|
||||||
|
|
||||||
- (void)queueDebuggerCommand:(NSString *)command
|
- (void)queueDebuggerCommand:(NSString *)command
|
||||||
|
@ -1691,18 +1860,6 @@ enum GBWindowResizeAction
|
||||||
[self log:log withAttributes:0];
|
[self log:log withAttributes:0];
|
||||||
}
|
}
|
||||||
|
|
||||||
- (uint8_t) readMemory:(uint16_t)addr
|
|
||||||
{
|
|
||||||
while (!GB_is_inited(&_gb));
|
|
||||||
return GB_safe_read_memory(&_gb, addr);
|
|
||||||
}
|
|
||||||
|
|
||||||
- (void) writeMemory:(uint16_t)addr value:(uint8_t)value
|
|
||||||
{
|
|
||||||
while (!GB_is_inited(&_gb));
|
|
||||||
GB_write_memory(&_gb, addr, value);
|
|
||||||
}
|
|
||||||
|
|
||||||
- (void)performAtomicBlock: (void (^)())block
|
- (void)performAtomicBlock: (void (^)())block
|
||||||
{
|
{
|
||||||
while (!GB_is_inited(&_gb));
|
while (!GB_is_inited(&_gb));
|
||||||
|
@ -1763,6 +1920,11 @@ enum GBWindowResizeAction
|
||||||
if (self.memoryWindow.isVisible) {
|
if (self.memoryWindow.isVisible) {
|
||||||
[_hexController reloadData];
|
[_hexController reloadData];
|
||||||
}
|
}
|
||||||
|
if (_cheatSearchController.window.isVisible) {
|
||||||
|
if ([_cheatSearchController.tableView editedColumn] != 2) {
|
||||||
|
[_cheatSearchController.tableView reloadData];
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
- (IBAction) reloadVRAMData: (id) sender
|
- (IBAction) reloadVRAMData: (id) sender
|
||||||
|
@ -1847,124 +2009,130 @@ enum GBWindowResizeAction
|
||||||
|
|
||||||
- (IBAction)hexGoTo:(id)sender
|
- (IBAction)hexGoTo:(id)sender
|
||||||
{
|
{
|
||||||
|
NSString *expression = [sender stringValue];
|
||||||
|
__block uint16_t addr = 0;
|
||||||
|
__block uint16_t bank = 0;
|
||||||
|
__block bool fail = false;
|
||||||
NSString *error = [self captureOutputForBlock:^{
|
NSString *error = [self captureOutputForBlock:^{
|
||||||
uint16_t addr;
|
if (GB_debugger_evaluate(&_gb, [expression UTF8String], &addr, &bank)) {
|
||||||
uint16_t bank;
|
fail = true;
|
||||||
if (GB_debugger_evaluate(&_gb, [[sender stringValue] UTF8String], &addr, &bank)) {
|
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (bank != (typeof(bank))-1) {
|
|
||||||
GB_memory_mode_t mode = [(GBMemoryByteArray *)(_hexController.byteArray) mode];
|
|
||||||
if (addr < 0x4000) {
|
|
||||||
if (bank == 0) {
|
|
||||||
if (mode != GBMemoryROM && mode != GBMemoryEntireSpace) {
|
|
||||||
mode = GBMemoryEntireSpace;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
addr |= 0x4000;
|
|
||||||
mode = GBMemoryROM;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else if (addr < 0x8000) {
|
|
||||||
mode = GBMemoryROM;
|
|
||||||
}
|
|
||||||
else if (addr < 0xA000) {
|
|
||||||
mode = GBMemoryVRAM;
|
|
||||||
}
|
|
||||||
else if (addr < 0xC000) {
|
|
||||||
mode = GBMemoryExternalRAM;
|
|
||||||
}
|
|
||||||
else if (addr < 0xD000) {
|
|
||||||
if (mode != GBMemoryRAM && mode != GBMemoryEntireSpace) {
|
|
||||||
mode = GBMemoryEntireSpace;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else if (addr < 0xE000) {
|
|
||||||
mode = GBMemoryRAM;
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
mode = GBMemoryEntireSpace;
|
|
||||||
}
|
|
||||||
[_memorySpaceButton selectItemAtIndex:mode];
|
|
||||||
[self hexUpdateSpace:_memorySpaceButton.cell];
|
|
||||||
[_memoryBankInput setStringValue:[NSString stringWithFormat:@"$%02x", bank]];
|
|
||||||
[self hexUpdateBank:_memoryBankInput];
|
|
||||||
}
|
|
||||||
addr -= _lineRep.valueOffset;
|
|
||||||
if (addr >= _hexController.byteArray.length) {
|
|
||||||
GB_log(&_gb, "Value $%04x is out of range.\n", addr);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
dispatch_async(dispatch_get_main_queue(), ^{
|
|
||||||
[_hexController setSelectedContentsRanges:@[[HFRangeWrapper withRange:HFRangeMake(addr, 0)]]];
|
|
||||||
[_hexController _ensureVisibilityOfLocation:addr];
|
|
||||||
for (HFRepresenter *representer in _hexController.representers) {
|
|
||||||
if ([representer isKindOfClass:[HFHexTextRepresenter class]]) {
|
|
||||||
[self.memoryWindow makeFirstResponder:representer.view];
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}];
|
}];
|
||||||
|
|
||||||
if (error) {
|
if (error) {
|
||||||
NSBeep();
|
NSBeep();
|
||||||
[GBWarningPopover popoverWithContents:error onView:sender];
|
[GBWarningPopover popoverWithContents:error onView:sender];
|
||||||
}
|
}
|
||||||
|
if (fail) return;
|
||||||
|
|
||||||
|
|
||||||
|
if (bank != (typeof(bank))-1) {
|
||||||
|
GB_memory_mode_t mode = [(GBMemoryByteArray *)(_hexController.byteArray) mode];
|
||||||
|
if (addr < 0x4000) {
|
||||||
|
if (bank == 0) {
|
||||||
|
if (mode != GBMemoryROM && mode != GBMemoryEntireSpace) {
|
||||||
|
mode = GBMemoryEntireSpace;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
addr |= 0x4000;
|
||||||
|
mode = GBMemoryROM;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (addr < 0x8000) {
|
||||||
|
mode = GBMemoryROM;
|
||||||
|
}
|
||||||
|
else if (addr < 0xA000) {
|
||||||
|
mode = GBMemoryVRAM;
|
||||||
|
}
|
||||||
|
else if (addr < 0xC000) {
|
||||||
|
mode = GBMemoryExternalRAM;
|
||||||
|
}
|
||||||
|
else if (addr < 0xD000) {
|
||||||
|
if (mode != GBMemoryRAM && mode != GBMemoryEntireSpace) {
|
||||||
|
mode = GBMemoryEntireSpace;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (addr < 0xE000) {
|
||||||
|
mode = GBMemoryRAM;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
mode = GBMemoryEntireSpace;
|
||||||
|
}
|
||||||
|
[_memorySpaceButton selectItemAtIndex:mode];
|
||||||
|
[self hexUpdateSpace:_memorySpaceButton.cell];
|
||||||
|
[_memoryBankInput setStringValue:[NSString stringWithFormat:@"$%02x", bank]];
|
||||||
|
[self hexUpdateBank:_memoryBankInput];
|
||||||
|
}
|
||||||
|
addr -= _lineRep.valueOffset;
|
||||||
|
if (addr >= _hexController.byteArray.length) {
|
||||||
|
GB_log(&_gb, "Value $%04x is out of range.\n", addr);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
[_hexController setSelectedContentsRanges:@[[HFRangeWrapper withRange:HFRangeMake(addr, 0)]]];
|
||||||
|
[_hexController _ensureVisibilityOfLocation:addr];
|
||||||
|
for (HFRepresenter *representer in _hexController.representers) {
|
||||||
|
if ([representer isKindOfClass:[HFHexTextRepresenter class]]) {
|
||||||
|
[self.memoryWindow makeFirstResponder:representer.view];
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
- (void)hexUpdateBank:(NSControl *)sender ignoreErrors: (bool)ignore_errors
|
- (void)hexUpdateBank:(NSControl *)sender ignoreErrors: (bool)ignore_errors
|
||||||
{
|
{
|
||||||
|
NSString *expression = [sender stringValue];
|
||||||
|
__block uint16_t addr, bank;
|
||||||
|
__block bool fail = false;
|
||||||
NSString *error = [self captureOutputForBlock:^{
|
NSString *error = [self captureOutputForBlock:^{
|
||||||
uint16_t addr, bank;
|
if (GB_debugger_evaluate(&_gb, [expression UTF8String], &addr, &bank)) {
|
||||||
if (GB_debugger_evaluate(&_gb, [[sender stringValue] UTF8String], &addr, &bank)) {
|
fail = true;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (bank == (uint16_t) -1) {
|
|
||||||
bank = addr;
|
|
||||||
}
|
|
||||||
|
|
||||||
uint16_t n_banks = 1;
|
|
||||||
switch ([(GBMemoryByteArray *)(_hexController.byteArray) mode]) {
|
|
||||||
case GBMemoryROM: {
|
|
||||||
size_t rom_size;
|
|
||||||
GB_get_direct_access(&_gb, GB_DIRECT_ACCESS_ROM, &rom_size, NULL);
|
|
||||||
n_banks = rom_size / 0x4000;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
case GBMemoryVRAM:
|
|
||||||
n_banks = GB_is_cgb(&_gb) ? 2 : 1;
|
|
||||||
break;
|
|
||||||
case GBMemoryExternalRAM: {
|
|
||||||
size_t ram_size;
|
|
||||||
GB_get_direct_access(&_gb, GB_DIRECT_ACCESS_CART_RAM, &ram_size, NULL);
|
|
||||||
n_banks = (ram_size + 0x1FFF) / 0x2000;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
case GBMemoryRAM:
|
|
||||||
n_banks = GB_is_cgb(&_gb) ? 8 : 1;
|
|
||||||
break;
|
|
||||||
case GBMemoryEntireSpace:
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
bank %= n_banks;
|
|
||||||
|
|
||||||
[sender setStringValue:[NSString stringWithFormat:@"$%x", bank]];
|
|
||||||
[(GBMemoryByteArray *)(_hexController.byteArray) setSelectedBank:bank];
|
|
||||||
_statusRep.bankForDescription = bank;
|
|
||||||
dispatch_async(dispatch_get_main_queue(), ^{
|
|
||||||
[_hexController reloadData];
|
|
||||||
});
|
|
||||||
}];
|
}];
|
||||||
|
|
||||||
if (error && !ignore_errors) {
|
if (error && !ignore_errors) {
|
||||||
NSBeep();
|
NSBeep();
|
||||||
[GBWarningPopover popoverWithContents:error onView:sender];
|
[GBWarningPopover popoverWithContents:error onView:sender];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (fail) return;
|
||||||
|
|
||||||
|
if (bank == (uint16_t) -1) {
|
||||||
|
bank = addr;
|
||||||
|
}
|
||||||
|
|
||||||
|
uint16_t n_banks = 1;
|
||||||
|
switch ([(GBMemoryByteArray *)(_hexController.byteArray) mode]) {
|
||||||
|
case GBMemoryROM: {
|
||||||
|
size_t rom_size;
|
||||||
|
GB_get_direct_access(&_gb, GB_DIRECT_ACCESS_ROM, &rom_size, NULL);
|
||||||
|
n_banks = rom_size / 0x4000;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case GBMemoryVRAM:
|
||||||
|
n_banks = GB_is_cgb(&_gb) ? 2 : 1;
|
||||||
|
break;
|
||||||
|
case GBMemoryExternalRAM: {
|
||||||
|
size_t ram_size;
|
||||||
|
GB_get_direct_access(&_gb, GB_DIRECT_ACCESS_CART_RAM, &ram_size, NULL);
|
||||||
|
n_banks = (ram_size + 0x1FFF) / 0x2000;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case GBMemoryRAM:
|
||||||
|
n_banks = GB_is_cgb(&_gb) ? 8 : 1;
|
||||||
|
break;
|
||||||
|
case GBMemoryEntireSpace:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
bank %= n_banks;
|
||||||
|
|
||||||
|
[(GBMemoryByteArray *)(_hexController.byteArray) setSelectedBank:bank];
|
||||||
|
_statusRep.bankForDescription = bank;
|
||||||
|
[sender setStringValue:[NSString stringWithFormat:@"$%x", bank]];
|
||||||
|
[_hexController reloadData];
|
||||||
}
|
}
|
||||||
|
|
||||||
- (IBAction)hexUpdateBank:(NSControl *)sender
|
- (IBAction)hexUpdateBank:(NSControl *)sender
|
||||||
|
@ -2002,9 +2170,8 @@ enum GBWindowResizeAction
|
||||||
}
|
}
|
||||||
byteArray.selectedBank = bank;
|
byteArray.selectedBank = bank;
|
||||||
_statusRep.bankForDescription = bank;
|
_statusRep.bankForDescription = bank;
|
||||||
if (bank != (uint16_t)-1) {
|
[self.memoryBankInput setStringValue:(bank == (uint16_t)-1)? @"" :
|
||||||
[self.memoryBankInput setStringValue:[NSString stringWithFormat:@"$%x", byteArray.selectedBank]];
|
[NSString stringWithFormat:@"$%x", byteArray.selectedBank]];
|
||||||
}
|
|
||||||
|
|
||||||
[_hexController reloadData];
|
[_hexController reloadData];
|
||||||
for (NSView *view in self.memoryView.subviews) {
|
for (NSView *view in self.memoryView.subviews) {
|
||||||
|
@ -2047,7 +2214,7 @@ enum GBWindowResizeAction
|
||||||
NSError *error;
|
NSError *error;
|
||||||
AVCaptureDevice *device = [AVCaptureDevice defaultDeviceWithMediaType: AVMediaTypeVideo];
|
AVCaptureDevice *device = [AVCaptureDevice defaultDeviceWithMediaType: AVMediaTypeVideo];
|
||||||
AVCaptureDeviceInput *input = [AVCaptureDeviceInput deviceInputWithDevice: device error: &error];
|
AVCaptureDeviceInput *input = [AVCaptureDeviceInput deviceInputWithDevice: device error: &error];
|
||||||
CMVideoDimensions dimensions = CMVideoFormatDescriptionGetDimensions([[[device formats] lastObject] formatDescription]);
|
CMVideoDimensions dimensions = CMVideoFormatDescriptionGetDimensions([[device activeFormat] formatDescription]);
|
||||||
|
|
||||||
if (!input) {
|
if (!input) {
|
||||||
GB_camera_updated(&_gb);
|
GB_camera_updated(&_gb);
|
||||||
|
@ -2344,9 +2511,16 @@ enum GBWindowResizeAction
|
||||||
- (void)setFileURL:(NSURL *)fileURL
|
- (void)setFileURL:(NSURL *)fileURL
|
||||||
{
|
{
|
||||||
[super setFileURL:fileURL];
|
[super setFileURL:fileURL];
|
||||||
self.consoleWindow.title = [NSString stringWithFormat:@"Debug Console – %@", [[fileURL path] lastPathComponent]];
|
if (@available(macOS 11.0, *)) {
|
||||||
self.memoryWindow.title = [NSString stringWithFormat:@"Memory – %@", [[fileURL path] lastPathComponent]];
|
self.consoleWindow.subtitle = [self.fileURL.path lastPathComponent];
|
||||||
self.vramWindow.title = [NSString stringWithFormat:@"VRAM Viewer – %@", [[fileURL path] lastPathComponent]];
|
self.memoryWindow.subtitle = [self.fileURL.path lastPathComponent];
|
||||||
|
self.vramWindow.subtitle = [self.fileURL.path lastPathComponent];
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
self.consoleWindow.title = [NSString stringWithFormat:@"Debug Console – %@", [self.fileURL.path lastPathComponent]];
|
||||||
|
self.memoryWindow.title = [NSString stringWithFormat:@"Memory – %@", [self.fileURL.path lastPathComponent]];
|
||||||
|
self.vramWindow.title = [NSString stringWithFormat:@"VRAM Viewer – %@", [self.fileURL.path lastPathComponent]];
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
- (BOOL)splitView:(GBSplitView *)splitView canCollapseSubview:(NSView *)subview;
|
- (BOOL)splitView:(GBSplitView *)splitView canCollapseSubview:(NSView *)subview;
|
||||||
|
@ -2388,6 +2562,14 @@ enum GBWindowResizeAction
|
||||||
[self.cheatsWindow makeKeyAndOrderFront:nil];
|
[self.cheatsWindow makeKeyAndOrderFront:nil];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
- (IBAction)showCheatSearch:(id)sender
|
||||||
|
{
|
||||||
|
if (!_cheatSearchController) {
|
||||||
|
_cheatSearchController = [GBCheatSearchController controllerWithDocument:self];
|
||||||
|
}
|
||||||
|
[_cheatSearchController.window makeKeyAndOrderFront:sender];
|
||||||
|
}
|
||||||
|
|
||||||
- (IBAction)toggleCheats:(id)sender
|
- (IBAction)toggleCheats:(id)sender
|
||||||
{
|
{
|
||||||
GB_set_cheats_enabled(&_gb, !GB_cheats_enabled(&_gb));
|
GB_set_cheats_enabled(&_gb, !GB_cheats_enabled(&_gb));
|
||||||
|
@ -2410,6 +2592,8 @@ enum GBWindowResizeAction
|
||||||
}
|
}
|
||||||
GB_set_turbo_mode(&_gb, false, false);
|
GB_set_turbo_mode(&_gb, false, false);
|
||||||
GB_set_turbo_mode(&partner->_gb, false, false);
|
GB_set_turbo_mode(&partner->_gb, false, false);
|
||||||
|
GB_set_turbo_cap(&_gb, [[NSUserDefaults standardUserDefaults] doubleForKey:@"GBTurboCap"]);
|
||||||
|
GB_set_turbo_cap(&partner->_gb, [[NSUserDefaults standardUserDefaults] doubleForKey:@"GBTurboCap"]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2425,6 +2609,7 @@ enum GBWindowResizeAction
|
||||||
GB_set_turbo_mode(&partner->_gb, true, true);
|
GB_set_turbo_mode(&partner->_gb, true, true);
|
||||||
_slave = partner;
|
_slave = partner;
|
||||||
partner->_master = self;
|
partner->_master = self;
|
||||||
|
GB_set_turbo_cap(&partner->_gb, 0);
|
||||||
_linkOffset = 0;
|
_linkOffset = 0;
|
||||||
GB_set_serial_transfer_bit_start_callback(&_gb, _linkCableBitStart);
|
GB_set_serial_transfer_bit_start_callback(&_gb, _linkCableBitStart);
|
||||||
GB_set_serial_transfer_bit_start_callback(&partner->_gb, _linkCableBitStart);
|
GB_set_serial_transfer_bit_start_callback(&partner->_gb, _linkCableBitStart);
|
||||||
|
@ -2773,4 +2958,15 @@ enum GBWindowResizeAction
|
||||||
[self queueDebuggerCommand:sender.alternateTitle];
|
[self queueDebuggerCommand:sender.alternateTitle];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
+ (NSArray<NSString *> *)readableTypes
|
||||||
|
{
|
||||||
|
NSMutableSet *set = [NSMutableSet setWithArray:[super readableTypes]];
|
||||||
|
for (NSString *type in @[@"gb", @"gbc", @"isx", @"gbs"]) {
|
||||||
|
[set addObject:(__bridge_transfer NSString *)UTTypeCreatePreferredIdentifierForTag(kUTTagClassFilenameExtension,
|
||||||
|
(__bridge CFStringRef)type,
|
||||||
|
NULL)];
|
||||||
|
}
|
||||||
|
return [set allObjects];
|
||||||
|
}
|
||||||
|
|
||||||
@end
|
@end
|
||||||
|
|
|
@ -1,8 +1,8 @@
|
||||||
<?xml version="1.0" encoding="UTF-8"?>
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
<document type="com.apple.InterfaceBuilder3.Cocoa.XIB" version="3.0" toolsVersion="21507" targetRuntime="MacOSX.Cocoa" propertyAccessControl="none" useAutolayout="YES" customObjectInstantitationMethod="direct">
|
<document type="com.apple.InterfaceBuilder3.Cocoa.XIB" version="3.0" toolsVersion="24093.7" targetRuntime="MacOSX.Cocoa" propertyAccessControl="none" useAutolayout="YES" customObjectInstantitationMethod="direct">
|
||||||
<dependencies>
|
<dependencies>
|
||||||
<deployment identifier="macosx"/>
|
<deployment identifier="macosx"/>
|
||||||
<plugIn identifier="com.apple.InterfaceBuilder.CocoaPlugin" version="21507"/>
|
<plugIn identifier="com.apple.InterfaceBuilder.CocoaPlugin" version="24093.7"/>
|
||||||
<capability name="System colors introduced in macOS 10.14" minToolsVersion="10.0"/>
|
<capability name="System colors introduced in macOS 10.14" minToolsVersion="10.0"/>
|
||||||
<capability name="documents saved in the Xcode 8 format" minToolsVersion="8.0"/>
|
<capability name="documents saved in the Xcode 8 format" minToolsVersion="8.0"/>
|
||||||
</dependencies>
|
</dependencies>
|
||||||
|
@ -15,15 +15,19 @@
|
||||||
<outlet property="consoleInput" destination="l22-S8-uji" id="Heu-am-YgB"/>
|
<outlet property="consoleInput" destination="l22-S8-uji" id="Heu-am-YgB"/>
|
||||||
<outlet property="consoleOutput" destination="doS-dM-hnl" id="Gn5-ju-Wb0"/>
|
<outlet property="consoleOutput" destination="doS-dM-hnl" id="Gn5-ju-Wb0"/>
|
||||||
<outlet property="consoleWindow" destination="21F-Ah-yHX" id="eQ4-ug-LsT"/>
|
<outlet property="consoleWindow" destination="21F-Ah-yHX" id="eQ4-ug-LsT"/>
|
||||||
<outlet property="debuggerBackstepButton" destination="onn-R8-3vg" id="gi1-dC-tJj"/>
|
<outlet property="cpuCounter" destination="xdx-GC-Tb8" id="oSn-U3-qvg"/>
|
||||||
<outlet property="debuggerContinueButton" destination="G4h-KO-Z3g" id="Dad-5e-XYM"/>
|
<outlet property="cpuView" destination="aBf-yU-8M0" id="RIb-Fj-lvt"/>
|
||||||
<outlet property="debuggerFinishButton" destination="vtb-n5-Qlz" id="9vv-fJ-gxp"/>
|
<outlet property="debugBar" destination="sah-kv-6KJ" id="24d-aM-rs5"/>
|
||||||
<outlet property="debuggerNextButton" destination="cOi-Rs-9gS" id="Xjx-uM-D0u"/>
|
<outlet property="debuggerBackstepButton" destination="E87-Uq-f2l" id="PI7-Wu-f0v"/>
|
||||||
|
<outlet property="debuggerContinueButton" destination="ybQ-jy-NgI" id="fRF-S3-xSh"/>
|
||||||
|
<outlet property="debuggerFinishButton" destination="jdD-yP-Nr6" id="V7Y-wP-nSS"/>
|
||||||
|
<outlet property="debuggerNextButton" destination="tTP-Zs-Ohu" id="mfm-Yl-UZA"/>
|
||||||
|
<outlet property="debuggerScrollView" destination="oTo-zx-o6N" id="EbZ-Le-dZJ"/>
|
||||||
<outlet property="debuggerSideView" destination="JgV-7E-iwp" id="RaA-fw-3i1"/>
|
<outlet property="debuggerSideView" destination="JgV-7E-iwp" id="RaA-fw-3i1"/>
|
||||||
<outlet property="debuggerSideViewInput" destination="w0g-eK-jM4" id="GBf-WK-ryI"/>
|
<outlet property="debuggerSideViewInput" destination="w0g-eK-jM4" id="GBf-WK-ryI"/>
|
||||||
<outlet property="debuggerSidebarEffectView" destination="4Z2-33-dYY" id="Ja6-bC-rQg"/>
|
<outlet property="debuggerSidebarEffectView" destination="4Z2-33-dYY" id="Ja6-bC-rQg"/>
|
||||||
<outlet property="debuggerSplitView" destination="pUc-ZN-vl5" id="0sG-0D-cID"/>
|
<outlet property="debuggerSplitView" destination="pUc-ZN-vl5" id="0sG-0D-cID"/>
|
||||||
<outlet property="debuggerStepButton" destination="DsN-Ce-QoH" id="Ts4-uK-pvI"/>
|
<outlet property="debuggerStepButton" destination="fsQ-dD-A8C" id="1Vi-Pi-rsI"/>
|
||||||
<outlet property="debuggerVerticalLine" destination="7bR-gM-1At" id="rfy-7Z-388"/>
|
<outlet property="debuggerVerticalLine" destination="7bR-gM-1At" id="rfy-7Z-388"/>
|
||||||
<outlet property="feedImageView" destination="Ar0-nN-eop" id="wHa-St-o4G"/>
|
<outlet property="feedImageView" destination="Ar0-nN-eop" id="wHa-St-o4G"/>
|
||||||
<outlet property="gridButton" destination="fL6-2S-Rgd" id="jtV-jh-GHC"/>
|
<outlet property="gridButton" destination="fL6-2S-Rgd" id="jtV-jh-GHC"/>
|
||||||
|
@ -52,7 +56,7 @@
|
||||||
</customObject>
|
</customObject>
|
||||||
<customObject id="-1" userLabel="First Responder" customClass="FirstResponder"/>
|
<customObject id="-1" userLabel="First Responder" customClass="FirstResponder"/>
|
||||||
<customObject id="-3" userLabel="Application" customClass="NSObject"/>
|
<customObject id="-3" userLabel="Application" customClass="NSObject"/>
|
||||||
<window title="Window" allowsToolTipsWhenApplicationIsInactive="NO" autorecalculatesKeyViewLoop="NO" releasedWhenClosed="NO" visibleAtLaunch="NO" animationBehavior="default" tabbingMode="disallowed" id="xOd-HO-29H" userLabel="Window">
|
<window title="Window" allowsToolTipsWhenApplicationIsInactive="NO" autorecalculatesKeyViewLoop="NO" releasedWhenClosed="NO" visibleAtLaunch="NO" animationBehavior="default" tabbingMode="disallowed" id="xOd-HO-29H" userLabel="Window" customClass="GBWindow">
|
||||||
<windowStyleMask key="styleMask" titled="YES" closable="YES" miniaturizable="YES" resizable="YES"/>
|
<windowStyleMask key="styleMask" titled="YES" closable="YES" miniaturizable="YES" resizable="YES"/>
|
||||||
<windowCollectionBehavior key="collectionBehavior" fullScreenPrimary="YES"/>
|
<windowCollectionBehavior key="collectionBehavior" fullScreenPrimary="YES"/>
|
||||||
<rect key="contentRect" x="0.0" y="0.0" width="160" height="144"/>
|
<rect key="contentRect" x="0.0" y="0.0" width="160" height="144"/>
|
||||||
|
@ -86,41 +90,41 @@
|
||||||
</connections>
|
</connections>
|
||||||
<point key="canvasLocation" x="293" y="347"/>
|
<point key="canvasLocation" x="293" y="347"/>
|
||||||
</window>
|
</window>
|
||||||
<window title="Debug Console" allowsToolTipsWhenApplicationIsInactive="NO" autorecalculatesKeyViewLoop="NO" restorable="NO" releasedWhenClosed="NO" visibleAtLaunch="NO" animationBehavior="default" id="21F-Ah-yHX" customClass="NSPanel">
|
<window title="Debug Console" allowsToolTipsWhenApplicationIsInactive="NO" autorecalculatesKeyViewLoop="NO" restorable="NO" releasedWhenClosed="NO" visibleAtLaunch="NO" animationBehavior="default" id="21F-Ah-yHX" customClass="GBPanel">
|
||||||
<windowStyleMask key="styleMask" titled="YES" closable="YES" resizable="YES" utility="YES" HUD="YES"/>
|
<windowStyleMask key="styleMask" titled="YES" closable="YES" resizable="YES" utility="YES" HUD="YES"/>
|
||||||
<windowCollectionBehavior key="collectionBehavior" fullScreenAuxiliary="YES"/>
|
<windowCollectionBehavior key="collectionBehavior" fullScreenAuxiliary="YES"/>
|
||||||
<rect key="contentRect" x="0.0" y="0.0" width="921" height="400"/>
|
<rect key="contentRect" x="0.0" y="0.0" width="921" height="480"/>
|
||||||
<rect key="screenRect" x="0.0" y="0.0" width="2560" height="1415"/>
|
<rect key="screenRect" x="0.0" y="0.0" width="2560" height="1415"/>
|
||||||
<value key="minSize" type="size" width="921" height="400"/>
|
<value key="minSize" type="size" width="921" height="400"/>
|
||||||
<view key="contentView" id="dCP-E5-7Fi" customClass="GBOptionalVisualEffectView">
|
<view key="contentView" id="dCP-E5-7Fi" customClass="GBOptionalVisualEffectView">
|
||||||
<rect key="frame" x="0.0" y="0.0" width="921" height="400"/>
|
<rect key="frame" x="0.0" y="0.0" width="921" height="480"/>
|
||||||
<autoresizingMask key="autoresizingMask"/>
|
<autoresizingMask key="autoresizingMask"/>
|
||||||
<subviews>
|
<subviews>
|
||||||
<box horizontalHuggingPriority="750" boxType="separator" id="7bR-gM-1At">
|
<box horizontalHuggingPriority="750" boxType="separator" id="7bR-gM-1At">
|
||||||
<rect key="frame" x="590" y="0.0" width="5" height="401"/>
|
<rect key="frame" x="590" y="0.0" width="5" height="481"/>
|
||||||
<autoresizingMask key="autoresizingMask" flexibleMinX="YES" flexibleMaxX="YES" heightSizable="YES"/>
|
<autoresizingMask key="autoresizingMask" flexibleMinX="YES" flexibleMaxX="YES" heightSizable="YES"/>
|
||||||
</box>
|
</box>
|
||||||
<splitView dividerStyle="thin" vertical="YES" id="pUc-ZN-vl5" customClass="GBSplitView">
|
<splitView dividerStyle="thin" vertical="YES" id="pUc-ZN-vl5" customClass="GBSplitView">
|
||||||
<rect key="frame" x="0.0" y="0.0" width="921" height="401"/>
|
<rect key="frame" x="0.0" y="0.0" width="921" height="481"/>
|
||||||
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
|
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
|
||||||
<subviews>
|
<subviews>
|
||||||
<customView fixedFrame="YES" id="2rj-7i-kxc">
|
<customView fixedFrame="YES" id="2rj-7i-kxc">
|
||||||
<rect key="frame" x="0.0" y="0.0" width="591" height="401"/>
|
<rect key="frame" x="0.0" y="0.0" width="591" height="481"/>
|
||||||
<autoresizingMask key="autoresizingMask"/>
|
<autoresizingMask key="autoresizingMask"/>
|
||||||
<subviews>
|
<subviews>
|
||||||
<scrollView fixedFrame="YES" borderType="none" horizontalLineScroll="10" horizontalPageScroll="10" verticalLineScroll="10" verticalPageScroll="10" hasHorizontalScroller="NO" usesPredominantAxisScrolling="NO" translatesAutoresizingMaskIntoConstraints="NO" id="oTo-zx-o6N">
|
<scrollView fixedFrame="YES" borderType="none" horizontalLineScroll="10" horizontalPageScroll="10" verticalLineScroll="10" verticalPageScroll="10" hasHorizontalScroller="NO" usesPredominantAxisScrolling="NO" translatesAutoresizingMaskIntoConstraints="NO" id="oTo-zx-o6N">
|
||||||
<rect key="frame" x="0.0" y="52" width="591" height="349"/>
|
<rect key="frame" x="0.0" y="52" width="591" height="429"/>
|
||||||
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
|
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
|
||||||
<clipView key="contentView" drawsBackground="NO" copiesOnScroll="NO" id="EQe-Ad-L7S">
|
<clipView key="contentView" drawsBackground="NO" copiesOnScroll="NO" id="EQe-Ad-L7S">
|
||||||
<rect key="frame" x="0.0" y="0.0" width="591" height="349"/>
|
<rect key="frame" x="0.0" y="0.0" width="591" height="429"/>
|
||||||
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
|
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
|
||||||
<subviews>
|
<subviews>
|
||||||
<textView editable="NO" importsGraphics="NO" richText="NO" verticallyResizable="YES" baseWritingDirection="leftToRight" findStyle="bar" allowsNonContiguousLayout="YES" id="doS-dM-hnl">
|
<textView editable="NO" importsGraphics="NO" richText="NO" verticallyResizable="YES" baseWritingDirection="leftToRight" findStyle="bar" allowsNonContiguousLayout="YES" id="doS-dM-hnl">
|
||||||
<rect key="frame" x="0.0" y="0.0" width="591" height="349"/>
|
<rect key="frame" x="0.0" y="0.0" width="591" height="429"/>
|
||||||
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
|
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
|
||||||
<color key="textColor" white="1" alpha="1" colorSpace="calibratedWhite"/>
|
<color key="textColor" white="1" alpha="1" colorSpace="calibratedWhite"/>
|
||||||
<color key="backgroundColor" red="0.0" green="0.0" blue="0.0" alpha="0.25" colorSpace="custom" customColorSpace="sRGB"/>
|
<color key="backgroundColor" red="0.0" green="0.0" blue="0.0" alpha="0.25" colorSpace="custom" customColorSpace="sRGB"/>
|
||||||
<size key="minSize" width="591" height="349"/>
|
<size key="minSize" width="591" height="429"/>
|
||||||
<size key="maxSize" width="1160" height="10000000"/>
|
<size key="maxSize" width="1160" height="10000000"/>
|
||||||
<color key="insertionPointColor" name="controlTextColor" catalog="System" colorSpace="catalog"/>
|
<color key="insertionPointColor" name="controlTextColor" catalog="System" colorSpace="catalog"/>
|
||||||
<allowedInputSourceLocales>
|
<allowedInputSourceLocales>
|
||||||
|
@ -134,7 +138,7 @@
|
||||||
<autoresizingMask key="autoresizingMask"/>
|
<autoresizingMask key="autoresizingMask"/>
|
||||||
</scroller>
|
</scroller>
|
||||||
<scroller key="verticalScroller" wantsLayer="YES" verticalHuggingPriority="750" horizontal="NO" id="cwi-6E-rbh">
|
<scroller key="verticalScroller" wantsLayer="YES" verticalHuggingPriority="750" horizontal="NO" id="cwi-6E-rbh">
|
||||||
<rect key="frame" x="575" y="0.0" width="16" height="349"/>
|
<rect key="frame" x="575" y="0.0" width="16" height="429"/>
|
||||||
<autoresizingMask key="autoresizingMask"/>
|
<autoresizingMask key="autoresizingMask"/>
|
||||||
</scroller>
|
</scroller>
|
||||||
</scrollView>
|
</scrollView>
|
||||||
|
@ -153,106 +157,112 @@
|
||||||
<action selector="consoleInput:" target="-2" id="ylQ-vw-ARS"/>
|
<action selector="consoleInput:" target="-2" id="ylQ-vw-ARS"/>
|
||||||
</connections>
|
</connections>
|
||||||
</textField>
|
</textField>
|
||||||
<box verticalHuggingPriority="750" fixedFrame="YES" boxType="separator" translatesAutoresizingMaskIntoConstraints="NO" id="xJr-K6-B4B">
|
<customView id="sah-kv-6KJ">
|
||||||
<rect key="frame" x="0.0" y="49" width="591" height="4"/>
|
<rect key="frame" x="0.0" y="26" width="591" height="26"/>
|
||||||
<autoresizingMask key="autoresizingMask" widthSizable="YES" flexibleMaxY="YES"/>
|
<autoresizingMask key="autoresizingMask" widthSizable="YES" flexibleMaxY="YES"/>
|
||||||
</box>
|
<subviews>
|
||||||
<box verticalHuggingPriority="750" fixedFrame="YES" boxType="separator" translatesAutoresizingMaskIntoConstraints="NO" id="9DF-fj-a2v">
|
<button verticalHuggingPriority="750" fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="ybQ-jy-NgI" customClass="GBDebuggerButton">
|
||||||
<rect key="frame" x="0.0" y="24" width="591" height="4"/>
|
<rect key="frame" x="4" y="0.0" width="26" height="26"/>
|
||||||
<autoresizingMask key="autoresizingMask" widthSizable="YES" flexibleMaxY="YES"/>
|
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMaxY="YES"/>
|
||||||
</box>
|
<buttonCell key="cell" type="bevel" title="Interrupt" alternateTitle="interrupt" bezelStyle="rounded" image="InterruptTemplate" imagePosition="only" alignment="center" imageScaling="proportionallyDown" inset="2" id="Yd7-kY-21r">
|
||||||
<button verticalHuggingPriority="750" fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="G4h-KO-Z3g" customClass="GBDebuggerButton">
|
<behavior key="behavior" pushIn="YES" lightByBackground="YES" lightByGray="YES"/>
|
||||||
<rect key="frame" x="2" y="26" width="26" height="26"/>
|
<font key="font" metaFont="system"/>
|
||||||
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMaxY="YES"/>
|
</buttonCell>
|
||||||
<buttonCell key="cell" type="bevel" title="Interrupt" alternateTitle="interrupt" bezelStyle="rounded" image="InterruptTemplate" imagePosition="only" alignment="center" imageScaling="proportionallyDown" inset="2" id="wfO-32-eG5">
|
<color key="contentTintColor" name="controlAccentColor" catalog="System" colorSpace="catalog"/>
|
||||||
<behavior key="behavior" pushIn="YES" lightByBackground="YES" lightByGray="YES"/>
|
<connections>
|
||||||
<font key="font" metaFont="system"/>
|
<action selector="debuggerButtonPressed:" target="-2" id="8pX-u8-oFG"/>
|
||||||
</buttonCell>
|
<outlet property="textField" destination="l22-S8-uji" id="cIZ-tr-dAu"/>
|
||||||
<color key="contentTintColor" name="controlAccentColor" catalog="System" colorSpace="catalog"/>
|
</connections>
|
||||||
<connections>
|
</button>
|
||||||
<action selector="debuggerButtonPressed:" target="-2" id="SjG-90-8dJ"/>
|
<button verticalHuggingPriority="750" fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="jdD-yP-Nr6" customClass="GBDebuggerButton">
|
||||||
<outlet property="textField" destination="l22-S8-uji" id="NZ8-eJ-Uyd"/>
|
<rect key="frame" x="80" y="0.0" width="26" height="26"/>
|
||||||
</connections>
|
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMaxY="YES"/>
|
||||||
</button>
|
<buttonCell key="cell" type="bevel" title="Step Out" alternateTitle="finish" bezelStyle="rounded" image="FinishTemplate" imagePosition="only" alignment="center" enabled="NO" imageScaling="proportionallyDown" inset="2" id="16t-ix-lOh">
|
||||||
<button verticalHuggingPriority="750" fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="cOi-Rs-9gS" customClass="GBDebuggerButton">
|
<behavior key="behavior" pushIn="YES" lightByBackground="YES" lightByGray="YES"/>
|
||||||
<rect key="frame" x="28" y="26" width="26" height="26"/>
|
<font key="font" metaFont="system"/>
|
||||||
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMaxY="YES"/>
|
</buttonCell>
|
||||||
<buttonCell key="cell" type="bevel" title="Step Over" alternateTitle="next" bezelStyle="rounded" image="NextTemplate" imagePosition="only" alignment="center" enabled="NO" imageScaling="proportionallyDown" inset="2" id="buW-ke-lgF">
|
<connections>
|
||||||
<behavior key="behavior" pushIn="YES" lightByBackground="YES" lightByGray="YES"/>
|
<action selector="debuggerButtonPressed:" target="-2" id="FXb-hO-cEh"/>
|
||||||
<font key="font" metaFont="system"/>
|
<outlet property="textField" destination="l22-S8-uji" id="IPT-hF-MHv"/>
|
||||||
</buttonCell>
|
</connections>
|
||||||
<connections>
|
</button>
|
||||||
<action selector="debuggerButtonPressed:" target="-2" id="g7E-UM-SHV"/>
|
<button verticalHuggingPriority="750" fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="tTP-Zs-Ohu" customClass="GBDebuggerButton">
|
||||||
<outlet property="textField" destination="l22-S8-uji" id="1uM-AA-yHi"/>
|
<rect key="frame" x="30" y="0.0" width="26" height="26"/>
|
||||||
</connections>
|
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMaxY="YES"/>
|
||||||
</button>
|
<buttonCell key="cell" type="bevel" title="Step Over" alternateTitle="next" bezelStyle="rounded" image="NextTemplate" imagePosition="only" alignment="center" enabled="NO" imageScaling="proportionallyDown" inset="2" id="835-qy-CNq">
|
||||||
<button verticalHuggingPriority="750" fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="DsN-Ce-QoH" customClass="GBDebuggerButton">
|
<behavior key="behavior" pushIn="YES" lightByBackground="YES" lightByGray="YES"/>
|
||||||
<rect key="frame" x="54" y="26" width="26" height="26"/>
|
<font key="font" metaFont="system"/>
|
||||||
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMaxY="YES"/>
|
</buttonCell>
|
||||||
<buttonCell key="cell" type="bevel" title="Step Into" alternateTitle="step" bezelStyle="rounded" image="StepTemplate" imagePosition="only" alignment="center" enabled="NO" imageScaling="proportionallyDown" inset="2" id="ATJ-Vx-zbo">
|
<connections>
|
||||||
<behavior key="behavior" pushIn="YES" lightByBackground="YES" lightByGray="YES"/>
|
<action selector="debuggerButtonPressed:" target="-2" id="qL6-Mz-v2a"/>
|
||||||
<font key="font" metaFont="system"/>
|
<outlet property="textField" destination="l22-S8-uji" id="MRn-cs-a9T"/>
|
||||||
</buttonCell>
|
</connections>
|
||||||
<connections>
|
</button>
|
||||||
<action selector="debuggerButtonPressed:" target="-2" id="QMw-82-HKJ"/>
|
<button verticalHuggingPriority="750" fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="E87-Uq-f2l" customClass="GBDebuggerButton">
|
||||||
<outlet property="textField" destination="l22-S8-uji" id="qaF-TF-cwg"/>
|
<rect key="frame" x="104" y="0.0" width="26" height="26"/>
|
||||||
</connections>
|
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMaxY="YES"/>
|
||||||
</button>
|
<buttonCell key="cell" type="bevel" title="Step Backward" alternateTitle="backstep" bezelStyle="rounded" image="BackstepTemplate" imagePosition="only" alignment="center" enabled="NO" imageScaling="proportionallyDown" inset="2" id="yr5-aU-Fli">
|
||||||
<button verticalHuggingPriority="750" fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="vtb-n5-Qlz" customClass="GBDebuggerButton">
|
<behavior key="behavior" pushIn="YES" lightByBackground="YES" lightByGray="YES"/>
|
||||||
<rect key="frame" x="78" y="26" width="26" height="26"/>
|
<font key="font" metaFont="system"/>
|
||||||
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMaxY="YES"/>
|
</buttonCell>
|
||||||
<buttonCell key="cell" type="bevel" title="Step Out" alternateTitle="finish" bezelStyle="rounded" image="FinishTemplate" imagePosition="only" alignment="center" enabled="NO" imageScaling="proportionallyDown" inset="2" id="8mF-ii-5Hx">
|
<connections>
|
||||||
<behavior key="behavior" pushIn="YES" lightByBackground="YES" lightByGray="YES"/>
|
<action selector="debuggerButtonPressed:" target="-2" id="vyO-14-k3A"/>
|
||||||
<font key="font" metaFont="system"/>
|
<outlet property="textField" destination="l22-S8-uji" id="f5e-xA-0En"/>
|
||||||
</buttonCell>
|
</connections>
|
||||||
<connections>
|
</button>
|
||||||
<action selector="debuggerButtonPressed:" target="-2" id="krr-9m-Jfz"/>
|
<button verticalHuggingPriority="750" fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="fsQ-dD-A8C" customClass="GBDebuggerButton">
|
||||||
<outlet property="textField" destination="l22-S8-uji" id="uYK-tU-BnO"/>
|
<rect key="frame" x="56" y="0.0" width="26" height="26"/>
|
||||||
</connections>
|
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMaxY="YES"/>
|
||||||
</button>
|
<buttonCell key="cell" type="bevel" title="Step Into" alternateTitle="step" bezelStyle="rounded" image="StepTemplate" imagePosition="only" alignment="center" enabled="NO" imageScaling="proportionallyDown" inset="2" id="lau-41-TYH">
|
||||||
<button verticalHuggingPriority="750" fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="oCa-UH-1mi" customClass="GBDebuggerButton">
|
<behavior key="behavior" pushIn="YES" lightByBackground="YES" lightByGray="YES"/>
|
||||||
<rect key="frame" x="563" y="26" width="26" height="26"/>
|
<font key="font" metaFont="system"/>
|
||||||
<autoresizingMask key="autoresizingMask" flexibleMinX="YES" flexibleMaxY="YES"/>
|
</buttonCell>
|
||||||
<buttonCell key="cell" type="bevel" title="Help" alternateTitle="help" bezelStyle="rounded" image="HelpTemplate" imagePosition="only" alignment="center" imageScaling="proportionallyDown" inset="2" id="tvn-kY-8FO">
|
<connections>
|
||||||
<behavior key="behavior" pushIn="YES" lightByBackground="YES" lightByGray="YES"/>
|
<action selector="debuggerButtonPressed:" target="-2" id="6DD-pu-gwc"/>
|
||||||
<font key="font" metaFont="system"/>
|
<outlet property="textField" destination="l22-S8-uji" id="ILQ-oy-iGc"/>
|
||||||
</buttonCell>
|
</connections>
|
||||||
<connections>
|
</button>
|
||||||
<action selector="debuggerButtonPressed:" target="-2" id="PwN-rf-AcB"/>
|
<box verticalHuggingPriority="750" fixedFrame="YES" boxType="separator" translatesAutoresizingMaskIntoConstraints="NO" id="8bt-2t-EIG">
|
||||||
<outlet property="textField" destination="l22-S8-uji" id="blK-B3-MWI"/>
|
<rect key="frame" x="-2" y="23" width="593" height="4"/>
|
||||||
</connections>
|
<autoresizingMask key="autoresizingMask" widthSizable="YES" flexibleMaxY="YES"/>
|
||||||
</button>
|
</box>
|
||||||
<button verticalHuggingPriority="750" fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="onn-R8-3vg" customClass="GBDebuggerButton">
|
<box verticalHuggingPriority="750" fixedFrame="YES" boxType="separator" translatesAutoresizingMaskIntoConstraints="NO" id="eSO-2z-QHX">
|
||||||
<rect key="frame" x="102" y="26" width="26" height="26"/>
|
<rect key="frame" x="-2" y="-2" width="593" height="4"/>
|
||||||
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMaxY="YES"/>
|
<autoresizingMask key="autoresizingMask" widthSizable="YES" flexibleMaxY="YES"/>
|
||||||
<buttonCell key="cell" type="bevel" title="Step Backwards" alternateTitle="backstep" bezelStyle="rounded" image="BackstepTemplate" imagePosition="only" alignment="center" enabled="NO" imageScaling="proportionallyDown" inset="2" id="WtK-kD-bf6">
|
</box>
|
||||||
<behavior key="behavior" pushIn="YES" lightByBackground="YES" lightByGray="YES"/>
|
<button verticalHuggingPriority="750" fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="0Jt-TO-8CM" customClass="GBDebuggerButton">
|
||||||
<font key="font" metaFont="system"/>
|
<rect key="frame" x="561" y="0.0" width="26" height="26"/>
|
||||||
</buttonCell>
|
<autoresizingMask key="autoresizingMask" flexibleMinX="YES" flexibleMaxY="YES"/>
|
||||||
<connections>
|
<buttonCell key="cell" type="bevel" title="Help" alternateTitle="help" bezelStyle="rounded" image="HelpTemplate" imagePosition="only" alignment="center" imageScaling="proportionallyDown" inset="2" id="fVh-bT-eYs">
|
||||||
<action selector="debuggerButtonPressed:" target="-2" id="S9a-jV-Z6g"/>
|
<behavior key="behavior" pushIn="YES" lightByBackground="YES" lightByGray="YES"/>
|
||||||
<outlet property="textField" destination="l22-S8-uji" id="1gw-Lc-QFS"/>
|
<font key="font" metaFont="system"/>
|
||||||
</connections>
|
</buttonCell>
|
||||||
</button>
|
<connections>
|
||||||
|
<action selector="debuggerButtonPressed:" target="-2" id="hKh-wH-W5U"/>
|
||||||
|
<outlet property="textField" destination="l22-S8-uji" id="PMA-QA-gwg"/>
|
||||||
|
</connections>
|
||||||
|
</button>
|
||||||
|
</subviews>
|
||||||
|
</customView>
|
||||||
</subviews>
|
</subviews>
|
||||||
</customView>
|
</customView>
|
||||||
<customView fixedFrame="YES" id="4Z2-33-dYY" customClass="GBOptionalVisualEffectView">
|
<customView fixedFrame="YES" id="4Z2-33-dYY" customClass="GBOptionalVisualEffectView">
|
||||||
<rect key="frame" x="592" y="0.0" width="329" height="401"/>
|
<rect key="frame" x="592" y="0.0" width="329" height="481"/>
|
||||||
<autoresizingMask key="autoresizingMask"/>
|
<autoresizingMask key="autoresizingMask"/>
|
||||||
<subviews>
|
<subviews>
|
||||||
<scrollView fixedFrame="YES" borderType="none" horizontalLineScroll="10" horizontalPageScroll="10" verticalLineScroll="10" verticalPageScroll="10" hasHorizontalScroller="NO" usesPredominantAxisScrolling="NO" scrollerKnobStyle="dark" translatesAutoresizingMaskIntoConstraints="NO" id="V9U-Ua-F4z">
|
<scrollView fixedFrame="YES" borderType="none" horizontalLineScroll="10" horizontalPageScroll="10" verticalLineScroll="10" verticalPageScroll="10" hasHorizontalScroller="NO" usesPredominantAxisScrolling="NO" scrollerKnobStyle="dark" translatesAutoresizingMaskIntoConstraints="NO" id="V9U-Ua-F4z">
|
||||||
<rect key="frame" x="0.0" y="354" width="329" height="47"/>
|
<rect key="frame" x="0.0" y="418" width="329" height="63"/>
|
||||||
<autoresizingMask key="autoresizingMask" widthSizable="YES" flexibleMinY="YES"/>
|
<autoresizingMask key="autoresizingMask" widthSizable="YES" flexibleMinY="YES"/>
|
||||||
<clipView key="contentView" drawsBackground="NO" copiesOnScroll="NO" id="YHx-TM-zIC">
|
<clipView key="contentView" drawsBackground="NO" copiesOnScroll="NO" id="YHx-TM-zIC">
|
||||||
<rect key="frame" x="0.0" y="0.0" width="329" height="47"/>
|
<rect key="frame" x="0.0" y="0.0" width="329" height="63"/>
|
||||||
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
|
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
|
||||||
<subviews>
|
<subviews>
|
||||||
<textView drawsBackground="NO" importsGraphics="NO" richText="NO" verticallyResizable="YES" allowsCharacterPickerTouchBarItem="NO" allowsUndo="YES" allowsNonContiguousLayout="YES" textCompletion="NO" spellingCorrection="YES" id="w0g-eK-jM4">
|
<textView drawsBackground="NO" importsGraphics="NO" richText="NO" verticallyResizable="YES" allowsCharacterPickerTouchBarItem="NO" allowsUndo="YES" allowsNonContiguousLayout="YES" textCompletion="NO" spellingCorrection="YES" id="w0g-eK-jM4">
|
||||||
<rect key="frame" x="0.0" y="0.0" width="329" height="47"/>
|
<rect key="frame" x="0.0" y="0.0" width="329" height="63"/>
|
||||||
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
|
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
|
||||||
<color key="textColor" name="textColor" catalog="System" colorSpace="catalog"/>
|
<color key="textColor" name="textColor" catalog="System" colorSpace="catalog"/>
|
||||||
<color key="backgroundColor" name="textBackgroundColor" catalog="System" colorSpace="catalog"/>
|
<color key="backgroundColor" name="textBackgroundColor" catalog="System" colorSpace="catalog"/>
|
||||||
<size key="minSize" width="329" height="47"/>
|
<size key="minSize" width="329" height="63"/>
|
||||||
<size key="maxSize" width="463" height="10000000"/>
|
<size key="maxSize" width="463" height="10000000"/>
|
||||||
<color key="insertionPointColor" name="controlTextColor" catalog="System" colorSpace="catalog"/>
|
<color key="insertionPointColor" name="controlTextColor" catalog="System" colorSpace="catalog"/>
|
||||||
<allowedInputSourceLocales>
|
<allowedInputSourceLocales>
|
||||||
|
@ -266,27 +276,27 @@
|
||||||
<autoresizingMask key="autoresizingMask"/>
|
<autoresizingMask key="autoresizingMask"/>
|
||||||
</scroller>
|
</scroller>
|
||||||
<scroller key="verticalScroller" wantsLayer="YES" verticalHuggingPriority="750" doubleValue="1" horizontal="NO" id="qgN-F8-fdB">
|
<scroller key="verticalScroller" wantsLayer="YES" verticalHuggingPriority="750" doubleValue="1" horizontal="NO" id="qgN-F8-fdB">
|
||||||
<rect key="frame" x="313" y="0.0" width="16" height="47"/>
|
<rect key="frame" x="313" y="0.0" width="16" height="63"/>
|
||||||
<autoresizingMask key="autoresizingMask"/>
|
<autoresizingMask key="autoresizingMask"/>
|
||||||
</scroller>
|
</scroller>
|
||||||
</scrollView>
|
</scrollView>
|
||||||
<box verticalHuggingPriority="750" fixedFrame="YES" boxType="separator" translatesAutoresizingMaskIntoConstraints="NO" id="5qI-qZ-nkh">
|
<box verticalHuggingPriority="750" fixedFrame="YES" boxType="separator" translatesAutoresizingMaskIntoConstraints="NO" id="5qI-qZ-nkh">
|
||||||
<rect key="frame" x="0.0" y="352" width="329" height="5"/>
|
<rect key="frame" x="0.0" y="415" width="329" height="5"/>
|
||||||
<autoresizingMask key="autoresizingMask" widthSizable="YES" flexibleMinY="YES"/>
|
<autoresizingMask key="autoresizingMask" widthSizable="YES" flexibleMinY="YES"/>
|
||||||
</box>
|
</box>
|
||||||
<scrollView fixedFrame="YES" borderType="none" horizontalLineScroll="10" horizontalPageScroll="10" verticalLineScroll="10" verticalPageScroll="10" hasHorizontalScroller="NO" usesPredominantAxisScrolling="NO" translatesAutoresizingMaskIntoConstraints="NO" id="vts-CC-ZjQ">
|
<scrollView fixedFrame="YES" borderType="none" horizontalLineScroll="10" horizontalPageScroll="10" verticalLineScroll="10" verticalPageScroll="10" hasHorizontalScroller="NO" usesPredominantAxisScrolling="NO" translatesAutoresizingMaskIntoConstraints="NO" id="vts-CC-ZjQ">
|
||||||
<rect key="frame" x="0.0" y="0.0" width="329" height="354"/>
|
<rect key="frame" x="0.0" y="78" width="329" height="339"/>
|
||||||
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
|
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
|
||||||
<clipView key="contentView" drawsBackground="NO" copiesOnScroll="NO" id="Cs9-3x-ATg">
|
<clipView key="contentView" drawsBackground="NO" copiesOnScroll="NO" id="Cs9-3x-ATg">
|
||||||
<rect key="frame" x="0.0" y="0.0" width="329" height="354"/>
|
<rect key="frame" x="0.0" y="0.0" width="329" height="339"/>
|
||||||
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
|
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
|
||||||
<subviews>
|
<subviews>
|
||||||
<textView editable="NO" drawsBackground="NO" importsGraphics="NO" richText="NO" verticallyResizable="YES" baseWritingDirection="leftToRight" findStyle="bar" allowsNonContiguousLayout="YES" spellingCorrection="YES" id="JgV-7E-iwp">
|
<textView editable="NO" drawsBackground="NO" importsGraphics="NO" richText="NO" verticallyResizable="YES" baseWritingDirection="leftToRight" findStyle="bar" allowsNonContiguousLayout="YES" spellingCorrection="YES" id="JgV-7E-iwp">
|
||||||
<rect key="frame" x="0.0" y="0.0" width="329" height="354"/>
|
<rect key="frame" x="0.0" y="0.0" width="329" height="339"/>
|
||||||
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
|
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
|
||||||
<color key="textColor" name="textColor" catalog="System" colorSpace="catalog"/>
|
<color key="textColor" name="textColor" catalog="System" colorSpace="catalog"/>
|
||||||
<color key="backgroundColor" red="0.14901960780000001" green="0.14901960780000001" blue="0.14901960780000001" alpha="1" colorSpace="calibratedRGB"/>
|
<color key="backgroundColor" red="0.14901960780000001" green="0.14901960780000001" blue="0.14901960780000001" alpha="1" colorSpace="calibratedRGB"/>
|
||||||
<size key="minSize" width="329" height="354"/>
|
<size key="minSize" width="329" height="339"/>
|
||||||
<size key="maxSize" width="1160" height="10000000"/>
|
<size key="maxSize" width="1160" height="10000000"/>
|
||||||
<color key="insertionPointColor" name="controlTextColor" catalog="System" colorSpace="catalog"/>
|
<color key="insertionPointColor" name="controlTextColor" catalog="System" colorSpace="catalog"/>
|
||||||
<allowedInputSourceLocales>
|
<allowedInputSourceLocales>
|
||||||
|
@ -301,10 +311,38 @@
|
||||||
<autoresizingMask key="autoresizingMask"/>
|
<autoresizingMask key="autoresizingMask"/>
|
||||||
</scroller>
|
</scroller>
|
||||||
<scroller key="verticalScroller" wantsLayer="YES" verticalHuggingPriority="750" horizontal="NO" id="4jm-Gm-D2R">
|
<scroller key="verticalScroller" wantsLayer="YES" verticalHuggingPriority="750" horizontal="NO" id="4jm-Gm-D2R">
|
||||||
<rect key="frame" x="313" y="0.0" width="16" height="354"/>
|
<rect key="frame" x="313" y="0.0" width="16" height="339"/>
|
||||||
<autoresizingMask key="autoresizingMask"/>
|
<autoresizingMask key="autoresizingMask"/>
|
||||||
</scroller>
|
</scroller>
|
||||||
</scrollView>
|
</scrollView>
|
||||||
|
<box verticalHuggingPriority="750" fixedFrame="YES" boxType="separator" translatesAutoresizingMaskIntoConstraints="NO" id="wC1-WG-WRf">
|
||||||
|
<rect key="frame" x="0.0" y="75" width="329" height="5"/>
|
||||||
|
<autoresizingMask key="autoresizingMask" widthSizable="YES" flexibleMaxY="YES"/>
|
||||||
|
</box>
|
||||||
|
<customView fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="aBf-yU-8M0" customClass="GBCPUView">
|
||||||
|
<rect key="frame" x="0.0" y="0.0" width="329" height="77"/>
|
||||||
|
<autoresizingMask key="autoresizingMask" widthSizable="YES" flexibleMaxY="YES"/>
|
||||||
|
<subviews>
|
||||||
|
<textField focusRingType="none" horizontalHuggingPriority="251" verticalHuggingPriority="750" fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="F9b-AT-CdX">
|
||||||
|
<rect key="frame" x="2" y="59" width="100" height="16"/>
|
||||||
|
<autoresizingMask key="autoresizingMask" widthSizable="YES" flexibleMaxY="YES"/>
|
||||||
|
<textFieldCell key="cell" lineBreakMode="clipping" title="CPU Load" id="ai6-8E-Let">
|
||||||
|
<font key="font" metaFont="smallSystemBold"/>
|
||||||
|
<color key="textColor" white="1" alpha="1" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/>
|
||||||
|
<color key="backgroundColor" name="textBackgroundColor" catalog="System" colorSpace="catalog"/>
|
||||||
|
</textFieldCell>
|
||||||
|
</textField>
|
||||||
|
<textField focusRingType="none" horizontalHuggingPriority="251" verticalHuggingPriority="750" fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="xdx-GC-Tb8">
|
||||||
|
<rect key="frame" x="2" y="2" width="100" height="16"/>
|
||||||
|
<autoresizingMask key="autoresizingMask" widthSizable="YES" flexibleMaxY="YES"/>
|
||||||
|
<textFieldCell key="cell" lineBreakMode="clipping" alignment="left" title="100%" id="set-AM-fVX">
|
||||||
|
<font key="font" metaFont="smallSystemBold"/>
|
||||||
|
<color key="textColor" white="1" alpha="1" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/>
|
||||||
|
<color key="backgroundColor" name="textBackgroundColor" catalog="System" colorSpace="catalog"/>
|
||||||
|
</textFieldCell>
|
||||||
|
</textField>
|
||||||
|
</subviews>
|
||||||
|
</customView>
|
||||||
</subviews>
|
</subviews>
|
||||||
</customView>
|
</customView>
|
||||||
</subviews>
|
</subviews>
|
||||||
|
@ -318,9 +356,12 @@
|
||||||
</splitView>
|
</splitView>
|
||||||
</subviews>
|
</subviews>
|
||||||
</view>
|
</view>
|
||||||
|
<connections>
|
||||||
|
<outlet property="ownerWindow" destination="xOd-HO-29H" id="beo-JZ-Ekb"/>
|
||||||
|
</connections>
|
||||||
<point key="canvasLocation" x="347.5" y="-29"/>
|
<point key="canvasLocation" x="347.5" y="-29"/>
|
||||||
</window>
|
</window>
|
||||||
<window title="Memory" allowsToolTipsWhenApplicationIsInactive="NO" autorecalculatesKeyViewLoop="NO" restorable="NO" releasedWhenClosed="NO" visibleAtLaunch="NO" animationBehavior="default" toolbarStyle="expanded" id="mRm-dL-mCj" customClass="NSPanel">
|
<window title="Memory" allowsToolTipsWhenApplicationIsInactive="NO" autorecalculatesKeyViewLoop="NO" restorable="NO" releasedWhenClosed="NO" visibleAtLaunch="NO" animationBehavior="default" toolbarStyle="expanded" id="mRm-dL-mCj" customClass="GBPanel">
|
||||||
<windowStyleMask key="styleMask" titled="YES" closable="YES" resizable="YES"/>
|
<windowStyleMask key="styleMask" titled="YES" closable="YES" resizable="YES"/>
|
||||||
<windowCollectionBehavior key="collectionBehavior" fullScreenAuxiliary="YES"/>
|
<windowCollectionBehavior key="collectionBehavior" fullScreenAuxiliary="YES"/>
|
||||||
<rect key="contentRect" x="0.0" y="0.0" width="528" height="320"/>
|
<rect key="contentRect" x="0.0" y="0.0" width="528" height="320"/>
|
||||||
|
@ -329,20 +370,20 @@
|
||||||
<rect key="frame" x="0.0" y="0.0" width="528" height="320"/>
|
<rect key="frame" x="0.0" y="0.0" width="528" height="320"/>
|
||||||
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
|
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
|
||||||
</view>
|
</view>
|
||||||
<toolbar key="toolbar" implicitIdentifier="D857E961-E523-4295-83F8-0849316E827C" autosavesConfiguration="NO" allowsUserCustomization="NO" displayMode="iconAndLabel" sizeMode="regular" id="82v-uB-RPi">
|
<toolbar key="toolbar" implicitIdentifier="D857E961-E523-4295-83F8-0849316E827C" autosavesConfiguration="NO" allowsUserCustomization="NO" showsBaselineSeparator="NO" displayMode="iconAndLabel" sizeMode="regular" id="82v-uB-RPi">
|
||||||
<allowedToolbarItems>
|
<allowedToolbarItems>
|
||||||
<toolbarItem implicitItemIdentifier="NSToolbarSpaceItem" id="WUk-8p-S6B"/>
|
<toolbarItem implicitItemIdentifier="NSToolbarSpaceItem" id="WUk-8p-S6B"/>
|
||||||
<toolbarItem implicitItemIdentifier="NSToolbarFlexibleSpaceItem" id="E3z-um-6KG"/>
|
<toolbarItem implicitItemIdentifier="NSToolbarFlexibleSpaceItem" id="E3z-um-6KG"/>
|
||||||
<toolbarItem implicitItemIdentifier="4F6AAE25-1E9D-4111-9E5B-91F0792E56CD" label="Address Space" paletteLabel="Address Space" id="VTy-lj-K0H">
|
<toolbarItem implicitItemIdentifier="4F6AAE25-1E9D-4111-9E5B-91F0792E56CD" label="Address Space" paletteLabel="Address Space" id="VTy-lj-K0H">
|
||||||
<nil key="toolTip"/>
|
<nil key="toolTip"/>
|
||||||
<size key="minSize" width="100" height="25"/>
|
<size key="minSize" width="160" height="25"/>
|
||||||
<size key="maxSize" width="130" height="25"/>
|
<size key="maxSize" width="160" height="25"/>
|
||||||
<popUpButton key="view" verticalHuggingPriority="750" id="vfJ-vu-gqJ">
|
<popUpButton key="view" verticalHuggingPriority="750" id="vfJ-vu-gqJ">
|
||||||
<rect key="frame" x="0.0" y="14" width="128" height="25"/>
|
<rect key="frame" x="0.0" y="14" width="160" height="25"/>
|
||||||
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMinY="YES"/>
|
<autoresizingMask key="autoresizingMask" widthSizable="YES" flexibleMinY="YES" flexibleMaxY="YES"/>
|
||||||
<popUpButtonCell key="cell" type="roundTextured" bezelStyle="texturedRounded" alignment="left" lineBreakMode="truncatingTail" borderStyle="border" imageScaling="proportionallyDown" inset="2" id="bpD-j9-omo">
|
<popUpButtonCell key="cell" type="roundTextured" bezelStyle="texturedRounded" alignment="left" lineBreakMode="truncatingTail" borderStyle="border" imageScaling="proportionallyDown" inset="2" id="bpD-j9-omo" customClass="GBToolbarPopUpButtonCell">
|
||||||
<behavior key="behavior" pushIn="YES" lightByBackground="YES" lightByGray="YES"/>
|
<behavior key="behavior" pushIn="YES" lightByBackground="YES" lightByGray="YES"/>
|
||||||
<font key="font" metaFont="menu"/>
|
<font key="font" metaFont="message"/>
|
||||||
<menu key="menu" id="gTX-6Z-mOH">
|
<menu key="menu" id="gTX-6Z-mOH">
|
||||||
<items>
|
<items>
|
||||||
<menuItem title="Entire Space" id="Zp5-J9-dd3"/>
|
<menuItem title="Entire Space" id="Zp5-J9-dd3"/>
|
||||||
|
@ -361,31 +402,29 @@
|
||||||
<toolbarItem implicitItemIdentifier="D16C64D2-2F0D-4033-A1EC-A1E699522ECE" label="Bank" paletteLabel="Bank" id="bWC-FW-IYP">
|
<toolbarItem implicitItemIdentifier="D16C64D2-2F0D-4033-A1EC-A1E699522ECE" label="Bank" paletteLabel="Bank" id="bWC-FW-IYP">
|
||||||
<nil key="toolTip"/>
|
<nil key="toolTip"/>
|
||||||
<size key="minSize" width="64" height="22"/>
|
<size key="minSize" width="64" height="22"/>
|
||||||
<size key="maxSize" width="64" height="22"/>
|
<size key="maxSize" width="80" height="22"/>
|
||||||
<textField key="view" verticalHuggingPriority="750" id="rdV-q6-hc6">
|
<textField key="view" focusRingType="none" verticalHuggingPriority="750" id="rdV-q6-hc6">
|
||||||
<rect key="frame" x="0.0" y="14" width="64" height="22"/>
|
<rect key="frame" x="0.0" y="14" width="64" height="22"/>
|
||||||
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMinY="YES"/>
|
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
|
||||||
<textFieldCell key="cell" scrollable="YES" lineBreakMode="clipping" selectable="YES" editable="YES" sendsActionOnEndEditing="YES" state="on" borderStyle="bezel" id="JCn-Y1-eHS">
|
<textFieldCell key="cell" scrollable="YES" lineBreakMode="clipping" selectable="YES" editable="YES" state="on" borderStyle="bezel" placeholderString="Bank" id="JCn-Y1-eHS" customClass="GBToolbarFieldCell">
|
||||||
<font key="font" metaFont="system"/>
|
<font key="font" metaFont="system"/>
|
||||||
<color key="textColor" name="controlTextColor" catalog="System" colorSpace="catalog"/>
|
<color key="textColor" name="controlTextColor" catalog="System" colorSpace="catalog"/>
|
||||||
<color key="backgroundColor" name="textBackgroundColor" catalog="System" colorSpace="catalog"/>
|
|
||||||
</textFieldCell>
|
</textFieldCell>
|
||||||
<connections>
|
<connections>
|
||||||
<action selector="hexUpdateBank:" target="-2" id="Mx9-WI-wgO"/>
|
<action selector="hexUpdateBank:" target="-2" id="Mx9-WI-wgO"/>
|
||||||
</connections>
|
</connections>
|
||||||
</textField>
|
</textField>
|
||||||
</toolbarItem>
|
</toolbarItem>
|
||||||
<toolbarItem implicitItemIdentifier="F9723DA8-D79F-43AB-876B-783DD0204AA6" label="Go to" paletteLabel="Go to" id="rLO-D7-zRG">
|
<toolbarItem implicitItemIdentifier="F9723DA8-D79F-43AB-876B-783DD0204AA6" label="Go To" paletteLabel="Go To" id="rLO-D7-zRG">
|
||||||
<nil key="toolTip"/>
|
<nil key="toolTip"/>
|
||||||
<size key="minSize" width="96" height="22"/>
|
<size key="minSize" width="160" height="22"/>
|
||||||
<size key="maxSize" width="128" height="22"/>
|
<size key="maxSize" width="160" height="22"/>
|
||||||
<textField key="view" verticalHuggingPriority="750" id="EJd-jG-hmH">
|
<textField key="view" focusRingType="none" verticalHuggingPriority="750" id="EJd-jG-hmH">
|
||||||
<rect key="frame" x="0.0" y="14" width="96" height="22"/>
|
<rect key="frame" x="0.0" y="14" width="160" height="22"/>
|
||||||
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMinY="YES"/>
|
<autoresizingMask key="autoresizingMask" widthSizable="YES"/>
|
||||||
<textFieldCell key="cell" scrollable="YES" lineBreakMode="clipping" selectable="YES" editable="YES" state="on" borderStyle="bezel" bezelStyle="round" id="vg5-Nn-abb">
|
<textFieldCell key="cell" scrollable="YES" lineBreakMode="clipping" selectable="YES" editable="YES" state="on" borderStyle="bezel" placeholderString="Address" bezelStyle="round" id="vg5-Nn-abb" customClass="GBToolbarFieldCell">
|
||||||
<font key="font" metaFont="system"/>
|
<font key="font" metaFont="system"/>
|
||||||
<color key="textColor" name="controlTextColor" catalog="System" colorSpace="catalog"/>
|
<color key="textColor" name="controlTextColor" catalog="System" colorSpace="catalog"/>
|
||||||
<color key="backgroundColor" name="textBackgroundColor" catalog="System" colorSpace="catalog"/>
|
|
||||||
</textFieldCell>
|
</textFieldCell>
|
||||||
<connections>
|
<connections>
|
||||||
<action selector="hexGoTo:" target="-2" id="7WG-8C-SK8"/>
|
<action selector="hexGoTo:" target="-2" id="7WG-8C-SK8"/>
|
||||||
|
@ -400,15 +439,18 @@
|
||||||
<toolbarItem reference="rLO-D7-zRG"/>
|
<toolbarItem reference="rLO-D7-zRG"/>
|
||||||
</defaultToolbarItems>
|
</defaultToolbarItems>
|
||||||
</toolbar>
|
</toolbar>
|
||||||
|
<connections>
|
||||||
|
<outlet property="ownerWindow" destination="xOd-HO-29H" id="wCE-dT-kGv"/>
|
||||||
|
</connections>
|
||||||
<point key="canvasLocation" x="-185" y="61"/>
|
<point key="canvasLocation" x="-185" y="61"/>
|
||||||
</window>
|
</window>
|
||||||
<menuItem title="Cartridge RAM" id="ylM-ah-PNQ"/>
|
<menuItem title="Cartridge RAM" id="ylM-ah-PNQ"/>
|
||||||
<window title="VRAM Viewer" allowsToolTipsWhenApplicationIsInactive="NO" autorecalculatesKeyViewLoop="NO" restorable="NO" releasedWhenClosed="NO" visibleAtLaunch="NO" animationBehavior="default" toolbarStyle="expanded" id="mbr-db-iZh" customClass="NSPanel">
|
<window title="VRAM Viewer" allowsToolTipsWhenApplicationIsInactive="NO" autorecalculatesKeyViewLoop="NO" restorable="NO" releasedWhenClosed="NO" visibleAtLaunch="NO" animationBehavior="default" toolbarStyle="expanded" id="mbr-db-iZh" customClass="GBPanel">
|
||||||
<windowStyleMask key="styleMask" titled="YES" closable="YES"/>
|
<windowStyleMask key="styleMask" titled="YES" closable="YES"/>
|
||||||
<windowCollectionBehavior key="collectionBehavior" fullScreenAuxiliary="YES"/>
|
<windowCollectionBehavior key="collectionBehavior" fullScreenAuxiliary="YES"/>
|
||||||
<rect key="contentRect" x="0.0" y="0.0" width="512" height="432"/>
|
<rect key="contentRect" x="0.0" y="0.0" width="512" height="432"/>
|
||||||
<rect key="screenRect" x="0.0" y="0.0" width="2560" height="1415"/>
|
<rect key="screenRect" x="0.0" y="0.0" width="2560" height="1415"/>
|
||||||
<view key="contentView" id="GYW-dv-Um1">
|
<view key="contentView" misplaced="YES" id="GYW-dv-Um1">
|
||||||
<rect key="frame" x="0.0" y="0.0" width="512" height="432"/>
|
<rect key="frame" x="0.0" y="0.0" width="512" height="432"/>
|
||||||
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
|
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
|
||||||
<subviews>
|
<subviews>
|
||||||
|
@ -416,7 +458,7 @@
|
||||||
<rect key="frame" x="0.0" y="406" width="512" height="5"/>
|
<rect key="frame" x="0.0" y="406" width="512" height="5"/>
|
||||||
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMinY="YES"/>
|
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMinY="YES"/>
|
||||||
</box>
|
</box>
|
||||||
<textField horizontalHuggingPriority="251" verticalHuggingPriority="750" fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="6vK-IP-PmP">
|
<textField focusRingType="none" horizontalHuggingPriority="251" verticalHuggingPriority="750" fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="6vK-IP-PmP">
|
||||||
<rect key="frame" x="-2" y="4" width="516" height="14"/>
|
<rect key="frame" x="-2" y="4" width="516" height="14"/>
|
||||||
<autoresizingMask key="autoresizingMask" widthSizable="YES" flexibleMaxY="YES"/>
|
<autoresizingMask key="autoresizingMask" widthSizable="YES" flexibleMaxY="YES"/>
|
||||||
<textFieldCell key="cell" controlSize="small" scrollable="YES" lineBreakMode="clipping" sendsActionOnEndEditing="YES" alignment="center" id="umk-4r-VNg">
|
<textFieldCell key="cell" controlSize="small" scrollable="YES" lineBreakMode="clipping" sendsActionOnEndEditing="YES" alignment="center" id="umk-4r-VNg">
|
||||||
|
@ -549,7 +591,7 @@
|
||||||
</connections>
|
</connections>
|
||||||
</popUpButton>
|
</popUpButton>
|
||||||
<popUpButton focusRingType="none" verticalHuggingPriority="750" fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="YIJ-Qc-SIZ">
|
<popUpButton focusRingType="none" verticalHuggingPriority="750" fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="YIJ-Qc-SIZ">
|
||||||
<rect key="frame" x="135" y="412" width="96" height="17"/>
|
<rect key="frame" x="135" y="412" width="100" height="17"/>
|
||||||
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMinY="YES"/>
|
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMinY="YES"/>
|
||||||
<popUpButtonCell key="cell" type="roundRect" title="Effective Tilemap" bezelStyle="roundedRect" alignment="left" controlSize="mini" lineBreakMode="truncatingTail" state="on" borderStyle="border" focusRingType="none" imageScaling="proportionallyDown" inset="2" selectedItem="XRF-Vj-3gs" id="3W1-Db-wDn">
|
<popUpButtonCell key="cell" type="roundRect" title="Effective Tilemap" bezelStyle="roundedRect" alignment="left" controlSize="mini" lineBreakMode="truncatingTail" state="on" borderStyle="border" focusRingType="none" imageScaling="proportionallyDown" inset="2" selectedItem="XRF-Vj-3gs" id="3W1-Db-wDn">
|
||||||
<behavior key="behavior" pushIn="YES" lightByBackground="YES" lightByGray="YES"/>
|
<behavior key="behavior" pushIn="YES" lightByBackground="YES" lightByGray="YES"/>
|
||||||
|
@ -567,7 +609,7 @@
|
||||||
</connections>
|
</connections>
|
||||||
</popUpButton>
|
</popUpButton>
|
||||||
<popUpButton focusRingType="none" verticalHuggingPriority="750" fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="k4c-Vg-MBu">
|
<popUpButton focusRingType="none" verticalHuggingPriority="750" fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="k4c-Vg-MBu">
|
||||||
<rect key="frame" x="235" y="412" width="96" height="17"/>
|
<rect key="frame" x="239" y="412" width="100" height="17"/>
|
||||||
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMinY="YES"/>
|
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMinY="YES"/>
|
||||||
<popUpButtonCell key="cell" type="roundRect" title="Effective Tileset" bezelStyle="roundedRect" alignment="left" controlSize="mini" lineBreakMode="truncatingTail" state="on" borderStyle="border" focusRingType="none" imageScaling="proportionallyDown" inset="2" selectedItem="CRe-dX-rzY" id="h53-sb-Odg">
|
<popUpButtonCell key="cell" type="roundRect" title="Effective Tileset" bezelStyle="roundedRect" alignment="left" controlSize="mini" lineBreakMode="truncatingTail" state="on" borderStyle="border" focusRingType="none" imageScaling="proportionallyDown" inset="2" selectedItem="CRe-dX-rzY" id="h53-sb-Odg">
|
||||||
<behavior key="behavior" pushIn="YES" lightByBackground="YES" lightByGray="YES"/>
|
<behavior key="behavior" pushIn="YES" lightByBackground="YES" lightByGray="YES"/>
|
||||||
|
@ -635,21 +677,19 @@
|
||||||
</tabView>
|
</tabView>
|
||||||
</subviews>
|
</subviews>
|
||||||
</view>
|
</view>
|
||||||
<toolbar key="toolbar" implicitIdentifier="7FF8B5E5-F61B-408C-9634-A5D496FE5E70" autosavesConfiguration="NO" allowsUserCustomization="NO" displayMode="iconOnly" sizeMode="regular" id="SVR-To-n7n">
|
<toolbar key="toolbar" implicitIdentifier="7FF8B5E5-F61B-408C-9634-A5D496FE5E70" autosavesConfiguration="NO" allowsUserCustomization="NO" showsBaselineSeparator="NO" displayMode="iconOnly" sizeMode="regular" id="SVR-To-n7n">
|
||||||
<allowedToolbarItems>
|
<allowedToolbarItems>
|
||||||
<toolbarItem implicitItemIdentifier="NSToolbarFlexibleSpaceItem" id="hnI-48-dYt"/>
|
<toolbarItem implicitItemIdentifier="NSToolbarFlexibleSpaceItem" id="hnI-48-dYt"/>
|
||||||
<toolbarItem implicitItemIdentifier="B9D3CF98-8020-4389-9372-F99361440794" label="" paletteLabel="" id="fmK-Jl-Koj">
|
<toolbarItem implicitItemIdentifier="B9D3CF98-8020-4389-9372-F99361440794" label="" paletteLabel="" sizingBehavior="auto" id="fmK-Jl-Koj">
|
||||||
<nil key="toolTip"/>
|
<nil key="toolTip"/>
|
||||||
<size key="minSize" width="100" height="25"/>
|
|
||||||
<size key="maxSize" width="268" height="25"/>
|
|
||||||
<segmentedControl key="view" verticalHuggingPriority="750" id="Aul-vO-dCK">
|
<segmentedControl key="view" verticalHuggingPriority="750" id="Aul-vO-dCK">
|
||||||
<rect key="frame" x="0.0" y="14" width="268" height="25"/>
|
<rect key="frame" x="0.0" y="14" width="268" height="25"/>
|
||||||
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMinY="YES"/>
|
<autoresizingMask key="autoresizingMask"/>
|
||||||
<segmentedCell key="cell" borderStyle="border" alignment="left" style="texturedSquare" trackingMode="selectOne" id="HhR-ky-5NN">
|
<segmentedCell key="cell" borderStyle="border" alignment="left" style="texturedSquare" trackingMode="selectOne" id="HhR-ky-5NN">
|
||||||
<font key="font" metaFont="system"/>
|
<font key="font" metaFont="system"/>
|
||||||
<segments>
|
<segments>
|
||||||
<segment label="Tileset" selected="YES"/>
|
<segment label="Tileset" selected="YES"/>
|
||||||
<segment label="Tilemap" tag="1"/>
|
<segment label="Tilemap"/>
|
||||||
<segment label="Objects"/>
|
<segment label="Objects"/>
|
||||||
<segment label="Palettes"/>
|
<segment label="Palettes"/>
|
||||||
</segments>
|
</segments>
|
||||||
|
@ -667,9 +707,12 @@
|
||||||
</defaultToolbarItems>
|
</defaultToolbarItems>
|
||||||
</toolbar>
|
</toolbar>
|
||||||
<contentBorderThickness minY="24"/>
|
<contentBorderThickness minY="24"/>
|
||||||
|
<connections>
|
||||||
|
<outlet property="ownerWindow" destination="xOd-HO-29H" id="hkb-AH-4fo"/>
|
||||||
|
</connections>
|
||||||
<point key="canvasLocation" x="182" y="760"/>
|
<point key="canvasLocation" x="182" y="760"/>
|
||||||
</window>
|
</window>
|
||||||
<window title="Printer Feed" allowsToolTipsWhenApplicationIsInactive="NO" autorecalculatesKeyViewLoop="NO" restorable="NO" hidesOnDeactivate="YES" releasedWhenClosed="NO" visibleAtLaunch="NO" animationBehavior="default" id="NdE-0B-WCf" customClass="NSPanel">
|
<window title="Printer" allowsToolTipsWhenApplicationIsInactive="NO" autorecalculatesKeyViewLoop="NO" restorable="NO" hidesOnDeactivate="YES" releasedWhenClosed="NO" visibleAtLaunch="NO" animationBehavior="default" id="NdE-0B-WCf" customClass="GBPanel">
|
||||||
<windowStyleMask key="styleMask" titled="YES" closable="YES" resizable="YES"/>
|
<windowStyleMask key="styleMask" titled="YES" closable="YES" resizable="YES"/>
|
||||||
<rect key="contentRect" x="0.0" y="0.0" width="320" height="288"/>
|
<rect key="contentRect" x="0.0" y="0.0" width="320" height="288"/>
|
||||||
<rect key="screenRect" x="0.0" y="0.0" width="2560" height="1415"/>
|
<rect key="screenRect" x="0.0" y="0.0" width="2560" height="1415"/>
|
||||||
|
@ -685,7 +728,7 @@
|
||||||
</imageView>
|
</imageView>
|
||||||
</subviews>
|
</subviews>
|
||||||
</view>
|
</view>
|
||||||
<toolbar key="toolbar" implicitIdentifier="1FF86A2B-6637-4EE6-A25A-7298D79AE84E" autosavesConfiguration="NO" allowsUserCustomization="NO" displayMode="iconAndLabel" sizeMode="regular" id="gH3-SH-7il">
|
<toolbar key="toolbar" implicitIdentifier="1FF86A2B-6637-4EE6-A25A-7298D79AE84E" autosavesConfiguration="NO" allowsUserCustomization="NO" showsBaselineSeparator="NO" displayMode="iconAndLabel" sizeMode="regular" id="gH3-SH-7il">
|
||||||
<allowedToolbarItems>
|
<allowedToolbarItems>
|
||||||
<toolbarItem implicitItemIdentifier="15EB8D49-8C6E-42F2-9F7F-F7D7A0BBDAAF" label="Save" paletteLabel="Save" tag="-1" image="NSFolder" id="CBz-1N-o0Q">
|
<toolbarItem implicitItemIdentifier="15EB8D49-8C6E-42F2-9F7F-F7D7A0BBDAAF" label="Save" paletteLabel="Save" tag="-1" image="NSFolder" id="CBz-1N-o0Q">
|
||||||
<size key="minSize" width="22" height="22"/>
|
<size key="minSize" width="22" height="22"/>
|
||||||
|
@ -717,168 +760,30 @@
|
||||||
<toolbarItem reference="L6N-6G-UWl"/>
|
<toolbarItem reference="L6N-6G-UWl"/>
|
||||||
</defaultToolbarItems>
|
</defaultToolbarItems>
|
||||||
</toolbar>
|
</toolbar>
|
||||||
|
<connections>
|
||||||
|
<outlet property="ownerWindow" destination="xOd-HO-29H" id="8Lk-t1-HNi"/>
|
||||||
|
</connections>
|
||||||
<point key="canvasLocation" x="-159" y="356"/>
|
<point key="canvasLocation" x="-159" y="356"/>
|
||||||
</window>
|
</window>
|
||||||
<window title="Cheats" allowsToolTipsWhenApplicationIsInactive="NO" autorecalculatesKeyViewLoop="NO" restorable="NO" releasedWhenClosed="NO" visibleAtLaunch="NO" frameAutosaveName="" animationBehavior="default" id="4Yb-Np-JrF" customClass="NSPanel">
|
<window title="Cheats" allowsToolTipsWhenApplicationIsInactive="NO" autorecalculatesKeyViewLoop="NO" restorable="NO" releasedWhenClosed="NO" visibleAtLaunch="NO" frameAutosaveName="" animationBehavior="default" id="4Yb-Np-JrF" customClass="GBPanel">
|
||||||
<windowStyleMask key="styleMask" titled="YES" closable="YES"/>
|
<windowStyleMask key="styleMask" titled="YES" closable="YES" miniaturizable="YES" resizable="YES"/>
|
||||||
<rect key="contentRect" x="0.0" y="0.0" width="692" height="272"/>
|
<rect key="contentRect" x="0.0" y="0.0" width="604" height="400"/>
|
||||||
<rect key="screenRect" x="0.0" y="0.0" width="2560" height="1415"/>
|
<rect key="screenRect" x="0.0" y="0.0" width="2560" height="1415"/>
|
||||||
|
<value key="minSize" type="size" width="604" height="400"/>
|
||||||
|
<value key="maxSize" type="size" width="604" height="99999"/>
|
||||||
<view key="contentView" id="gBP-5p-BTh">
|
<view key="contentView" id="gBP-5p-BTh">
|
||||||
<rect key="frame" x="0.0" y="0.0" width="692" height="272"/>
|
<rect key="frame" x="0.0" y="0.0" width="604" height="400"/>
|
||||||
<autoresizingMask key="autoresizingMask"/>
|
<autoresizingMask key="autoresizingMask"/>
|
||||||
<subviews>
|
<subviews>
|
||||||
<view id="fWr-0i-K1d" customClass="GBOptionalVisualEffectView">
|
<scrollView autohidesScrollers="YES" horizontalLineScroll="26" horizontalPageScroll="10" verticalLineScroll="26" verticalPageScroll="10" usesPredominantAxisScrolling="NO" id="6rU-Xg-KHc">
|
||||||
<rect key="frame" x="0.0" y="0.0" width="294" height="272"/>
|
<rect key="frame" x="-1" y="143" width="606" height="259"/>
|
||||||
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" heightSizable="YES"/>
|
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
|
||||||
<subviews>
|
|
||||||
<textField horizontalHuggingPriority="251" verticalHuggingPriority="750" id="hqi-ob-NW9">
|
|
||||||
<rect key="frame" x="16" y="174" width="154" height="19"/>
|
|
||||||
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMinY="YES"/>
|
|
||||||
<textFieldCell key="cell" lineBreakMode="clipping" title="To value:" id="Ycx-oE-aA4">
|
|
||||||
<font key="font" metaFont="system"/>
|
|
||||||
<color key="textColor" name="labelColor" catalog="System" colorSpace="catalog"/>
|
|
||||||
<color key="backgroundColor" name="textBackgroundColor" catalog="System" colorSpace="catalog"/>
|
|
||||||
</textFieldCell>
|
|
||||||
</textField>
|
|
||||||
<button verticalHuggingPriority="750" fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="Kq8-6F-9GK">
|
|
||||||
<rect key="frame" x="16" y="142" width="154" height="19"/>
|
|
||||||
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMinY="YES"/>
|
|
||||||
<buttonCell key="cell" type="check" title="Only if old value was: " bezelStyle="regularSquare" imagePosition="left" state="on" inset="2" id="LkB-WQ-9Qd">
|
|
||||||
<behavior key="behavior" changeContents="YES" doesNotDimImage="YES" lightByContents="YES"/>
|
|
||||||
<font key="font" metaFont="system"/>
|
|
||||||
</buttonCell>
|
|
||||||
<connections>
|
|
||||||
<action selector="updateCheat:" target="v7q-gT-jHT" id="kNc-cj-bmF"/>
|
|
||||||
</connections>
|
|
||||||
</button>
|
|
||||||
<box verticalHuggingPriority="750" boxType="separator" id="D6k-Pe-23u">
|
|
||||||
<rect key="frame" x="10" y="129" width="274" height="5"/>
|
|
||||||
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMinY="YES"/>
|
|
||||||
</box>
|
|
||||||
<textField horizontalHuggingPriority="251" verticalHuggingPriority="750" fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="r5T-ol-Dod">
|
|
||||||
<rect key="frame" x="16" y="107" width="270" height="16"/>
|
|
||||||
<autoresizingMask key="autoresizingMask" flexibleMinY="YES"/>
|
|
||||||
<textFieldCell key="cell" lineBreakMode="clipping" title="Import GameShark or GameGenie cheat:" id="0mf-EN-cKc">
|
|
||||||
<font key="font" metaFont="system"/>
|
|
||||||
<color key="textColor" name="labelColor" catalog="System" colorSpace="catalog"/>
|
|
||||||
<color key="backgroundColor" name="textBackgroundColor" catalog="System" colorSpace="catalog"/>
|
|
||||||
</textFieldCell>
|
|
||||||
</textField>
|
|
||||||
<textField focusRingType="none" verticalHuggingPriority="750" fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="X7K-nJ-alF">
|
|
||||||
<rect key="frame" x="39" y="78" width="233" height="21"/>
|
|
||||||
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMinY="YES"/>
|
|
||||||
<textFieldCell key="cell" scrollable="YES" lineBreakMode="clipping" selectable="YES" editable="YES" borderStyle="bezel" focusRingType="none" placeholderString="Code" drawsBackground="YES" usesSingleLineMode="YES" id="2bz-dT-7Fi">
|
|
||||||
<font key="font" metaFont="system"/>
|
|
||||||
<color key="textColor" name="controlTextColor" catalog="System" colorSpace="catalog"/>
|
|
||||||
<color key="backgroundColor" name="textBackgroundColor" catalog="System" colorSpace="catalog"/>
|
|
||||||
<allowedInputSourceLocales>
|
|
||||||
<string>NSAllRomanInputSourcesLocaleIdentifier</string>
|
|
||||||
</allowedInputSourceLocales>
|
|
||||||
</textFieldCell>
|
|
||||||
<connections>
|
|
||||||
<action selector="selectText:" target="KHj-uX-Wbk" id="11z-0U-tMA"/>
|
|
||||||
</connections>
|
|
||||||
</textField>
|
|
||||||
<textField focusRingType="none" verticalHuggingPriority="750" fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="KHj-uX-Wbk">
|
|
||||||
<rect key="frame" x="39" y="47" width="233" height="21"/>
|
|
||||||
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMinY="YES"/>
|
|
||||||
<textFieldCell key="cell" scrollable="YES" lineBreakMode="clipping" selectable="YES" editable="YES" borderStyle="bezel" focusRingType="none" placeholderString="Description" drawsBackground="YES" usesSingleLineMode="YES" id="50d-va-Cen">
|
|
||||||
<font key="font" metaFont="system"/>
|
|
||||||
<color key="textColor" name="controlTextColor" catalog="System" colorSpace="catalog"/>
|
|
||||||
<color key="backgroundColor" name="textBackgroundColor" catalog="System" colorSpace="catalog"/>
|
|
||||||
</textFieldCell>
|
|
||||||
<connections>
|
|
||||||
<action selector="performClick:" target="C3V-Ep-bMj" id="kIN-jl-A8d"/>
|
|
||||||
</connections>
|
|
||||||
</textField>
|
|
||||||
<textField focusRingType="none" verticalHuggingPriority="750" fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="C6E-oI-hDC">
|
|
||||||
<rect key="frame" x="20" y="233" width="252" height="21"/>
|
|
||||||
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMinY="YES"/>
|
|
||||||
<textFieldCell key="cell" scrollable="YES" lineBreakMode="clipping" selectable="YES" editable="YES" sendsActionOnEndEditing="YES" borderStyle="bezel" focusRingType="none" placeholderString="Description" drawsBackground="YES" usesSingleLineMode="YES" id="2uR-9N-hBb">
|
|
||||||
<font key="font" metaFont="system"/>
|
|
||||||
<color key="textColor" name="controlTextColor" catalog="System" colorSpace="catalog"/>
|
|
||||||
<color key="backgroundColor" name="textBackgroundColor" catalog="System" colorSpace="catalog"/>
|
|
||||||
</textFieldCell>
|
|
||||||
<connections>
|
|
||||||
<outlet property="delegate" destination="v7q-gT-jHT" id="zyw-h0-hRP"/>
|
|
||||||
</connections>
|
|
||||||
</textField>
|
|
||||||
<button verticalHuggingPriority="750" id="C3V-Ep-bMj">
|
|
||||||
<rect key="frame" x="203" y="12" width="83" height="23"/>
|
|
||||||
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMinY="YES"/>
|
|
||||||
<buttonCell key="cell" type="roundTextured" title="Import" bezelStyle="texturedRounded" alignment="center" borderStyle="border" imageScaling="proportionallyDown" inset="2" id="mMP-KW-YNy">
|
|
||||||
<behavior key="behavior" pushIn="YES" lightByBackground="YES" lightByGray="YES"/>
|
|
||||||
<font key="font" metaFont="system"/>
|
|
||||||
</buttonCell>
|
|
||||||
<connections>
|
|
||||||
<action selector="importCheat:" target="v7q-gT-jHT" id="lkX-N5-wD1"/>
|
|
||||||
</connections>
|
|
||||||
</button>
|
|
||||||
<textField focusRingType="none" verticalHuggingPriority="750" fixedFrame="YES" mirrorLayoutDirectionWhenInternationalizing="never" translatesAutoresizingMaskIntoConstraints="NO" id="qHx-1z-daR">
|
|
||||||
<rect key="frame" x="176" y="204" width="96" height="21"/>
|
|
||||||
<autoresizingMask key="autoresizingMask" widthSizable="YES" flexibleMaxY="YES"/>
|
|
||||||
<textFieldCell key="cell" scrollable="YES" lineBreakMode="clipping" selectable="YES" editable="YES" state="on" borderStyle="bezel" focusRingType="none" drawsBackground="YES" usesSingleLineMode="YES" id="edq-46-JeP" customClass="GBCheatTextFieldCell">
|
|
||||||
<font key="font" metaFont="system"/>
|
|
||||||
<color key="textColor" name="controlTextColor" catalog="System" colorSpace="catalog"/>
|
|
||||||
<color key="backgroundColor" name="textBackgroundColor" catalog="System" colorSpace="catalog"/>
|
|
||||||
<allowedInputSourceLocales>
|
|
||||||
<string>NSAllRomanInputSourcesLocaleIdentifier</string>
|
|
||||||
</allowedInputSourceLocales>
|
|
||||||
</textFieldCell>
|
|
||||||
<connections>
|
|
||||||
<outlet property="delegate" destination="v7q-gT-jHT" id="79v-33-R1X"/>
|
|
||||||
</connections>
|
|
||||||
</textField>
|
|
||||||
<textField focusRingType="none" verticalHuggingPriority="750" fixedFrame="YES" mirrorLayoutDirectionWhenInternationalizing="never" translatesAutoresizingMaskIntoConstraints="NO" id="N3I-PP-X85">
|
|
||||||
<rect key="frame" x="176" y="174" width="96" height="21"/>
|
|
||||||
<autoresizingMask key="autoresizingMask" widthSizable="YES" flexibleMaxY="YES"/>
|
|
||||||
<textFieldCell key="cell" scrollable="YES" lineBreakMode="clipping" selectable="YES" editable="YES" state="on" borderStyle="bezel" focusRingType="none" drawsBackground="YES" usesSingleLineMode="YES" id="CV2-D9-WsB" customClass="GBCheatTextFieldCell">
|
|
||||||
<font key="font" metaFont="system"/>
|
|
||||||
<color key="textColor" name="controlTextColor" catalog="System" colorSpace="catalog"/>
|
|
||||||
<color key="backgroundColor" name="textBackgroundColor" catalog="System" colorSpace="catalog"/>
|
|
||||||
<allowedInputSourceLocales>
|
|
||||||
<string>NSAllRomanInputSourcesLocaleIdentifier</string>
|
|
||||||
</allowedInputSourceLocales>
|
|
||||||
</textFieldCell>
|
|
||||||
<connections>
|
|
||||||
<outlet property="delegate" destination="v7q-gT-jHT" id="P69-nT-oOt"/>
|
|
||||||
</connections>
|
|
||||||
</textField>
|
|
||||||
<textField focusRingType="none" verticalHuggingPriority="750" fixedFrame="YES" mirrorLayoutDirectionWhenInternationalizing="never" translatesAutoresizingMaskIntoConstraints="NO" id="S6O-LB-gSj">
|
|
||||||
<rect key="frame" x="176" y="144" width="96" height="21"/>
|
|
||||||
<autoresizingMask key="autoresizingMask" widthSizable="YES" flexibleMaxY="YES"/>
|
|
||||||
<textFieldCell key="cell" scrollable="YES" lineBreakMode="clipping" selectable="YES" editable="YES" state="on" borderStyle="bezel" focusRingType="none" drawsBackground="YES" usesSingleLineMode="YES" id="tpM-ys-MEO" customClass="GBCheatTextFieldCell">
|
|
||||||
<font key="font" metaFont="system"/>
|
|
||||||
<color key="textColor" name="controlTextColor" catalog="System" colorSpace="catalog"/>
|
|
||||||
<color key="backgroundColor" name="textBackgroundColor" catalog="System" colorSpace="catalog"/>
|
|
||||||
<allowedInputSourceLocales>
|
|
||||||
<string>NSAllRomanInputSourcesLocaleIdentifier</string>
|
|
||||||
</allowedInputSourceLocales>
|
|
||||||
</textFieldCell>
|
|
||||||
<connections>
|
|
||||||
<outlet property="delegate" destination="v7q-gT-jHT" id="6RH-dg-SL7"/>
|
|
||||||
</connections>
|
|
||||||
</textField>
|
|
||||||
<textField horizontalHuggingPriority="251" verticalHuggingPriority="750" id="uFo-ly-Veq">
|
|
||||||
<rect key="frame" x="16" y="204" width="152" height="19"/>
|
|
||||||
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMinY="YES"/>
|
|
||||||
<textFieldCell key="cell" lineBreakMode="clipping" title="Change byte at address:" id="xwa-TF-eY1">
|
|
||||||
<font key="font" metaFont="system"/>
|
|
||||||
<color key="textColor" name="labelColor" catalog="System" colorSpace="catalog"/>
|
|
||||||
<color key="backgroundColor" name="textBackgroundColor" catalog="System" colorSpace="catalog"/>
|
|
||||||
</textFieldCell>
|
|
||||||
</textField>
|
|
||||||
</subviews>
|
|
||||||
</view>
|
|
||||||
<scrollView autohidesScrollers="YES" horizontalLineScroll="19" horizontalPageScroll="10" verticalLineScroll="19" verticalPageScroll="10" usesPredominantAxisScrolling="NO" id="6rU-Xg-KHc">
|
|
||||||
<rect key="frame" x="293" y="-1" width="400" height="275"/>
|
|
||||||
<autoresizingMask key="autoresizingMask" flexibleMinX="YES" heightSizable="YES"/>
|
|
||||||
<clipView key="contentView" id="mzf-yu-RID">
|
<clipView key="contentView" id="mzf-yu-RID">
|
||||||
<rect key="frame" x="1" y="1" width="398" height="273"/>
|
<rect key="frame" x="1" y="1" width="604" height="257"/>
|
||||||
<autoresizingMask key="autoresizingMask"/>
|
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
|
||||||
<subviews>
|
<subviews>
|
||||||
<tableView verticalHuggingPriority="750" allowsExpansionToolTips="YES" columnAutoresizingStyle="none" alternatingRowBackgroundColors="YES" columnReordering="NO" columnResizing="NO" multipleSelection="NO" emptySelection="NO" autosaveColumns="NO" typeSelect="NO" headerView="pvX-uJ-qK5" id="tA3-8T-bxb">
|
<tableView verticalHuggingPriority="750" allowsExpansionToolTips="YES" columnAutoresizingStyle="none" alternatingRowBackgroundColors="YES" columnReordering="NO" columnResizing="NO" multipleSelection="NO" emptySelection="NO" autosaveColumns="NO" typeSelect="NO" rowHeight="24" headerView="pvX-uJ-qK5" id="tA3-8T-bxb">
|
||||||
<rect key="frame" x="0.0" y="0.0" width="398" height="256"/>
|
<rect key="frame" x="0.0" y="0.0" width="604" height="240"/>
|
||||||
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
|
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
|
||||||
<size key="intercellSpacing" width="3" height="2"/>
|
<size key="intercellSpacing" width="3" height="2"/>
|
||||||
<color key="backgroundColor" name="controlBackgroundColor" catalog="System" colorSpace="catalog"/>
|
<color key="backgroundColor" name="controlBackgroundColor" catalog="System" colorSpace="catalog"/>
|
||||||
|
@ -889,13 +794,13 @@
|
||||||
<color key="textColor" name="headerTextColor" catalog="System" colorSpace="catalog"/>
|
<color key="textColor" name="headerTextColor" catalog="System" colorSpace="catalog"/>
|
||||||
<color key="backgroundColor" name="headerColor" catalog="System" colorSpace="catalog"/>
|
<color key="backgroundColor" name="headerColor" catalog="System" colorSpace="catalog"/>
|
||||||
</tableHeaderCell>
|
</tableHeaderCell>
|
||||||
<buttonCell key="dataCell" type="inline" bezelStyle="inline" image="NSStopProgressFreestandingTemplate" imagePosition="only" alignment="center" imageScaling="proportionallyDown" inset="2" id="5xh-hN-jHH">
|
<buttonCell key="dataCell" type="inline" bezelStyle="inline" image="NSStopProgressFreestandingTemplate" imagePosition="only" alignment="center" imageScaling="proportionallyDown" inset="2" id="5xh-hN-jHH" customClass="GBDeleteButtonCell">
|
||||||
<behavior key="behavior" pushIn="YES" lightByBackground="YES" lightByGray="YES"/>
|
<behavior key="behavior" pushIn="YES" lightByBackground="YES" lightByGray="YES"/>
|
||||||
<font key="font" metaFont="system"/>
|
<font key="font" metaFont="system"/>
|
||||||
</buttonCell>
|
</buttonCell>
|
||||||
<tableColumnResizingMask key="resizingMask" resizeWithTable="YES" userResizable="YES"/>
|
<tableColumnResizingMask key="resizingMask" resizeWithTable="YES" userResizable="YES"/>
|
||||||
</tableColumn>
|
</tableColumn>
|
||||||
<tableColumn width="40" minWidth="40" maxWidth="1000" id="9DZ-oW-Scx">
|
<tableColumn width="52" minWidth="52" maxWidth="1000" id="9DZ-oW-Scx">
|
||||||
<tableHeaderCell key="headerCell" lineBreakMode="truncatingTail" borderStyle="border" title="Enabled">
|
<tableHeaderCell key="headerCell" lineBreakMode="truncatingTail" borderStyle="border" title="Enabled">
|
||||||
<color key="textColor" name="headerTextColor" catalog="System" colorSpace="catalog"/>
|
<color key="textColor" name="headerTextColor" catalog="System" colorSpace="catalog"/>
|
||||||
<color key="backgroundColor" name="headerColor" catalog="System" colorSpace="catalog"/>
|
<color key="backgroundColor" name="headerColor" catalog="System" colorSpace="catalog"/>
|
||||||
|
@ -906,24 +811,24 @@
|
||||||
</buttonCell>
|
</buttonCell>
|
||||||
<tableColumnResizingMask key="resizingMask" resizeWithTable="YES" userResizable="YES"/>
|
<tableColumnResizingMask key="resizingMask" resizeWithTable="YES" userResizable="YES"/>
|
||||||
</tableColumn>
|
</tableColumn>
|
||||||
<tableColumn editable="NO" width="142" minWidth="40" maxWidth="1000" id="4Qa-FQ-QWY">
|
<tableColumn editable="NO" width="320" minWidth="320" maxWidth="1000" id="4Qa-FQ-QWY">
|
||||||
<tableHeaderCell key="headerCell" lineBreakMode="truncatingTail" borderStyle="border" title="Description">
|
<tableHeaderCell key="headerCell" lineBreakMode="truncatingTail" borderStyle="border" title="Description">
|
||||||
<color key="textColor" name="headerTextColor" catalog="System" colorSpace="catalog"/>
|
<color key="textColor" name="headerTextColor" catalog="System" colorSpace="catalog"/>
|
||||||
<color key="backgroundColor" name="headerColor" catalog="System" colorSpace="catalog"/>
|
<color key="backgroundColor" name="headerColor" catalog="System" colorSpace="catalog"/>
|
||||||
</tableHeaderCell>
|
</tableHeaderCell>
|
||||||
<textFieldCell key="dataCell" lineBreakMode="truncatingTail" selectable="YES" editable="YES" title="Description" id="1hX-Sr-bGz">
|
<textFieldCell key="dataCell" lineBreakMode="truncatingTail" selectable="YES" editable="YES" title="Description" id="1hX-Sr-bGz" customClass="GBCenteredTextCell">
|
||||||
<font key="font" metaFont="system"/>
|
<font key="font" metaFont="system"/>
|
||||||
<color key="textColor" name="controlTextColor" catalog="System" colorSpace="catalog"/>
|
<color key="textColor" name="controlTextColor" catalog="System" colorSpace="catalog"/>
|
||||||
<color key="backgroundColor" name="controlBackgroundColor" catalog="System" colorSpace="catalog"/>
|
<color key="backgroundColor" name="controlBackgroundColor" catalog="System" colorSpace="catalog"/>
|
||||||
</textFieldCell>
|
</textFieldCell>
|
||||||
<tableColumnResizingMask key="resizingMask" resizeWithTable="YES" userResizable="YES"/>
|
<tableColumnResizingMask key="resizingMask" resizeWithTable="YES" userResizable="YES"/>
|
||||||
</tableColumn>
|
</tableColumn>
|
||||||
<tableColumn editable="NO" width="134" minWidth="40" maxWidth="1000" id="ACq-gU-K36">
|
<tableColumn editable="NO" width="172" minWidth="172" maxWidth="1000" id="ACq-gU-K36">
|
||||||
<tableHeaderCell key="headerCell" lineBreakMode="truncatingTail" borderStyle="border" title="Action">
|
<tableHeaderCell key="headerCell" lineBreakMode="truncatingTail" borderStyle="border" title="Action">
|
||||||
<color key="textColor" name="headerTextColor" catalog="System" colorSpace="catalog"/>
|
<color key="textColor" name="headerTextColor" catalog="System" colorSpace="catalog"/>
|
||||||
<color key="backgroundColor" name="headerColor" catalog="System" colorSpace="catalog"/>
|
<color key="backgroundColor" name="headerColor" catalog="System" colorSpace="catalog"/>
|
||||||
</tableHeaderCell>
|
</tableHeaderCell>
|
||||||
<textFieldCell key="dataCell" lineBreakMode="truncatingTail" selectable="YES" editable="YES" title="Action" id="8Sq-h9-eV7">
|
<textFieldCell key="dataCell" lineBreakMode="truncatingTail" selectable="YES" editable="YES" title="Action" id="8Sq-h9-eV7" customClass="GBCenteredTextCell">
|
||||||
<font key="font" metaFont="fixedUser" size="11"/>
|
<font key="font" metaFont="fixedUser" size="11"/>
|
||||||
<color key="textColor" name="controlTextColor" catalog="System" colorSpace="catalog"/>
|
<color key="textColor" name="controlTextColor" catalog="System" colorSpace="catalog"/>
|
||||||
<color key="backgroundColor" name="controlBackgroundColor" catalog="System" colorSpace="catalog"/>
|
<color key="backgroundColor" name="controlBackgroundColor" catalog="System" colorSpace="catalog"/>
|
||||||
|
@ -939,7 +844,7 @@
|
||||||
</subviews>
|
</subviews>
|
||||||
</clipView>
|
</clipView>
|
||||||
<scroller key="horizontalScroller" hidden="YES" wantsLayer="YES" verticalHuggingPriority="750" horizontal="YES" id="3Hg-LL-VqH">
|
<scroller key="horizontalScroller" hidden="YES" wantsLayer="YES" verticalHuggingPriority="750" horizontal="YES" id="3Hg-LL-VqH">
|
||||||
<rect key="frame" x="1" y="119" width="223" height="15"/>
|
<rect key="frame" x="1" y="242" width="604" height="16"/>
|
||||||
<autoresizingMask key="autoresizingMask"/>
|
<autoresizingMask key="autoresizingMask"/>
|
||||||
</scroller>
|
</scroller>
|
||||||
<scroller key="verticalScroller" hidden="YES" wantsLayer="YES" verticalHuggingPriority="750" doubleValue="1" horizontal="NO" id="zET-KH-qF4">
|
<scroller key="verticalScroller" hidden="YES" wantsLayer="YES" verticalHuggingPriority="750" doubleValue="1" horizontal="NO" id="zET-KH-qF4">
|
||||||
|
@ -947,13 +852,159 @@
|
||||||
<autoresizingMask key="autoresizingMask"/>
|
<autoresizingMask key="autoresizingMask"/>
|
||||||
</scroller>
|
</scroller>
|
||||||
<tableHeaderView key="headerView" wantsLayer="YES" id="pvX-uJ-qK5">
|
<tableHeaderView key="headerView" wantsLayer="YES" id="pvX-uJ-qK5">
|
||||||
<rect key="frame" x="0.0" y="0.0" width="398" height="17"/>
|
<rect key="frame" x="0.0" y="0.0" width="604" height="17"/>
|
||||||
<autoresizingMask key="autoresizingMask"/>
|
<autoresizingMask key="autoresizingMask"/>
|
||||||
</tableHeaderView>
|
</tableHeaderView>
|
||||||
</scrollView>
|
</scrollView>
|
||||||
|
<customView fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="TFe-hA-XJc">
|
||||||
|
<rect key="frame" x="-1" y="0.0" width="308" height="135"/>
|
||||||
|
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMaxY="YES"/>
|
||||||
|
<subviews>
|
||||||
|
<textField focusRingType="none" horizontalHuggingPriority="251" verticalHuggingPriority="750" id="hqi-ob-NW9">
|
||||||
|
<rect key="frame" x="20" y="52" width="176" height="18"/>
|
||||||
|
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES"/>
|
||||||
|
<textFieldCell key="cell" lineBreakMode="clipping" alignment="right" title="To value:" id="Ycx-oE-aA4">
|
||||||
|
<font key="font" metaFont="system"/>
|
||||||
|
<color key="textColor" name="labelColor" catalog="System" colorSpace="catalog"/>
|
||||||
|
<color key="backgroundColor" name="textBackgroundColor" catalog="System" colorSpace="catalog"/>
|
||||||
|
</textFieldCell>
|
||||||
|
</textField>
|
||||||
|
<button verticalHuggingPriority="750" fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="Kq8-6F-9GK">
|
||||||
|
<rect key="frame" x="42" y="22" width="152" height="18"/>
|
||||||
|
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES"/>
|
||||||
|
<buttonCell key="cell" type="check" title="Only if old value was: " bezelStyle="regularSquare" imagePosition="left" alignment="right" state="on" inset="2" id="LkB-WQ-9Qd">
|
||||||
|
<behavior key="behavior" changeContents="YES" doesNotDimImage="YES" lightByContents="YES"/>
|
||||||
|
<font key="font" metaFont="system"/>
|
||||||
|
</buttonCell>
|
||||||
|
<connections>
|
||||||
|
<action selector="updateCheat:" target="v7q-gT-jHT" id="kNc-cj-bmF"/>
|
||||||
|
</connections>
|
||||||
|
</button>
|
||||||
|
<textField focusRingType="none" verticalHuggingPriority="750" fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="C6E-oI-hDC">
|
||||||
|
<rect key="frame" x="22" y="113" width="276" height="21"/>
|
||||||
|
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES"/>
|
||||||
|
<textFieldCell key="cell" scrollable="YES" lineBreakMode="clipping" selectable="YES" editable="YES" sendsActionOnEndEditing="YES" borderStyle="bezel" placeholderString="Description" drawsBackground="YES" usesSingleLineMode="YES" id="2uR-9N-hBb">
|
||||||
|
<font key="font" metaFont="system"/>
|
||||||
|
<color key="textColor" name="controlTextColor" catalog="System" colorSpace="catalog"/>
|
||||||
|
<color key="backgroundColor" name="textBackgroundColor" catalog="System" colorSpace="catalog"/>
|
||||||
|
</textFieldCell>
|
||||||
|
<connections>
|
||||||
|
<outlet property="delegate" destination="v7q-gT-jHT" id="zyw-h0-hRP"/>
|
||||||
|
</connections>
|
||||||
|
</textField>
|
||||||
|
<textField focusRingType="none" verticalHuggingPriority="750" fixedFrame="YES" mirrorLayoutDirectionWhenInternationalizing="never" translatesAutoresizingMaskIntoConstraints="NO" id="qHx-1z-daR">
|
||||||
|
<rect key="frame" x="202" y="82" width="96" height="21"/>
|
||||||
|
<autoresizingMask key="autoresizingMask" flexibleMaxY="YES"/>
|
||||||
|
<textFieldCell key="cell" scrollable="YES" lineBreakMode="clipping" selectable="YES" editable="YES" state="on" borderStyle="bezel" drawsBackground="YES" usesSingleLineMode="YES" id="edq-46-JeP" customClass="GBCheatTextFieldCell">
|
||||||
|
<font key="font" metaFont="system"/>
|
||||||
|
<color key="textColor" name="controlTextColor" catalog="System" colorSpace="catalog"/>
|
||||||
|
<color key="backgroundColor" name="textBackgroundColor" catalog="System" colorSpace="catalog"/>
|
||||||
|
<allowedInputSourceLocales>
|
||||||
|
<string>NSAllRomanInputSourcesLocaleIdentifier</string>
|
||||||
|
</allowedInputSourceLocales>
|
||||||
|
</textFieldCell>
|
||||||
|
<connections>
|
||||||
|
<outlet property="delegate" destination="v7q-gT-jHT" id="79v-33-R1X"/>
|
||||||
|
</connections>
|
||||||
|
</textField>
|
||||||
|
<textField focusRingType="none" verticalHuggingPriority="750" fixedFrame="YES" mirrorLayoutDirectionWhenInternationalizing="never" translatesAutoresizingMaskIntoConstraints="NO" id="N3I-PP-X85">
|
||||||
|
<rect key="frame" x="202" y="51" width="96" height="21"/>
|
||||||
|
<autoresizingMask key="autoresizingMask" flexibleMaxY="YES"/>
|
||||||
|
<textFieldCell key="cell" scrollable="YES" lineBreakMode="clipping" selectable="YES" editable="YES" state="on" borderStyle="bezel" drawsBackground="YES" usesSingleLineMode="YES" id="CV2-D9-WsB" customClass="GBCheatTextFieldCell">
|
||||||
|
<font key="font" metaFont="system"/>
|
||||||
|
<color key="textColor" name="controlTextColor" catalog="System" colorSpace="catalog"/>
|
||||||
|
<color key="backgroundColor" name="textBackgroundColor" catalog="System" colorSpace="catalog"/>
|
||||||
|
<allowedInputSourceLocales>
|
||||||
|
<string>NSAllRomanInputSourcesLocaleIdentifier</string>
|
||||||
|
</allowedInputSourceLocales>
|
||||||
|
</textFieldCell>
|
||||||
|
<connections>
|
||||||
|
<outlet property="delegate" destination="v7q-gT-jHT" id="P69-nT-oOt"/>
|
||||||
|
</connections>
|
||||||
|
</textField>
|
||||||
|
<textField focusRingType="none" verticalHuggingPriority="750" fixedFrame="YES" mirrorLayoutDirectionWhenInternationalizing="never" translatesAutoresizingMaskIntoConstraints="NO" id="S6O-LB-gSj">
|
||||||
|
<rect key="frame" x="202" y="20" width="96" height="21"/>
|
||||||
|
<autoresizingMask key="autoresizingMask" flexibleMaxY="YES"/>
|
||||||
|
<textFieldCell key="cell" scrollable="YES" lineBreakMode="clipping" selectable="YES" editable="YES" state="on" borderStyle="bezel" drawsBackground="YES" usesSingleLineMode="YES" id="tpM-ys-MEO" customClass="GBCheatTextFieldCell">
|
||||||
|
<font key="font" metaFont="system"/>
|
||||||
|
<color key="textColor" name="controlTextColor" catalog="System" colorSpace="catalog"/>
|
||||||
|
<color key="backgroundColor" name="textBackgroundColor" catalog="System" colorSpace="catalog"/>
|
||||||
|
<allowedInputSourceLocales>
|
||||||
|
<string>NSAllRomanInputSourcesLocaleIdentifier</string>
|
||||||
|
</allowedInputSourceLocales>
|
||||||
|
</textFieldCell>
|
||||||
|
<connections>
|
||||||
|
<outlet property="delegate" destination="v7q-gT-jHT" id="6RH-dg-SL7"/>
|
||||||
|
</connections>
|
||||||
|
</textField>
|
||||||
|
<textField focusRingType="none" horizontalHuggingPriority="251" verticalHuggingPriority="750" id="uFo-ly-Veq">
|
||||||
|
<rect key="frame" x="18" y="83" width="178" height="18"/>
|
||||||
|
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES"/>
|
||||||
|
<textFieldCell key="cell" lineBreakMode="clipping" alignment="right" title="Change byte at address:" id="xwa-TF-eY1">
|
||||||
|
<font key="font" metaFont="system"/>
|
||||||
|
<color key="textColor" name="labelColor" catalog="System" colorSpace="catalog"/>
|
||||||
|
<color key="backgroundColor" name="textBackgroundColor" catalog="System" colorSpace="catalog"/>
|
||||||
|
</textFieldCell>
|
||||||
|
</textField>
|
||||||
|
</subviews>
|
||||||
|
</customView>
|
||||||
|
<textField focusRingType="none" horizontalHuggingPriority="251" verticalHuggingPriority="750" fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="r5T-ol-Dod">
|
||||||
|
<rect key="frame" x="316" y="116" width="270" height="16"/>
|
||||||
|
<autoresizingMask key="autoresizingMask" flexibleMinX="YES"/>
|
||||||
|
<textFieldCell key="cell" lineBreakMode="clipping" title="Import GameShark or Game Genie cheat:" id="0mf-EN-cKc">
|
||||||
|
<font key="font" metaFont="system"/>
|
||||||
|
<color key="textColor" name="labelColor" catalog="System" colorSpace="catalog"/>
|
||||||
|
<color key="backgroundColor" name="textBackgroundColor" catalog="System" colorSpace="catalog"/>
|
||||||
|
</textFieldCell>
|
||||||
|
</textField>
|
||||||
|
<textField focusRingType="none" verticalHuggingPriority="750" fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="X7K-nJ-alF">
|
||||||
|
<rect key="frame" x="351" y="82" width="233" height="21"/>
|
||||||
|
<autoresizingMask key="autoresizingMask" flexibleMinX="YES"/>
|
||||||
|
<textFieldCell key="cell" scrollable="YES" lineBreakMode="clipping" selectable="YES" editable="YES" borderStyle="bezel" placeholderString="Code" drawsBackground="YES" usesSingleLineMode="YES" id="2bz-dT-7Fi">
|
||||||
|
<font key="font" metaFont="system"/>
|
||||||
|
<color key="textColor" name="controlTextColor" catalog="System" colorSpace="catalog"/>
|
||||||
|
<color key="backgroundColor" name="textBackgroundColor" catalog="System" colorSpace="catalog"/>
|
||||||
|
<allowedInputSourceLocales>
|
||||||
|
<string>NSAllRomanInputSourcesLocaleIdentifier</string>
|
||||||
|
</allowedInputSourceLocales>
|
||||||
|
</textFieldCell>
|
||||||
|
<connections>
|
||||||
|
<action selector="selectText:" target="KHj-uX-Wbk" id="11z-0U-tMA"/>
|
||||||
|
</connections>
|
||||||
|
</textField>
|
||||||
|
<textField focusRingType="none" verticalHuggingPriority="750" fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="KHj-uX-Wbk">
|
||||||
|
<rect key="frame" x="351" y="51" width="233" height="21"/>
|
||||||
|
<autoresizingMask key="autoresizingMask" flexibleMinX="YES"/>
|
||||||
|
<textFieldCell key="cell" scrollable="YES" lineBreakMode="clipping" selectable="YES" editable="YES" borderStyle="bezel" placeholderString="Description" drawsBackground="YES" usesSingleLineMode="YES" id="50d-va-Cen">
|
||||||
|
<font key="font" metaFont="system"/>
|
||||||
|
<color key="textColor" name="controlTextColor" catalog="System" colorSpace="catalog"/>
|
||||||
|
<color key="backgroundColor" name="textBackgroundColor" catalog="System" colorSpace="catalog"/>
|
||||||
|
</textFieldCell>
|
||||||
|
<connections>
|
||||||
|
<action selector="performClick:" target="C3V-Ep-bMj" id="kIN-jl-A8d"/>
|
||||||
|
</connections>
|
||||||
|
</textField>
|
||||||
|
<button verticalHuggingPriority="750" id="C3V-Ep-bMj">
|
||||||
|
<rect key="frame" x="508" y="13" width="83" height="32"/>
|
||||||
|
<autoresizingMask key="autoresizingMask" flexibleMinX="YES"/>
|
||||||
|
<buttonCell key="cell" type="push" title="Import" bezelStyle="rounded" alignment="center" borderStyle="border" imageScaling="proportionallyDown" inset="2" id="mMP-KW-YNy">
|
||||||
|
<behavior key="behavior" pushIn="YES" lightByBackground="YES" lightByGray="YES"/>
|
||||||
|
<font key="font" metaFont="system"/>
|
||||||
|
</buttonCell>
|
||||||
|
<connections>
|
||||||
|
<action selector="importCheat:" target="v7q-gT-jHT" id="lkX-N5-wD1"/>
|
||||||
|
</connections>
|
||||||
|
</button>
|
||||||
|
<box horizontalHuggingPriority="750" fixedFrame="YES" boxType="separator" translatesAutoresizingMaskIntoConstraints="NO" id="P90-u5-8ko">
|
||||||
|
<rect key="frame" x="302" y="12" width="5" height="123"/>
|
||||||
|
<autoresizingMask key="autoresizingMask" flexibleMinX="YES" flexibleMaxX="YES" flexibleMaxY="YES"/>
|
||||||
|
</box>
|
||||||
</subviews>
|
</subviews>
|
||||||
</view>
|
</view>
|
||||||
<point key="canvasLocation" x="254" y="-463"/>
|
<connections>
|
||||||
|
<outlet property="ownerWindow" destination="xOd-HO-29H" id="ZQr-6h-iby"/>
|
||||||
|
</connections>
|
||||||
|
<point key="canvasLocation" x="210" y="-399"/>
|
||||||
</window>
|
</window>
|
||||||
<customObject id="v7q-gT-jHT" customClass="GBCheatWindowController">
|
<customObject id="v7q-gT-jHT" customClass="GBCheatWindowController">
|
||||||
<connections>
|
<connections>
|
||||||
|
@ -975,7 +1026,7 @@
|
||||||
<image name="HelpTemplate" width="14" height="14"/>
|
<image name="HelpTemplate" width="14" height="14"/>
|
||||||
<image name="InterruptTemplate" width="14" height="14"/>
|
<image name="InterruptTemplate" width="14" height="14"/>
|
||||||
<image name="NSFolder" width="32" height="32"/>
|
<image name="NSFolder" width="32" height="32"/>
|
||||||
<image name="NSStopProgressFreestandingTemplate" width="15" height="15"/>
|
<image name="NSStopProgressFreestandingTemplate" width="20" height="20"/>
|
||||||
<image name="NextTemplate" width="14" height="14"/>
|
<image name="NextTemplate" width="14" height="14"/>
|
||||||
<image name="StepTemplate" width="14" height="14"/>
|
<image name="StepTemplate" width="14" height="14"/>
|
||||||
<image name="printer" catalog="system" width="18" height="16"/>
|
<image name="printer" catalog="system" width="18" height="16"/>
|
||||||
|
|
|
@ -22,5 +22,6 @@
|
||||||
@property (strong) IBOutlet NSButton *updateProgressButton;
|
@property (strong) IBOutlet NSButton *updateProgressButton;
|
||||||
@property (strong) IBOutlet NSWindow *updateProgressWindow;
|
@property (strong) IBOutlet NSWindow *updateProgressWindow;
|
||||||
@property (strong) IBOutlet NSProgressIndicator *updateProgressSpinner;
|
@property (strong) IBOutlet NSProgressIndicator *updateProgressSpinner;
|
||||||
|
- (void)updateThemesDefault:(bool)overwrite;
|
||||||
@end
|
@end
|
||||||
|
|
||||||
|
|
159
Cocoa/GBApp.m
|
@ -8,9 +8,15 @@
|
||||||
#import <JoyKit/JoyKit.h>
|
#import <JoyKit/JoyKit.h>
|
||||||
#import <WebKit/WebKit.h>
|
#import <WebKit/WebKit.h>
|
||||||
#import <mach-o/dyld.h>
|
#import <mach-o/dyld.h>
|
||||||
|
#include <sys/mount.h>
|
||||||
|
#include <sys/xattr.h>
|
||||||
|
|
||||||
#define UPDATE_SERVER "https://sameboy.github.io"
|
#define UPDATE_SERVER "https://sameboy.github.io"
|
||||||
|
|
||||||
|
@interface NSToolbarItem(private)
|
||||||
|
- (NSButton *)_view;
|
||||||
|
@end
|
||||||
|
|
||||||
static uint32_t color_to_int(NSColor *color)
|
static uint32_t color_to_int(NSColor *color)
|
||||||
{
|
{
|
||||||
color = [color colorUsingColorSpace:[NSColorSpace deviceRGBColorSpace]];
|
color = [color colorUsingColorSpace:[NSColorSpace deviceRGBColorSpace]];
|
||||||
|
@ -40,14 +46,26 @@ static uint32_t color_to_int(NSColor *color)
|
||||||
- (void) applicationDidFinishLaunching:(NSNotification *)notification
|
- (void) applicationDidFinishLaunching:(NSNotification *)notification
|
||||||
{
|
{
|
||||||
// Refresh icon if launched via a software update
|
// Refresh icon if launched via a software update
|
||||||
[NSApplication sharedApplication].applicationIconImage = [NSImage imageNamed:@"AppIcon"];
|
if (@available(macOS 26.0, *)) {
|
||||||
|
// Severely broken on macOS 26
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
NSImage *icon = [[NSWorkspace sharedWorkspace] iconForFile:[[NSBundle mainBundle] bundlePath]];
|
||||||
|
icon.size = [NSApplication sharedApplication].applicationIconImage.size;
|
||||||
|
[NSApplication sharedApplication].applicationIconImage = icon;
|
||||||
|
}
|
||||||
|
|
||||||
NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];
|
NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];
|
||||||
for (unsigned i = 0; i < GBButtonCount; i++) {
|
for (unsigned i = 0; i < GBKeyboardButtonCount; i++) {
|
||||||
if ([[defaults objectForKey:button_to_preference_name(i, 0)] isKindOfClass:[NSString class]]) {
|
if ([[defaults objectForKey:button_to_preference_name(i, 0)] isKindOfClass:[NSString class]]) {
|
||||||
[defaults removeObjectForKey:button_to_preference_name(i, 0)];
|
[defaults removeObjectForKey:button_to_preference_name(i, 0)];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool hasSFMono = false;
|
||||||
|
if (@available(macOS 10.15, *)) {
|
||||||
|
hasSFMono = [[NSFont monospacedSystemFontOfSize:12 weight:NSFontWeightRegular].displayName containsString:@"SF"];
|
||||||
|
}
|
||||||
[[NSUserDefaults standardUserDefaults] registerDefaults:@{
|
[[NSUserDefaults standardUserDefaults] registerDefaults:@{
|
||||||
@"GBRight": @(kVK_RightArrow),
|
@"GBRight": @(kVK_RightArrow),
|
||||||
@"GBLeft": @(kVK_LeftArrow),
|
@"GBLeft": @(kVK_LeftArrow),
|
||||||
|
@ -83,8 +101,24 @@ static uint32_t color_to_int(NSColor *color)
|
||||||
@"GBJoyConAutoPair": @YES,
|
@"GBJoyConAutoPair": @YES,
|
||||||
@"GBJoyConsDefaultsToHorizontal": @YES,
|
@"GBJoyConsDefaultsToHorizontal": @YES,
|
||||||
|
|
||||||
|
@"GBEmulatedModel": @(MODEL_AUTO),
|
||||||
|
|
||||||
|
@"GBDebuggerFont": hasSFMono? @"SF Mono" : @"Menlo",
|
||||||
|
@"GBDebuggerFontSize": @12,
|
||||||
|
|
||||||
|
@"GBColorPalette": @1,
|
||||||
|
@"GBTurboCap": @0,
|
||||||
|
|
||||||
// Default themes
|
// Default themes
|
||||||
@"GBThemes": @{
|
@"GBThemes": @{
|
||||||
|
@"Canyon": @{
|
||||||
|
@"BrightnessBias": @0.1227009965823247,
|
||||||
|
@"Colors": @[@0xff0c1e20, @0xff122b91, @0xff466aa2, @0xfff1efae, @0xfff1efae],
|
||||||
|
@"DisabledLCDColor": @NO,
|
||||||
|
@"HueBias": @0.01782661816105247,
|
||||||
|
@"HueBiasStrength": @1,
|
||||||
|
@"Manual": @NO,
|
||||||
|
},
|
||||||
@"Desert": @{
|
@"Desert": @{
|
||||||
@"BrightnessBias": @0.0,
|
@"BrightnessBias": @0.0,
|
||||||
@"Colors": @[@0xff302f3e, @0xff576674, @0xff839ba4, @0xffb1d0d2, @0xffb7d7d8],
|
@"Colors": @[@0xff302f3e, @0xff576674, @0xff839ba4, @0xffb1d0d2, @0xffb7d7d8],
|
||||||
|
@ -109,6 +143,30 @@ static uint32_t color_to_int(NSColor *color)
|
||||||
@"HueBiasStrength": @0.18424738545816732,
|
@"HueBiasStrength": @0.18424738545816732,
|
||||||
@"Manual": @NO,
|
@"Manual": @NO,
|
||||||
},
|
},
|
||||||
|
@"Green Slate": @{
|
||||||
|
@"BrightnessBias": @0.2210012227296829,
|
||||||
|
@"Colors": @[@0xff343117, @0xff6a876f, @0xff98b4a1, @0xffc3daca, @0xffc8decf],
|
||||||
|
@"DisabledLCDColor": @YES,
|
||||||
|
@"HueBias": @0.1887667975388467,
|
||||||
|
@"HueBiasStrength": @0.1272283345460892,
|
||||||
|
@"Manual": @NO,
|
||||||
|
},
|
||||||
|
@"Green Tea": @{
|
||||||
|
@"BrightnessBias": @-0.4946326622596153,
|
||||||
|
@"Colors": @[@0xff1a1d08, @0xff1d5231, @0xff3b9774, @0xff97e4c6, @0xffa9eed1],
|
||||||
|
@"DisabledLCDColor": @YES,
|
||||||
|
@"HueBias": @0.1912955007245464,
|
||||||
|
@"HueBiasStrength": @0.3621708039314516,
|
||||||
|
@"Manual": @NO,
|
||||||
|
},
|
||||||
|
@"Lavender": @{
|
||||||
|
@"BrightnessBias": @0.10072476038566,
|
||||||
|
@"Colors": @[@0xff2b2a3a, @0xff8c507c, @0xffbf82a8, @0xffe9bcce, @0xffeec3d3],
|
||||||
|
@"DisabledLCDColor": @YES,
|
||||||
|
@"HueBias": @0.7914529587142169,
|
||||||
|
@"HueBiasStrength": @0.2498168498277664,
|
||||||
|
@"Manual": @NO,
|
||||||
|
},
|
||||||
@"Magic Eggplant": @{
|
@"Magic Eggplant": @{
|
||||||
@"BrightnessBias": @0.0,
|
@"BrightnessBias": @0.0,
|
||||||
@"Colors": @[@0xff3c2136, @0xff942e84, @0xffc7699d, @0xfff1e4b0, @0xfff6f9b2],
|
@"Colors": @[@0xff3c2136, @0xff942e84, @0xffc7699d, @0xfff1e4b0, @0xfff6f9b2],
|
||||||
|
@ -117,6 +175,22 @@ static uint32_t color_to_int(NSColor *color)
|
||||||
@"HueBiasStrength": @0.65018052788844627,
|
@"HueBiasStrength": @0.65018052788844627,
|
||||||
@"Manual": @NO,
|
@"Manual": @NO,
|
||||||
},
|
},
|
||||||
|
@"Mystic Blue": @{
|
||||||
|
@"BrightnessBias": @-0.3291049897670746,
|
||||||
|
@"Colors": @[@0xff3b2306, @0xffa27807, @0xffd1b523, @0xfff6ebbe, @0xfffaf1e4],
|
||||||
|
@"DisabledLCDColor": @YES,
|
||||||
|
@"HueBias": @0.5282051088288426,
|
||||||
|
@"HueBiasStrength": @0.7699633836746216,
|
||||||
|
@"Manual": @NO,
|
||||||
|
},
|
||||||
|
@"Pink Pop": @{
|
||||||
|
@"BrightnessBias": @0.624908447265625,
|
||||||
|
@"Colors": @[@0xff28140a, @0xff7c42cb, @0xffaa83de, @0xffd1ceeb, @0xffd5d8ec],
|
||||||
|
@"DisabledLCDColor": @YES,
|
||||||
|
@"HueBias": @0.9477411056868732,
|
||||||
|
@"HueBiasStrength": @0.80024421215057373,
|
||||||
|
@"Manual": @NO,
|
||||||
|
},
|
||||||
@"Radioactive Pea": @{
|
@"Radioactive Pea": @{
|
||||||
@"BrightnessBias": @-0.48079556772908372,
|
@"BrightnessBias": @-0.48079556772908372,
|
||||||
@"Colors": @[@0xff215200, @0xff1f7306, @0xff169e34, @0xff03ceb8, @0xff00d4d1],
|
@"Colors": @[@0xff215200, @0xff1f7306, @0xff169e34, @0xff03ceb8, @0xff00d4d1],
|
||||||
|
@ -125,6 +199,14 @@ static uint32_t color_to_int(NSColor *color)
|
||||||
@"HueBiasStrength": @0.34337649402390436,
|
@"HueBiasStrength": @0.34337649402390436,
|
||||||
@"Manual": @NO,
|
@"Manual": @NO,
|
||||||
},
|
},
|
||||||
|
@"Rose": @{
|
||||||
|
@"BrightnessBias": @0.2727272808551788,
|
||||||
|
@"Colors": @[@0xff001500, @0xff4e1fae, @0xff865ac4, @0xffb7e6d3, @0xffbdffd4],
|
||||||
|
@"DisabledLCDColor": @YES,
|
||||||
|
@"HueBias": @0.9238900924101472,
|
||||||
|
@"HueBiasStrength": @0.9957716464996338,
|
||||||
|
@"Manual": @NO,
|
||||||
|
},
|
||||||
@"Seaweed": @{
|
@"Seaweed": @{
|
||||||
@"BrightnessBias": @-0.28532744023904377,
|
@"BrightnessBias": @-0.28532744023904377,
|
||||||
@"Colors": @[@0xff3f0015, @0xff426532, @0xff58a778, @0xff95e0df, @0xffa0e7ee],
|
@"Colors": @[@0xff3f0015, @0xff426532, @0xff58a778, @0xff95e0df, @0xffa0e7ee],
|
||||||
|
@ -169,6 +251,31 @@ static uint32_t color_to_int(NSColor *color)
|
||||||
if ([[NSProcessInfo processInfo].arguments containsObject:@"--update-launch"]) {
|
if ([[NSProcessInfo processInfo].arguments containsObject:@"--update-launch"]) {
|
||||||
[NSApp activateIgnoringOtherApps:true];
|
[NSApp activateIgnoringOtherApps:true];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (![[[NSUserDefaults standardUserDefaults] stringForKey:@"GBThemesVersion"] isEqualToString:@(GB_VERSION)]) {
|
||||||
|
[self updateThemesDefault:false];
|
||||||
|
[[NSUserDefaults standardUserDefaults] setObject:@(GB_VERSION) forKey:@"GBThemesVersion"];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
- (void)updateThemesDefault:(bool)overwrite
|
||||||
|
{
|
||||||
|
NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];
|
||||||
|
NSMutableDictionary *currentThemes = [defaults dictionaryForKey:@"GBThemes"].mutableCopy;
|
||||||
|
[defaults removeObjectForKey:@"GBThemes"];
|
||||||
|
NSMutableDictionary *defaultThemes = [defaults dictionaryForKey:@"GBThemes"].mutableCopy;
|
||||||
|
if (![[NSUserDefaults standardUserDefaults] stringForKey:@"GBThemesVersion"]) {
|
||||||
|
// Force update the Pink Pop theme, it was glitchy in 1.0
|
||||||
|
[currentThemes removeObjectForKey:@"Pink Pop"];
|
||||||
|
}
|
||||||
|
if (overwrite) {
|
||||||
|
[currentThemes addEntriesFromDictionary:defaultThemes];
|
||||||
|
[defaults setObject:currentThemes forKey:@"GBThemes"];
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
[defaultThemes addEntriesFromDictionary:currentThemes];
|
||||||
|
[defaults setObject:defaultThemes forKey:@"GBThemes"];
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
- (IBAction)toggleDeveloperMode:(id)sender
|
- (IBAction)toggleDeveloperMode:(id)sender
|
||||||
|
@ -216,7 +323,10 @@ static uint32_t color_to_int(NSColor *color)
|
||||||
[item.image setSize:NSMakeSize(16, 16)];
|
[item.image setSize:NSMakeSize(16, 16)];
|
||||||
[items addObject:item];
|
[items addObject:item];
|
||||||
}
|
}
|
||||||
menu.itemArray = items;
|
[menu removeAllItems];
|
||||||
|
for (NSMenuItem *item in items) {
|
||||||
|
[menu addItem:item];
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
- (IBAction) showPreferences: (id) sender
|
- (IBAction) showPreferences: (id) sender
|
||||||
|
@ -232,9 +342,8 @@ static uint32_t color_to_int(NSColor *color)
|
||||||
#ifndef UPDATE_SUPPORT
|
#ifndef UPDATE_SUPPORT
|
||||||
[_preferencesWindow.toolbar removeItemAtIndex:4];
|
[_preferencesWindow.toolbar removeItemAtIndex:4];
|
||||||
#endif
|
#endif
|
||||||
if (@available(macOS 11.0, *)) {
|
for (unsigned i = _preferencesWindow.toolbar.items.count; i--;) {
|
||||||
[_preferencesWindow.toolbar insertItemWithItemIdentifier:NSToolbarFlexibleSpaceItemIdentifier atIndex:0];
|
[_preferencesWindow.toolbar.items[i] _view].imageScaling = NSImageScaleNone;
|
||||||
[_preferencesWindow.toolbar insertItemWithItemIdentifier:NSToolbarFlexibleSpaceItemIdentifier atIndex:_preferencesWindow.toolbar.items.count];
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
[_preferencesWindow makeKeyAndOrderFront:self];
|
[_preferencesWindow makeKeyAndOrderFront:self];
|
||||||
|
@ -294,7 +403,12 @@ static uint32_t color_to_int(NSColor *color)
|
||||||
else {
|
else {
|
||||||
self.updateChanges.preferences.standardFontFamily = @"Lucida Grande";
|
self.updateChanges.preferences.standardFontFamily = @"Lucida Grande";
|
||||||
}
|
}
|
||||||
self.updateChanges.preferences.fixedFontFamily = @"Menlo";
|
if (@available(macOS 10.15, *)) {
|
||||||
|
self.updateChanges.preferences.fixedFontFamily = [NSFont monospacedSystemFontOfSize:12 weight:NSFontWeightRegular].displayName;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
self.updateChanges.preferences.fixedFontFamily = @"Menlo";
|
||||||
|
}
|
||||||
self.updateChanges.drawsBackground = false;
|
self.updateChanges.drawsBackground = false;
|
||||||
[self.updateChanges.mainFrame loadHTMLString:html baseURL:nil];
|
[self.updateChanges.mainFrame loadHTMLString:html baseURL:nil];
|
||||||
});
|
});
|
||||||
|
@ -550,6 +664,14 @@ static uint32_t color_to_int(NSColor *color)
|
||||||
}
|
}
|
||||||
[[NSFileManager defaultManager] removeItemAtPath:_downloadDirectory error:nil];
|
[[NSFileManager defaultManager] removeItemAtPath:_downloadDirectory error:nil];
|
||||||
[[NSFileManager defaultManager] removeItemAtPath:contentsTempPath error:nil];
|
[[NSFileManager defaultManager] removeItemAtPath:contentsTempPath error:nil];
|
||||||
|
|
||||||
|
// Remove the quarantine flag so we don't have to escape translocation
|
||||||
|
NSString *bundlePath = [NSBundle mainBundle].bundlePath;
|
||||||
|
removexattr(bundlePath.UTF8String, "com.apple.quarantine", 0);
|
||||||
|
for (NSString *path in [[NSFileManager defaultManager] enumeratorAtPath:bundlePath]) {
|
||||||
|
removexattr([bundlePath stringByAppendingPathComponent:path].UTF8String, "com.apple.quarantine", 0);
|
||||||
|
};
|
||||||
|
|
||||||
_downloadDirectory = nil;
|
_downloadDirectory = nil;
|
||||||
atexit_b(^{
|
atexit_b(^{
|
||||||
execl(executablePath.UTF8String, executablePath.UTF8String, "--update-launch", NULL);
|
execl(executablePath.UTF8String, executablePath.UTF8String, "--update-launch", NULL);
|
||||||
|
@ -669,4 +791,27 @@ static uint32_t color_to_int(NSColor *color)
|
||||||
- (IBAction)nop:(id)sender
|
- (IBAction)nop:(id)sender
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* This runs before C constructors. If we need to escape translocation, we should
|
||||||
|
do it ASAP to minimize our launch time. */
|
||||||
|
|
||||||
|
+ (void)load
|
||||||
|
{
|
||||||
|
if (@available(macOS 10.12, *)) {
|
||||||
|
/* Detect and escape translocation so we can safely update ourselves */
|
||||||
|
if ([[[NSBundle mainBundle] bundlePath] containsString:@"/AppTranslocation/"]) {
|
||||||
|
const char *mountPath = [[[[NSBundle mainBundle] bundlePath] stringByDeletingLastPathComponent] stringByDeletingLastPathComponent].UTF8String;
|
||||||
|
struct statfs *mntbuf;
|
||||||
|
int mntsize = getmntinfo(&mntbuf, MNT_NOWAIT);
|
||||||
|
for (unsigned i = 0; i < mntsize; i++) {
|
||||||
|
if (strcmp(mntbuf[i].f_mntonname, mountPath) == 0) {
|
||||||
|
NSBundle *origBundle = [NSBundle bundleWithPath:@(mntbuf[i].f_mntfromname)];
|
||||||
|
|
||||||
|
execl(origBundle.executablePath.UTF8String, origBundle.executablePath.UTF8String, NULL);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@end
|
@end
|
||||||
|
|
|
@ -7,20 +7,24 @@ typedef enum {
|
||||||
GBB,
|
GBB,
|
||||||
GBSelect,
|
GBSelect,
|
||||||
GBStart,
|
GBStart,
|
||||||
|
GBRapidA,
|
||||||
|
GBRapidB,
|
||||||
GBTurbo,
|
GBTurbo,
|
||||||
GBRewind,
|
GBRewind,
|
||||||
GBUnderclock,
|
GBUnderclock,
|
||||||
GBHotkey1,
|
GBHotkey1,
|
||||||
GBHotkey2,
|
GBHotkey2,
|
||||||
GBJoypadButtonCount,
|
GBTotalButtonCount,
|
||||||
GBButtonCount = GBUnderclock + 1,
|
GBKeyboardButtonCount = GBUnderclock + 1,
|
||||||
GBGameBoyButtonCount = GBStart + 1,
|
GBPerPlayerButtonCount = GBRapidB + 1,
|
||||||
} GBButton;
|
} GBButton;
|
||||||
|
|
||||||
#define GBJoyKitHotkey1 JOYButtonUsageGeneric0 + 0x100
|
#define GBJoyKitHotkey1 JOYButtonUsageGeneric0 + 0x100
|
||||||
#define GBJoyKitHotkey2 JOYButtonUsageGeneric0 + 0x101
|
#define GBJoyKitHotkey2 JOYButtonUsageGeneric0 + 0x101
|
||||||
|
#define GBJoyKitRapidA JOYButtonUsageGeneric0 + 0x102
|
||||||
|
#define GBJoyKitRapidB JOYButtonUsageGeneric0 + 0x103
|
||||||
|
|
||||||
extern NSString const *GBButtonNames[GBJoypadButtonCount];
|
extern NSString const *GBButtonNames[GBTotalButtonCount];
|
||||||
|
|
||||||
static inline NSString *n2s(uint64_t number)
|
static inline NSString *n2s(uint64_t number)
|
||||||
{
|
{
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
#import <Foundation/Foundation.h>
|
#import <Foundation/Foundation.h>
|
||||||
#import "GBButtons.h"
|
#import "GBButtons.h"
|
||||||
|
|
||||||
NSString const *GBButtonNames[] = {@"Right", @"Left", @"Up", @"Down", @"A", @"B", @"Select", @"Start", @"Turbo", @"Rewind", @"Slow-Motion", @"Hotkey 1", @"Hotkey 2"};
|
NSString const *GBButtonNames[] = {@"Right", @"Left", @"Up", @"Down", @"A", @"B", @"Select", @"Start", @"Rapid A", @"Rapid B", @"Turbo", @"Rewind", @"Slow-Motion", @"Hotkey 1", @"Hotkey 2"};
|
||||||
|
|
|
@ -0,0 +1,5 @@
|
||||||
|
#import <Cocoa/Cocoa.h>
|
||||||
|
|
||||||
|
@interface GBCPUView : NSView
|
||||||
|
- (void)addSample:(double)sample;
|
||||||
|
@end
|
|
@ -0,0 +1,126 @@
|
||||||
|
#import "GBCPUView.h"
|
||||||
|
|
||||||
|
#define SAMPLE_COUNT 0x100 // ~4 seconds
|
||||||
|
|
||||||
|
@implementation GBCPUView
|
||||||
|
{
|
||||||
|
double _samples[SAMPLE_COUNT];
|
||||||
|
size_t _position;
|
||||||
|
}
|
||||||
|
|
||||||
|
- (void)drawRect:(NSRect)dirtyRect
|
||||||
|
{
|
||||||
|
CGRect bounds = self.bounds;
|
||||||
|
NSSize size = bounds.size;
|
||||||
|
unsigned factor = [[self.window screen] backingScaleFactor];
|
||||||
|
|
||||||
|
NSBitmapImageRep *maskBitmap = [[NSBitmapImageRep alloc] initWithBitmapDataPlanes:NULL
|
||||||
|
pixelsWide:(unsigned)size.width * factor
|
||||||
|
pixelsHigh:(unsigned)size.height * factor
|
||||||
|
bitsPerSample:8
|
||||||
|
samplesPerPixel:2
|
||||||
|
hasAlpha:true
|
||||||
|
isPlanar:false
|
||||||
|
colorSpaceName:NSDeviceWhiteColorSpace
|
||||||
|
bytesPerRow:size.width * 2 * factor
|
||||||
|
bitsPerPixel:16];
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
NSGraphicsContext *mainContext = [NSGraphicsContext currentContext];
|
||||||
|
|
||||||
|
|
||||||
|
NSColor *greenColor, *redColor;
|
||||||
|
if (@available(macOS 10.10, *)) {
|
||||||
|
greenColor = [NSColor systemGreenColor];
|
||||||
|
redColor = [NSColor systemRedColor];
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
greenColor = [NSColor colorWithRed:3.0 / 16 green:0.5 blue:5.0 / 16 alpha:1.0];
|
||||||
|
redColor = [NSColor colorWithRed:13.0 / 16 green:0.25 blue:0.25 alpha:1.0];
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
NSBitmapImageRep *colorBitmap = [[NSBitmapImageRep alloc] initWithBitmapDataPlanes:NULL
|
||||||
|
pixelsWide:SAMPLE_COUNT
|
||||||
|
pixelsHigh:1
|
||||||
|
bitsPerSample:8
|
||||||
|
samplesPerPixel:3
|
||||||
|
hasAlpha:false
|
||||||
|
isPlanar:false
|
||||||
|
colorSpaceName:NSDeviceRGBColorSpace
|
||||||
|
bytesPerRow:SAMPLE_COUNT * 4
|
||||||
|
bitsPerPixel:32];
|
||||||
|
|
||||||
|
unsigned lastFill = 0;
|
||||||
|
NSBezierPath *line = [NSBezierPath bezierPath];
|
||||||
|
bool isRed = false;
|
||||||
|
{
|
||||||
|
double sample = _samples[_position % SAMPLE_COUNT];
|
||||||
|
[line moveToPoint:NSMakePoint(0,
|
||||||
|
(sample * (size.height - 1) + 0.5) * factor)];
|
||||||
|
isRed = sample == 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
[NSGraphicsContext setCurrentContext:[NSGraphicsContext graphicsContextWithBitmapImageRep:colorBitmap]];
|
||||||
|
for (unsigned i = 1; i < SAMPLE_COUNT; i++) {
|
||||||
|
double sample = _samples[(i + _position) % SAMPLE_COUNT];
|
||||||
|
[line lineToPoint:NSMakePoint(size.width * i * factor / (SAMPLE_COUNT - 1),
|
||||||
|
(sample * (size.height - 1) + 0.5) * factor)];
|
||||||
|
|
||||||
|
if (isRed != (sample == 1)) {
|
||||||
|
// Color changed
|
||||||
|
[(isRed? redColor : greenColor) setFill];
|
||||||
|
NSRectFill(CGRectMake(lastFill, 0, i - lastFill, 1));
|
||||||
|
lastFill = i;
|
||||||
|
|
||||||
|
isRed ^= true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
[(isRed? redColor : greenColor) setFill];
|
||||||
|
NSRectFill(CGRectMake(lastFill, 0, SAMPLE_COUNT - lastFill, 1));
|
||||||
|
|
||||||
|
NSBezierPath *fill = [line copy];
|
||||||
|
[fill lineToPoint:NSMakePoint(size.width * factor, 0)];
|
||||||
|
[fill lineToPoint:NSMakePoint(0, 0)];
|
||||||
|
|
||||||
|
NSColor *strokeColor = [NSColor whiteColor];
|
||||||
|
NSColor *fillColor = [strokeColor colorWithAlphaComponent:1 / 3.0];
|
||||||
|
|
||||||
|
[NSGraphicsContext setCurrentContext:[NSGraphicsContext graphicsContextWithBitmapImageRep:maskBitmap]];
|
||||||
|
[fillColor setFill];
|
||||||
|
[fill fill];
|
||||||
|
|
||||||
|
[strokeColor setStroke];
|
||||||
|
[line setLineWidth:factor];
|
||||||
|
[line stroke];
|
||||||
|
|
||||||
|
CGContextRef maskContext = CGContextRetain([NSGraphicsContext currentContext].graphicsPort);
|
||||||
|
[NSGraphicsContext setCurrentContext:mainContext];
|
||||||
|
CGContextSaveGState(mainContext.graphicsPort);
|
||||||
|
|
||||||
|
CGImageRef maskImage = CGBitmapContextCreateImage(maskContext);
|
||||||
|
CGContextClipToMask(mainContext.graphicsPort, bounds, maskImage);
|
||||||
|
CGImageRelease(maskImage);
|
||||||
|
|
||||||
|
NSImage *colors = [[NSImage alloc] initWithSize:NSMakeSize(SAMPLE_COUNT, 1)];
|
||||||
|
[colors addRepresentation:colorBitmap];
|
||||||
|
[colors drawInRect:bounds];
|
||||||
|
|
||||||
|
CGContextRestoreGState(mainContext.graphicsPort);
|
||||||
|
CGContextRelease(maskContext);
|
||||||
|
|
||||||
|
|
||||||
|
[super drawRect:dirtyRect];
|
||||||
|
}
|
||||||
|
|
||||||
|
- (void)addSample:(double)sample
|
||||||
|
{
|
||||||
|
_samples[_position++] = sample;
|
||||||
|
if (_position == SAMPLE_COUNT) {
|
||||||
|
_position = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@end
|
|
@ -0,0 +1,5 @@
|
||||||
|
#import <Cocoa/Cocoa.h>
|
||||||
|
|
||||||
|
@interface GBCenteredTextCell : NSTextFieldCell
|
||||||
|
|
||||||
|
@end
|
|
@ -0,0 +1,29 @@
|
||||||
|
#import "GBCenteredTextCell.h"
|
||||||
|
|
||||||
|
@implementation GBCenteredTextCell
|
||||||
|
- (void)drawInteriorWithFrame:(NSRect)cellFrame inView:(NSView *)controlView
|
||||||
|
{
|
||||||
|
double height = round([self.attributedStringValue size].height);
|
||||||
|
cellFrame.origin.y += (cellFrame.size.height - height) / 2;
|
||||||
|
cellFrame.size.height = height;
|
||||||
|
[super drawInteriorWithFrame:cellFrame inView:controlView];
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
- (void)selectWithFrame:(NSRect)rect inView:(NSView *)controlView editor:(NSText *)textObj delegate:(id)delegate start:(NSInteger)selStart length:(NSInteger)selLength
|
||||||
|
{
|
||||||
|
double height = round([self.attributedStringValue size].height);
|
||||||
|
rect.origin.y += (rect.size.height - height) / 2;
|
||||||
|
rect.size.height = height;
|
||||||
|
[super selectWithFrame:rect inView:controlView editor:textObj delegate:delegate start:selStart length:selLength];
|
||||||
|
}
|
||||||
|
|
||||||
|
- (void)editWithFrame:(NSRect)rect inView:(NSView *)controlView editor:(NSText *)textObj delegate:(id)delegate event:(NSEvent *)event
|
||||||
|
{
|
||||||
|
double height = round([self.attributedStringValue size].height);
|
||||||
|
rect.origin.y += (rect.size.height - height) / 2;
|
||||||
|
rect.size.height = height;
|
||||||
|
[super editWithFrame:rect inView:controlView editor:textObj delegate:delegate event:event];
|
||||||
|
|
||||||
|
}
|
||||||
|
@end
|
|
@ -0,0 +1,8 @@
|
||||||
|
#import <AppKit/AppKit.h>
|
||||||
|
#import "Document.h"
|
||||||
|
|
||||||
|
@interface GBCheatSearchController<NSTableViewDelegate, NSTableViewDataSource, NSControlTextEditingDelegate> : NSObject
|
||||||
|
@property IBOutlet NSWindow *window;
|
||||||
|
@property IBOutlet NSTableView *tableView;
|
||||||
|
+ (instancetype)controllerWithDocument:(Document *)document;
|
||||||
|
@end
|
|
@ -0,0 +1,234 @@
|
||||||
|
#import "GBCheatSearchController.h"
|
||||||
|
#import "GBWarningPopover.h"
|
||||||
|
#import "GBCheatWindowController.h"
|
||||||
|
#import "GBPanel.h"
|
||||||
|
|
||||||
|
@interface GBCheatSearchController() <NSTableViewDelegate, NSTableViewDataSource>
|
||||||
|
@property IBOutlet NSPopUpButton *dataTypeButton;
|
||||||
|
@property IBOutlet NSPopUpButton *conditionTypeButton;
|
||||||
|
@property IBOutlet NSTextField *operandField;
|
||||||
|
@property IBOutlet NSTextField *conditionField;
|
||||||
|
@property IBOutlet NSTextField *resultsLabel;
|
||||||
|
@property (strong) IBOutlet NSButton *addCheatButton;
|
||||||
|
@end
|
||||||
|
|
||||||
|
@implementation GBCheatSearchController
|
||||||
|
{
|
||||||
|
__weak Document *_document;
|
||||||
|
size_t _resultCount;
|
||||||
|
GB_cheat_search_result_t *_results;
|
||||||
|
GBPanel *_window;
|
||||||
|
}
|
||||||
|
|
||||||
|
+ (instancetype)controllerWithDocument:(Document *)document
|
||||||
|
{
|
||||||
|
GBCheatSearchController *ret = [[self alloc] init];
|
||||||
|
ret->_document = document;
|
||||||
|
NSArray *objects;
|
||||||
|
[[NSBundle mainBundle] loadNibNamed:@"CheatSearch" owner:ret topLevelObjects:&objects];
|
||||||
|
ret->_resultsLabel.stringValue = @"";
|
||||||
|
ret->_resultsLabel.cell.backgroundStyle = NSBackgroundStyleRaised;
|
||||||
|
ret->_window.ownerWindow = document.mainWindow;
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
- (IBAction)reset:(id)sender
|
||||||
|
{
|
||||||
|
_dataTypeButton.enabled = true;
|
||||||
|
[_document performAtomicBlock:^{
|
||||||
|
GB_cheat_search_reset(_document.gb);
|
||||||
|
}];
|
||||||
|
_resultCount = 0;
|
||||||
|
if (_results) {
|
||||||
|
free(_results);
|
||||||
|
_results = NULL;
|
||||||
|
}
|
||||||
|
[_tableView reloadData];
|
||||||
|
_resultsLabel.stringValue = @"";
|
||||||
|
}
|
||||||
|
|
||||||
|
- (IBAction)search:(id)sender
|
||||||
|
{
|
||||||
|
// Dispatch to work around firstResponder oddities
|
||||||
|
dispatch_async(dispatch_get_main_queue(), ^{
|
||||||
|
if ([sender isKindOfClass:[NSTextField class]]) {
|
||||||
|
// Action sent by losing focus rather than pressing enter
|
||||||
|
if (![sender currentEditor]) return;
|
||||||
|
}
|
||||||
|
_dataTypeButton.enabled = false;
|
||||||
|
[_document performAtomicBlock:^{
|
||||||
|
__block bool success = false;
|
||||||
|
NSString *error = [_document captureOutputForBlock:^{
|
||||||
|
success = GB_cheat_search_filter(_document.gb, _conditionField.stringValue.UTF8String, _dataTypeButton.selectedTag);
|
||||||
|
}];
|
||||||
|
if (!success) {
|
||||||
|
dispatch_async(dispatch_get_main_queue(), ^{
|
||||||
|
[GBWarningPopover popoverWithContents:error onView:_conditionField];
|
||||||
|
NSBeep();
|
||||||
|
});
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
_resultCount = GB_cheat_search_result_count(_document.gb);
|
||||||
|
_results = malloc(sizeof(*_results) * _resultCount);
|
||||||
|
GB_cheat_search_get_results(_document.gb, _results);
|
||||||
|
}];
|
||||||
|
if (_resultCount == 0) {
|
||||||
|
_dataTypeButton.enabled = true;
|
||||||
|
_resultsLabel.stringValue = @"No results.";
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
_resultsLabel.stringValue = [NSString stringWithFormat:@"%@ result%s",
|
||||||
|
[NSNumberFormatter localizedStringFromNumber:@(_resultCount)
|
||||||
|
numberStyle:NSNumberFormatterDecimalStyle],
|
||||||
|
_resultCount > 1? "s" : ""];
|
||||||
|
}
|
||||||
|
[_tableView reloadData];
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
- (IBAction)conditionChanged:(id)sender
|
||||||
|
{
|
||||||
|
unsigned index = [_conditionTypeButton indexOfSelectedItem];
|
||||||
|
_conditionField.enabled = index == 11;
|
||||||
|
_operandField.enabled = index >= 1 && index <= 6;
|
||||||
|
switch ([_conditionTypeButton indexOfSelectedItem]) {
|
||||||
|
case 0: _conditionField.stringValue = @"1"; break;
|
||||||
|
case 1: _conditionField.stringValue = [NSString stringWithFormat:@"new == (%@)", _operandField.stringValue]; break;
|
||||||
|
case 2: _conditionField.stringValue = [NSString stringWithFormat:@"new != (%@)", _operandField.stringValue]; break;
|
||||||
|
case 3: _conditionField.stringValue = [NSString stringWithFormat:@"new > (%@)", _operandField.stringValue]; break;
|
||||||
|
case 4: _conditionField.stringValue = [NSString stringWithFormat:@"new >= (%@)", _operandField.stringValue]; break;
|
||||||
|
case 5: _conditionField.stringValue = [NSString stringWithFormat:@"new < (%@)", _operandField.stringValue]; break;
|
||||||
|
case 6: _conditionField.stringValue = [NSString stringWithFormat:@"new <= (%@)", _operandField.stringValue]; break;
|
||||||
|
case 7: _conditionField.stringValue = @"new != old"; break;
|
||||||
|
case 8: _conditionField.stringValue = @"new == old"; break;
|
||||||
|
case 9: _conditionField.stringValue = @"new > old"; break;
|
||||||
|
case 10: _conditionField.stringValue = @"new < old"; break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
- (NSInteger)numberOfRowsInTableView:(NSTableView *)tableView
|
||||||
|
{
|
||||||
|
return _resultCount;
|
||||||
|
}
|
||||||
|
|
||||||
|
- (uint8_t *)addressForRow:(unsigned)row
|
||||||
|
{
|
||||||
|
uint8_t *base;
|
||||||
|
uint32_t offset;
|
||||||
|
if (_results[row].addr < 0xc000) {
|
||||||
|
base = GB_get_direct_access(_document.gb, GB_DIRECT_ACCESS_CART_RAM, NULL, NULL);
|
||||||
|
offset = (_results[row].addr & 0x1FFF) + _results[row].bank * 0x2000;
|
||||||
|
}
|
||||||
|
else if (_results[row].addr < 0xe000) {
|
||||||
|
base = GB_get_direct_access(_document.gb, GB_DIRECT_ACCESS_RAM, NULL, NULL);
|
||||||
|
offset = (_results[row].addr & 0xFFF) + _results[row].bank * 0x1000;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
base = GB_get_direct_access(_document.gb, GB_DIRECT_ACCESS_HRAM, NULL, NULL);
|
||||||
|
offset = (_results[row].addr & 0x7F);
|
||||||
|
}
|
||||||
|
return base + offset;
|
||||||
|
}
|
||||||
|
|
||||||
|
- (id)tableView:(NSTableView *)tableView objectValueForTableColumn:(NSTableColumn *)tableColumn row:(NSInteger)row
|
||||||
|
{
|
||||||
|
switch ([[tableView tableColumns] indexOfObject:tableColumn]) {
|
||||||
|
case 0:
|
||||||
|
return [NSString stringWithFormat:@"$%02x:$%04x", _results[row].bank, _results[row].addr];
|
||||||
|
case 1:
|
||||||
|
if (_dataTypeButton.selectedTag & GB_CHEAT_SEARCH_DATA_TYPE_16BIT) {
|
||||||
|
return [NSString stringWithFormat:@"$%04x", _results[row].value];
|
||||||
|
}
|
||||||
|
return [NSString stringWithFormat:@"$%02x", _results[row].value];
|
||||||
|
default: {
|
||||||
|
const uint8_t *data = [self addressForRow:row];
|
||||||
|
GB_cheat_search_data_type_t dataType = _dataTypeButton.selectedTag;
|
||||||
|
uint16_t value = data[0];
|
||||||
|
if (!(dataType & GB_CHEAT_SEARCH_DATA_TYPE_16BIT)) {
|
||||||
|
return [NSString stringWithFormat:@"$%02x", value];
|
||||||
|
}
|
||||||
|
value |= data[1] << 8;
|
||||||
|
if ((dataType & GB_CHEAT_SEARCH_DATA_TYPE_BE_BIT)) {
|
||||||
|
value = __builtin_bswap16(value);
|
||||||
|
}
|
||||||
|
return [NSString stringWithFormat:@"$%04x", value];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
- (void)tableView:(NSTableView *)tableView setObjectValue:(NSString *)object forTableColumn:(NSTableColumn *)tableColumn row:(NSInteger)row
|
||||||
|
{
|
||||||
|
[_document performAtomicBlock:^{
|
||||||
|
__block bool success = false;
|
||||||
|
__block uint16_t value;
|
||||||
|
NSString *error = [_document captureOutputForBlock:^{
|
||||||
|
success = !GB_debugger_evaluate(_document.gb, object.UTF8String, &value, NULL);
|
||||||
|
}];
|
||||||
|
if (!success) {
|
||||||
|
dispatch_async(dispatch_get_main_queue(), ^{
|
||||||
|
[GBWarningPopover popoverWithContents:error onView:tableView];
|
||||||
|
NSBeep();
|
||||||
|
});
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
uint8_t *dest = [self addressForRow:row];
|
||||||
|
GB_cheat_search_data_type_t dataType = _dataTypeButton.selectedTag;
|
||||||
|
if (dataType & GB_CHEAT_SEARCH_DATA_TYPE_BE_BIT) {
|
||||||
|
value = __builtin_bswap16(value);
|
||||||
|
}
|
||||||
|
dest[0] = value;
|
||||||
|
if (dataType & GB_CHEAT_SEARCH_DATA_TYPE_16BIT) {
|
||||||
|
dest[1] = value >> 8;
|
||||||
|
}
|
||||||
|
dispatch_async(dispatch_get_main_queue(), ^{
|
||||||
|
[tableView reloadData];
|
||||||
|
});
|
||||||
|
}];
|
||||||
|
}
|
||||||
|
|
||||||
|
- (void)controlTextDidChange:(NSNotification *)obj
|
||||||
|
{
|
||||||
|
[self conditionChanged:nil];
|
||||||
|
}
|
||||||
|
|
||||||
|
- (IBAction)addCheat:(id)sender
|
||||||
|
{
|
||||||
|
GB_cheat_search_result_t *result = _results + _tableView.selectedRow;
|
||||||
|
uint8_t *data = [self addressForRow:_tableView.selectedRow];
|
||||||
|
GB_cheat_search_data_type_t dataType = _dataTypeButton.selectedTag;
|
||||||
|
size_t rowToSelect = 0;
|
||||||
|
GB_get_cheats(_document.gb, &rowToSelect);
|
||||||
|
[_document performAtomicBlock:^{
|
||||||
|
GB_add_cheat(_document.gb,
|
||||||
|
(dataType & GB_CHEAT_SEARCH_DATA_TYPE_16BIT)? "New Cheat (Part 1)" : "New Cheat",
|
||||||
|
result->addr, result->bank,
|
||||||
|
*data,
|
||||||
|
0, false,
|
||||||
|
true);
|
||||||
|
if (dataType & GB_CHEAT_SEARCH_DATA_TYPE_16BIT) {
|
||||||
|
GB_add_cheat(_document.gb,
|
||||||
|
(dataType & GB_CHEAT_SEARCH_DATA_TYPE_16BIT)? "New Cheat (Part 2)" : "New Cheat",
|
||||||
|
result->addr + 1, result->bank,
|
||||||
|
data[1],
|
||||||
|
0, false,
|
||||||
|
true);
|
||||||
|
}
|
||||||
|
GB_set_cheats_enabled(_document.gb, true);
|
||||||
|
}];
|
||||||
|
[_document.cheatsWindow makeKeyAndOrderFront:nil];
|
||||||
|
[_document.cheatWindowController.cheatsTable reloadData];
|
||||||
|
[_document.cheatWindowController.cheatsTable selectRow:rowToSelect byExtendingSelection:false];
|
||||||
|
[_document.cheatWindowController.cheatsTable.delegate tableViewSelectionDidChange:nil];
|
||||||
|
}
|
||||||
|
|
||||||
|
- (void)tableViewSelectionDidChange:(NSNotification *)notification
|
||||||
|
{
|
||||||
|
_addCheatButton.enabled = _tableView.numberOfSelectedRows != 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
- (void)dealloc
|
||||||
|
{
|
||||||
|
if (_results) free(_results);
|
||||||
|
}
|
||||||
|
|
||||||
|
@end
|
|
@ -102,7 +102,7 @@
|
||||||
else {
|
else {
|
||||||
dispatch_async(dispatch_get_main_queue(), ^{
|
dispatch_async(dispatch_get_main_queue(), ^{
|
||||||
NSBeep();
|
NSBeep();
|
||||||
[GBWarningPopover popoverWithContents:@"This code is not a valid GameShark or GameGenie code" onView:self.importCodeField];
|
[GBWarningPopover popoverWithContents:@"This code is not a valid GameShark or Game Genie code" onView:self.importCodeField];
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}];
|
}];
|
||||||
|
|
|
@ -0,0 +1,5 @@
|
||||||
|
#import <Cocoa/Cocoa.h>
|
||||||
|
|
||||||
|
@interface GBColorTextCell : NSTextFieldCell
|
||||||
|
|
||||||
|
@end
|
|
@ -0,0 +1,19 @@
|
||||||
|
#import "GBColorTextCell.h"
|
||||||
|
|
||||||
|
@implementation GBColorTextCell
|
||||||
|
|
||||||
|
- (void)drawWithFrame:(NSRect)cellFrame inView:(NSView *)controlView
|
||||||
|
{
|
||||||
|
[self.backgroundColor set];
|
||||||
|
NSRectFill(cellFrame);
|
||||||
|
|
||||||
|
NSBezierPath *path = [NSBezierPath bezierPathWithRect:cellFrame];
|
||||||
|
path.lineWidth = 2;
|
||||||
|
|
||||||
|
[[NSColor colorWithWhite:0 alpha:0.25] setStroke];
|
||||||
|
[path addClip];
|
||||||
|
[path stroke];
|
||||||
|
|
||||||
|
[self drawInteriorWithFrame:cellFrame inView:controlView];
|
||||||
|
}
|
||||||
|
@end
|
|
@ -0,0 +1,5 @@
|
||||||
|
#import <Cocoa/Cocoa.h>
|
||||||
|
|
||||||
|
@interface GBDeleteButtonCell : NSButtonCell
|
||||||
|
|
||||||
|
@end
|
|
@ -0,0 +1,30 @@
|
||||||
|
#import "GBDeleteButtonCell.h"
|
||||||
|
|
||||||
|
@implementation GBDeleteButtonCell
|
||||||
|
|
||||||
|
// Image scaling is broken on some older macOS versions
|
||||||
|
- (void)drawImage:(NSImage *)image withFrame:(NSRect)frame inView:(NSView *)controlView
|
||||||
|
{
|
||||||
|
double size = 13;
|
||||||
|
unsigned offset = 1;
|
||||||
|
if (@available(macOS 10.10, *)) {
|
||||||
|
size = 15;
|
||||||
|
offset = 0;
|
||||||
|
}
|
||||||
|
frame.origin.x += round((frame.size.width - size) / 2) + offset;
|
||||||
|
frame.origin.y += round((frame.size.height - size) / 2) - offset;
|
||||||
|
frame.size.width = frame.size.height = size;
|
||||||
|
[super drawImage:image withFrame:frame inView:controlView];
|
||||||
|
}
|
||||||
|
|
||||||
|
- (void)drawInteriorWithFrame:(NSRect)cellFrame inView:(NSView *)controlView
|
||||||
|
{
|
||||||
|
[self drawImage:self.image withFrame:cellFrame inView:controlView];
|
||||||
|
}
|
||||||
|
|
||||||
|
-(void)drawBezelWithFrame:(NSRect)frame inView:(NSView *)controlView
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
@end
|
|
@ -0,0 +1,5 @@
|
||||||
|
#import <Cocoa/Cocoa.h>
|
||||||
|
|
||||||
|
@interface GBDisabledButton : NSButton
|
||||||
|
|
||||||
|
@end
|
|
@ -0,0 +1,8 @@
|
||||||
|
#import "GBDisabledButton.h"
|
||||||
|
|
||||||
|
@implementation GBDisabledButton
|
||||||
|
- (void)mouseDown:(NSEvent *)event
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
@end
|
|
@ -136,7 +136,7 @@
|
||||||
if (!_gb) {
|
if (!_gb) {
|
||||||
return [NSString stringWithFormat:@"$%llX", offset];
|
return [NSString stringWithFormat:@"$%llX", offset];
|
||||||
}
|
}
|
||||||
return @(GB_debugger_describe_address(_gb, offset + _baseAddress, _bankForDescription, false, isRangeEnd));
|
return @(GB_debugger_describe_address(_gb, offset + _baseAddress, offset < 0x4000? -1 :_bankForDescription, false, isRangeEnd));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -46,17 +46,29 @@
|
||||||
-(void)drawKnob:(NSRect)knobRect
|
-(void)drawKnob:(NSRect)knobRect
|
||||||
{
|
{
|
||||||
[super drawKnob:knobRect];
|
[super drawKnob:knobRect];
|
||||||
NSRect peekRect = knobRect;
|
NSBezierPath *path = nil;
|
||||||
peekRect.size.width /= 2;
|
if (@available(macos 26.0, *)) {
|
||||||
peekRect.size.height = peekRect.size.width;
|
NSRect peekRect = knobRect;
|
||||||
peekRect.origin.x += peekRect.size.width / 2;
|
peekRect.size.height /= 2;
|
||||||
peekRect.origin.y += peekRect.size.height / 2;
|
peekRect.size.width -= peekRect.size.height;
|
||||||
|
peekRect.origin.x += peekRect.size.height / 2;
|
||||||
|
peekRect.origin.y += peekRect.size.height / 2;
|
||||||
|
path = [NSBezierPath bezierPathWithRoundedRect:peekRect xRadius:peekRect.size.height / 2 yRadius:peekRect.size.height / 2];
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
NSRect peekRect = knobRect;
|
||||||
|
peekRect.size.width /= 2;
|
||||||
|
peekRect.size.height = peekRect.size.width;
|
||||||
|
peekRect.origin.x += peekRect.size.width / 2;
|
||||||
|
peekRect.origin.y += peekRect.size.height / 2;
|
||||||
|
path = [NSBezierPath bezierPathWithOvalInRect:peekRect];
|
||||||
|
|
||||||
|
}
|
||||||
NSColor *color = self.colorValue;
|
NSColor *color = self.colorValue;
|
||||||
if (!self.enabled) {
|
if (!self.enabled) {
|
||||||
color = [color colorWithAlphaComponent:0.5];
|
color = [color colorWithAlphaComponent:0.5];
|
||||||
}
|
}
|
||||||
[color setFill];
|
[color setFill];
|
||||||
NSBezierPath *path = [NSBezierPath bezierPathWithOvalInRect:peekRect];
|
|
||||||
[path fill];
|
[path fill];
|
||||||
[[NSColor colorWithWhite:0 alpha:0.25] setStroke];
|
[[NSColor colorWithWhite:0 alpha:0.25] setStroke];
|
||||||
[path setLineWidth:0.5];
|
[path setLineWidth:0.5];
|
||||||
|
|
|
@ -44,7 +44,8 @@
|
||||||
}
|
}
|
||||||
|
|
||||||
if (parent.displayScrollRect) {
|
if (parent.displayScrollRect) {
|
||||||
NSBezierPath *path = [NSBezierPath bezierPathWithRect:CGRectInfinite];
|
// CGRectInfinite in NSBezierPath is broken in newer macOS versions
|
||||||
|
NSBezierPath *path = [NSBezierPath bezierPathWithRect:CGRectMake(-0x4000, -0x4000, 0x8000, 0x8000)];
|
||||||
for (unsigned x = 0; x < 2; x++) {
|
for (unsigned x = 0; x < 2; x++) {
|
||||||
for (unsigned y = 0; y < 2; y++) {
|
for (unsigned y = 0; y < 2; y++) {
|
||||||
NSRect rect = parent.scrollRect;
|
NSRect rect = parent.scrollRect;
|
||||||
|
|
|
@ -16,7 +16,7 @@
|
||||||
static GBJoyConManager *manager = nil;
|
static GBJoyConManager *manager = nil;
|
||||||
static dispatch_once_t onceToken;
|
static dispatch_once_t onceToken;
|
||||||
dispatch_once(&onceToken, ^{
|
dispatch_once(&onceToken, ^{
|
||||||
manager = [[self alloc] _init];
|
manager = [[super allocWithZone:nil] _init];
|
||||||
});
|
});
|
||||||
return manager;
|
return manager;
|
||||||
}
|
}
|
||||||
|
@ -32,6 +32,16 @@
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
+ (instancetype)allocWithZone:(struct _NSZone *)zone
|
||||||
|
{
|
||||||
|
return [self sharedInstance];
|
||||||
|
}
|
||||||
|
|
||||||
|
+ (instancetype)alloc
|
||||||
|
{
|
||||||
|
return [self sharedInstance];
|
||||||
|
}
|
||||||
|
|
||||||
- (instancetype)init
|
- (instancetype)init
|
||||||
{
|
{
|
||||||
return [self.class sharedInstance];
|
return [self.class sharedInstance];
|
||||||
|
|
|
@ -57,6 +57,9 @@
|
||||||
uint8_t length = document.oamCount;
|
uint8_t length = document.oamCount;
|
||||||
bool cgb = GB_is_cgb(document.gb);
|
bool cgb = GB_is_cgb(document.gb);
|
||||||
uint8_t height = document.oamHeight;
|
uint8_t height = document.oamHeight;
|
||||||
|
NSFont *font = [document debuggerFontOfSize:11];
|
||||||
|
NSFont *boldFont = [[NSFontManager sharedFontManager] convertFont:font toHaveTrait:NSBoldFontMask];
|
||||||
|
|
||||||
for (unsigned i = 0; i < 40; i++) {
|
for (unsigned i = 0; i < 40; i++) {
|
||||||
GBObjectViewItem *item = _items[i];
|
GBObjectViewItem *item = _items[i];
|
||||||
if (i >= length) {
|
if (i >= length) {
|
||||||
|
@ -64,6 +67,13 @@
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
item.view.hidden = false;
|
item.view.hidden = false;
|
||||||
|
|
||||||
|
item.oamAddress.font = boldFont;
|
||||||
|
item.position.font = font;
|
||||||
|
item.attributes.font = font;
|
||||||
|
item.tile.font = font;
|
||||||
|
item.tileAddress.font = font;
|
||||||
|
|
||||||
item.oamAddress.stringValue = [NSString stringWithFormat:@"$%04X", info[i].oam_addr];
|
item.oamAddress.stringValue = [NSString stringWithFormat:@"$%04X", info[i].oam_addr];
|
||||||
item.position.stringValue = [NSString stringWithFormat:@"(%d, %d)",
|
item.position.stringValue = [NSString stringWithFormat:@"(%d, %d)",
|
||||||
((signed)(unsigned)info[i].x) - 8,
|
((signed)(unsigned)info[i].x) - 8,
|
||||||
|
|
|
@ -1,8 +1,8 @@
|
||||||
<?xml version="1.0" encoding="UTF-8"?>
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
<document type="com.apple.InterfaceBuilder3.Cocoa.XIB" version="3.0" toolsVersion="14868" targetRuntime="MacOSX.Cocoa" propertyAccessControl="none" useAutolayout="YES" customObjectInstantitationMethod="direct">
|
<document type="com.apple.InterfaceBuilder3.Cocoa.XIB" version="3.0" toolsVersion="21507" targetRuntime="MacOSX.Cocoa" propertyAccessControl="none" useAutolayout="YES" customObjectInstantitationMethod="direct">
|
||||||
<dependencies>
|
<dependencies>
|
||||||
<deployment identifier="macosx"/>
|
<deployment identifier="macosx"/>
|
||||||
<plugIn identifier="com.apple.InterfaceBuilder.CocoaPlugin" version="14868"/>
|
<plugIn identifier="com.apple.InterfaceBuilder.CocoaPlugin" version="21507"/>
|
||||||
<capability name="documents saved in the Xcode 8 format" minToolsVersion="8.0"/>
|
<capability name="documents saved in the Xcode 8 format" minToolsVersion="8.0"/>
|
||||||
</dependencies>
|
</dependencies>
|
||||||
<objects>
|
<objects>
|
||||||
|
|
|
@ -29,11 +29,12 @@
|
||||||
- (instancetype)initWithFrame:(NSRect)frameRect pixelFormat:(NSOpenGLPixelFormat *)format
|
- (instancetype)initWithFrame:(NSRect)frameRect pixelFormat:(NSOpenGLPixelFormat *)format
|
||||||
{
|
{
|
||||||
__unsafe_unretained GBOpenGLView *weakSelf = self;
|
__unsafe_unretained GBOpenGLView *weakSelf = self;
|
||||||
|
self = [super initWithFrame:frameRect pixelFormat:format];
|
||||||
[self observeStandardDefaultsKey:@"GBFilter" withBlock:^(id newValue) {
|
[self observeStandardDefaultsKey:@"GBFilter" withBlock:^(id newValue) {
|
||||||
weakSelf.shader = nil;
|
weakSelf.shader = nil;
|
||||||
[weakSelf setNeedsDisplay:true];
|
[weakSelf setNeedsDisplay:true];
|
||||||
|
|
||||||
}];
|
}];
|
||||||
return [super initWithFrame:frameRect pixelFormat:format];
|
return self;
|
||||||
}
|
}
|
||||||
@end
|
@end
|
||||||
|
|
|
@ -14,5 +14,7 @@
|
||||||
@property (weak) IBOutlet NSSlider *hueStrengthSlider;
|
@property (weak) IBOutlet NSSlider *hueStrengthSlider;
|
||||||
@property (weak) IBOutlet NSTableView *themesList;
|
@property (weak) IBOutlet NSTableView *themesList;
|
||||||
@property (weak) IBOutlet NSMenu *menu;
|
@property (weak) IBOutlet NSMenu *menu;
|
||||||
|
@property (weak) IBOutlet NSSegmentedControl *segmentControl;
|
||||||
|
@property IBOutlet NSMenu *segmentMenu;
|
||||||
+ (const GB_palette_t *)userPalette;
|
+ (const GB_palette_t *)userPalette;
|
||||||
@end
|
@end
|
||||||
|
|
|
@ -1,5 +1,6 @@
|
||||||
#import "GBPaletteEditorController.h"
|
#import "GBPaletteEditorController.h"
|
||||||
#import "GBHueSliderCell.h"
|
#import "GBHueSliderCell.h"
|
||||||
|
#import "GBApp.h"
|
||||||
#import <Core/gb.h>
|
#import <Core/gb.h>
|
||||||
|
|
||||||
#define MAGIC 'SBPL'
|
#define MAGIC 'SBPL'
|
||||||
|
@ -199,11 +200,17 @@ static double blend(double from, double to, double position)
|
||||||
if (theme && themes[theme]) {
|
if (theme && themes[theme]) {
|
||||||
unsigned index = [[themes.allKeys sortedArrayUsingSelector:@selector(localizedCaseInsensitiveCompare:)] indexOfObject:theme];
|
unsigned index = [[themes.allKeys sortedArrayUsingSelector:@selector(localizedCaseInsensitiveCompare:)] indexOfObject:theme];
|
||||||
[_themesList selectRowIndexes:[NSIndexSet indexSetWithIndex:index] byExtendingSelection:false];
|
[_themesList selectRowIndexes:[NSIndexSet indexSetWithIndex:index] byExtendingSelection:false];
|
||||||
|
[_themesList scrollRowToVisible:index];
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
[_themesList selectRowIndexes:[NSIndexSet indexSetWithIndex:0] byExtendingSelection:false];
|
[_themesList selectRowIndexes:[NSIndexSet indexSetWithIndex:0] byExtendingSelection:false];
|
||||||
|
[_themesList scrollRowToVisible:0];
|
||||||
}
|
}
|
||||||
[self tableViewSelectionDidChange:nil];
|
[self tableViewSelectionDidChange:nil];
|
||||||
|
if (@available(macOS 10.10, *)) {
|
||||||
|
_themesList.enclosingScrollView.contentView.automaticallyAdjustsContentInsets = false;
|
||||||
|
_themesList.enclosingScrollView.contentView.contentInsets = NSEdgeInsetsMake(0, 0, 10, 0);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
- (IBAction)addTheme:(id)sender
|
- (IBAction)addTheme:(id)sender
|
||||||
|
@ -360,19 +367,48 @@ static double blend(double from, double to, double position)
|
||||||
}
|
}
|
||||||
[defaults setObject:newName forKey:@"GBCurrentTheme"];
|
[defaults setObject:newName forKey:@"GBCurrentTheme"];
|
||||||
[self savePalette:sender];
|
[self savePalette:sender];
|
||||||
|
[self.themesList reloadData];
|
||||||
[self awakeFromNib];
|
[self awakeFromNib];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
- (IBAction)segmentAction:(NSSegmentedControl *)sender
|
||||||
|
{
|
||||||
|
switch (sender.selectedSegment) {
|
||||||
|
case 0: [self addTheme:sender]; return;
|
||||||
|
case 1: [self deleteTheme:sender]; return;
|
||||||
|
case 3: {
|
||||||
|
NSSize buttonSize = _segmentControl.bounds.size;
|
||||||
|
[_segmentMenu popUpMenuPositioningItem:_segmentMenu.itemArray.lastObject
|
||||||
|
atLocation:NSMakePoint(buttonSize.width,
|
||||||
|
0)
|
||||||
|
inView:sender];
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
- (IBAction)restoreDefaultPalettes:(id)sender
|
||||||
|
{
|
||||||
|
[(GBApp *)NSApp updateThemesDefault:true];
|
||||||
|
[self awakeFromNib];
|
||||||
|
}
|
||||||
|
|
||||||
- (IBAction)done:(NSButton *)sender
|
- (IBAction)done:(NSButton *)sender
|
||||||
{
|
{
|
||||||
[sender.window.sheetParent endSheet:sender.window];
|
[sender.window.sheetParent endSheet:sender.window];
|
||||||
}
|
}
|
||||||
|
|
||||||
- (instancetype)init
|
+ (instancetype)alloc
|
||||||
{
|
{
|
||||||
static id singleton = nil;
|
static id singleton = nil;
|
||||||
if (singleton) return singleton;
|
if (singleton) return singleton;
|
||||||
return (singleton = [super init]);
|
return (singleton = [super allocWithZone:nil]);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
+ (instancetype)allocWithZone:(struct _NSZone *)zone
|
||||||
|
{
|
||||||
|
return [self alloc];
|
||||||
|
}
|
||||||
|
|
||||||
@end
|
@end
|
||||||
|
|
|
@ -43,6 +43,7 @@
|
||||||
GB_gameboy_t *gb = document.gb;
|
GB_gameboy_t *gb = document.gb;
|
||||||
uint8_t *bg = GB_get_direct_access(gb, GB_DIRECT_ACCESS_BGP, NULL, NULL);
|
uint8_t *bg = GB_get_direct_access(gb, GB_DIRECT_ACCESS_BGP, NULL, NULL);
|
||||||
uint8_t *obj = GB_get_direct_access(gb, GB_DIRECT_ACCESS_OBP, NULL, NULL);
|
uint8_t *obj = GB_get_direct_access(gb, GB_DIRECT_ACCESS_OBP, NULL, NULL);
|
||||||
|
NSFont *font = [document debuggerFontOfSize:13];
|
||||||
|
|
||||||
for (unsigned i = 0; i < 4 * 8 * 2; i++) {
|
for (unsigned i = 0; i < 4 * 8 * 2; i++) {
|
||||||
uint8_t index = i % (4 * 8);
|
uint8_t index = i % (4 * 8);
|
||||||
|
@ -58,6 +59,7 @@
|
||||||
field.stringValue = [NSString stringWithFormat:@"$%04X", color];
|
field.stringValue = [NSString stringWithFormat:@"$%04X", color];
|
||||||
field.textColor = r * 3 + g * 4 + b * 2 > 120? [NSColor blackColor] : [NSColor whiteColor];
|
field.textColor = r * 3 + g * 4 + b * 2 > 120? [NSColor blackColor] : [NSColor whiteColor];
|
||||||
field.toolTip = [NSString stringWithFormat:@"Red: %d, Green: %d, Blue: %d", r, g, b];
|
field.toolTip = [NSString stringWithFormat:@"Red: %d, Green: %d, Blue: %d", r, g, b];
|
||||||
|
field.font = font;
|
||||||
field.backgroundColor = [NSColor colorWithRed:(nativeColor & 0xFF) / 255.0
|
field.backgroundColor = [NSColor colorWithRed:(nativeColor & 0xFF) / 255.0
|
||||||
green:((nativeColor >> 8) & 0xFF) / 255.0
|
green:((nativeColor >> 8) & 0xFF) / 255.0
|
||||||
blue:((nativeColor >> 16) & 0xFF) / 255.0
|
blue:((nativeColor >> 16) & 0xFF) / 255.0
|
||||||
|
|
|
@ -1,8 +1,8 @@
|
||||||
<?xml version="1.0" encoding="UTF-8"?>
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
<document type="com.apple.InterfaceBuilder3.Cocoa.XIB" version="3.0" toolsVersion="14868" targetRuntime="MacOSX.Cocoa" propertyAccessControl="none" useAutolayout="YES" customObjectInstantitationMethod="direct">
|
<document type="com.apple.InterfaceBuilder3.Cocoa.XIB" version="3.0" toolsVersion="24093.7" targetRuntime="MacOSX.Cocoa" propertyAccessControl="none" useAutolayout="YES" customObjectInstantitationMethod="direct">
|
||||||
<dependencies>
|
<dependencies>
|
||||||
<deployment identifier="macosx"/>
|
<deployment identifier="macosx"/>
|
||||||
<plugIn identifier="com.apple.InterfaceBuilder.CocoaPlugin" version="14868"/>
|
<plugIn identifier="com.apple.InterfaceBuilder.CocoaPlugin" version="24093.7"/>
|
||||||
<capability name="documents saved in the Xcode 8 format" minToolsVersion="8.0"/>
|
<capability name="documents saved in the Xcode 8 format" minToolsVersion="8.0"/>
|
||||||
</dependencies>
|
</dependencies>
|
||||||
<objects>
|
<objects>
|
||||||
|
@ -22,44 +22,44 @@
|
||||||
<rect key="frame" x="0.0" y="0.0" width="512" height="24"/>
|
<rect key="frame" x="0.0" y="0.0" width="512" height="24"/>
|
||||||
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMinY="YES"/>
|
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMinY="YES"/>
|
||||||
<subviews>
|
<subviews>
|
||||||
<textField verticalHuggingPriority="750" fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="ypt-t4-Mf3">
|
<textField focusRingType="none" verticalHuggingPriority="750" fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="ypt-t4-Mf3">
|
||||||
<rect key="frame" x="131" y="0.0" width="96" height="24"/>
|
<rect key="frame" x="131" y="0.0" width="95" height="24"/>
|
||||||
<autoresizingMask key="autoresizingMask"/>
|
<autoresizingMask key="autoresizingMask"/>
|
||||||
<textFieldCell key="cell" scrollable="YES" lineBreakMode="clipping" selectable="YES" sendsActionOnEndEditing="YES" borderStyle="border" alignment="center" title="$7FFF" drawsBackground="YES" id="sKu-Uy-2LG">
|
<textFieldCell key="cell" scrollable="YES" lineBreakMode="clipping" selectable="YES" sendsActionOnEndEditing="YES" borderStyle="border" alignment="center" title="$7FFF" drawsBackground="YES" id="sKu-Uy-2LG" customClass="GBColorTextCell">
|
||||||
<font key="font" size="13" name="Menlo-Regular"/>
|
<font key="font" size="13" name="Menlo-Regular"/>
|
||||||
<color key="textColor" white="0.0" alpha="1" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/>
|
<color key="textColor" white="0.0" alpha="1" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/>
|
||||||
<color key="backgroundColor" white="1" alpha="1" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/>
|
<color key="backgroundColor" white="1" alpha="1" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/>
|
||||||
</textFieldCell>
|
</textFieldCell>
|
||||||
</textField>
|
</textField>
|
||||||
<textField verticalHuggingPriority="750" fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="KkX-Z8-Sqi">
|
<textField focusRingType="none" verticalHuggingPriority="750" fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="KkX-Z8-Sqi">
|
||||||
<rect key="frame" x="226" y="0.0" width="96" height="24"/>
|
<rect key="frame" x="226" y="0.0" width="95" height="24"/>
|
||||||
<autoresizingMask key="autoresizingMask"/>
|
<autoresizingMask key="autoresizingMask"/>
|
||||||
<textFieldCell key="cell" scrollable="YES" lineBreakMode="clipping" selectable="YES" sendsActionOnEndEditing="YES" borderStyle="border" alignment="center" title="$7FFF" drawsBackground="YES" id="9LH-TF-W1L">
|
<textFieldCell key="cell" scrollable="YES" lineBreakMode="clipping" selectable="YES" sendsActionOnEndEditing="YES" borderStyle="border" alignment="center" title="$7FFF" drawsBackground="YES" id="9LH-TF-W1L" customClass="GBColorTextCell">
|
||||||
<font key="font" size="13" name="Menlo-Regular"/>
|
<font key="font" size="13" name="Menlo-Regular"/>
|
||||||
<color key="textColor" white="0.0" alpha="1" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/>
|
<color key="textColor" white="0.0" alpha="1" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/>
|
||||||
<color key="backgroundColor" white="1" alpha="1" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/>
|
<color key="backgroundColor" white="1" alpha="1" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/>
|
||||||
</textFieldCell>
|
</textFieldCell>
|
||||||
</textField>
|
</textField>
|
||||||
<textField verticalHuggingPriority="750" fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="jDk-Ej-4yI">
|
<textField focusRingType="none" verticalHuggingPriority="750" fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="jDk-Ej-4yI">
|
||||||
<rect key="frame" x="321" y="0.0" width="96" height="24"/>
|
<rect key="frame" x="321" y="0.0" width="95" height="24"/>
|
||||||
<autoresizingMask key="autoresizingMask"/>
|
<autoresizingMask key="autoresizingMask"/>
|
||||||
<textFieldCell key="cell" scrollable="YES" lineBreakMode="clipping" selectable="YES" sendsActionOnEndEditing="YES" borderStyle="border" alignment="center" title="$7FFF" drawsBackground="YES" id="arE-i5-zCC">
|
<textFieldCell key="cell" scrollable="YES" lineBreakMode="clipping" selectable="YES" sendsActionOnEndEditing="YES" borderStyle="border" alignment="center" title="$7FFF" drawsBackground="YES" id="arE-i5-zCC" customClass="GBColorTextCell">
|
||||||
<font key="font" size="13" name="Menlo-Regular"/>
|
<font key="font" size="13" name="Menlo-Regular"/>
|
||||||
<color key="textColor" white="0.0" alpha="1" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/>
|
<color key="textColor" white="0.0" alpha="1" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/>
|
||||||
<color key="backgroundColor" white="1" alpha="1" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/>
|
<color key="backgroundColor" white="1" alpha="1" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/>
|
||||||
</textFieldCell>
|
</textFieldCell>
|
||||||
</textField>
|
</textField>
|
||||||
<textField verticalHuggingPriority="750" fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="7PI-YE-fTk">
|
<textField focusRingType="none" verticalHuggingPriority="750" fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="7PI-YE-fTk">
|
||||||
<rect key="frame" x="416" y="0.0" width="96" height="24"/>
|
<rect key="frame" x="416" y="0.0" width="95" height="24"/>
|
||||||
<autoresizingMask key="autoresizingMask"/>
|
<autoresizingMask key="autoresizingMask"/>
|
||||||
<textFieldCell key="cell" scrollable="YES" lineBreakMode="clipping" selectable="YES" sendsActionOnEndEditing="YES" borderStyle="border" alignment="center" title="$7FFF" drawsBackground="YES" id="ZbU-nE-FsE">
|
<textFieldCell key="cell" scrollable="YES" lineBreakMode="clipping" selectable="YES" sendsActionOnEndEditing="YES" borderStyle="border" alignment="center" title="$7FFF" drawsBackground="YES" id="ZbU-nE-FsE" customClass="GBColorTextCell">
|
||||||
<font key="font" size="13" name="Menlo-Regular"/>
|
<font key="font" size="13" name="Menlo-Regular"/>
|
||||||
<color key="textColor" white="0.0" alpha="1" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/>
|
<color key="textColor" white="0.0" alpha="1" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/>
|
||||||
<color key="backgroundColor" white="1" alpha="1" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/>
|
<color key="backgroundColor" white="1" alpha="1" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/>
|
||||||
</textFieldCell>
|
</textFieldCell>
|
||||||
</textField>
|
</textField>
|
||||||
<textField horizontalHuggingPriority="251" verticalHuggingPriority="750" fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="NOK-yI-LKh">
|
<textField focusRingType="none" horizontalHuggingPriority="251" verticalHuggingPriority="750" fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="NOK-yI-LKh">
|
||||||
<rect key="frame" x="4" y="0.0" width="121" height="20"/>
|
<rect key="frame" x="8" y="0.0" width="121" height="20"/>
|
||||||
<autoresizingMask key="autoresizingMask"/>
|
<autoresizingMask key="autoresizingMask"/>
|
||||||
<textFieldCell key="cell" lineBreakMode="clipping" title="Background 0" id="qM4-cY-SDE">
|
<textFieldCell key="cell" lineBreakMode="clipping" title="Background 0" id="qM4-cY-SDE">
|
||||||
<font key="font" usesAppearanceFont="YES"/>
|
<font key="font" usesAppearanceFont="YES"/>
|
||||||
|
|
|
@ -0,0 +1,5 @@
|
||||||
|
#import <Cocoa/Cocoa.h>
|
||||||
|
|
||||||
|
@interface GBPanel : NSPanel
|
||||||
|
@property (weak) IBOutlet NSWindow *ownerWindow;
|
||||||
|
@end
|
|
@ -0,0 +1,11 @@
|
||||||
|
#import "GBPanel.h"
|
||||||
|
|
||||||
|
@implementation GBPanel
|
||||||
|
- (void)becomeKeyWindow
|
||||||
|
{
|
||||||
|
if ([_ownerWindow canBecomeMainWindow]) {
|
||||||
|
[_ownerWindow makeMainWindow];
|
||||||
|
}
|
||||||
|
[super becomeKeyWindow];
|
||||||
|
}
|
||||||
|
@end
|
|
@ -1,6 +1,7 @@
|
||||||
#import <Cocoa/Cocoa.h>
|
#import <Cocoa/Cocoa.h>
|
||||||
#import <JoyKit/JoyKit.h>
|
#import <JoyKit/JoyKit.h>
|
||||||
#import "GBPaletteEditorController.h"
|
#import "GBPaletteEditorController.h"
|
||||||
|
#import "GBTitledPopUpButton.h"
|
||||||
|
|
||||||
@interface GBPreferencesWindow : NSWindow <NSTableViewDelegate, NSTableViewDataSource, JOYListener>
|
@interface GBPreferencesWindow : NSWindow <NSTableViewDelegate, NSTableViewDataSource, JOYListener>
|
||||||
@property IBOutlet NSTableView *controlsTableView;
|
@property IBOutlet NSTableView *controlsTableView;
|
||||||
|
@ -18,4 +19,10 @@
|
||||||
@property IBOutlet NSPopUpButton *colorPalettePopupButton;
|
@property IBOutlet NSPopUpButton *colorPalettePopupButton;
|
||||||
@property IBOutlet NSPopUpButton *hotkey1PopupButton;
|
@property IBOutlet NSPopUpButton *hotkey1PopupButton;
|
||||||
@property IBOutlet NSPopUpButton *hotkey2PopupButton;
|
@property IBOutlet NSPopUpButton *hotkey2PopupButton;
|
||||||
|
@property IBOutlet NSButton *turboCapButton;
|
||||||
|
@property IBOutlet NSSlider *turboCapSlider;
|
||||||
|
@property IBOutlet NSTextField *turboCapLabel;
|
||||||
|
|
||||||
|
@property IBOutlet GBTitledPopUpButton *fontPopupButton;
|
||||||
|
@property IBOutlet NSStepper *fontSizeStepper;
|
||||||
@end
|
@end
|
||||||
|
|
|
@ -20,7 +20,7 @@
|
||||||
|
|
||||||
- (NSWindowToolbarStyle)toolbarStyle
|
- (NSWindowToolbarStyle)toolbarStyle
|
||||||
{
|
{
|
||||||
return NSWindowToolbarStyleExpanded;
|
return NSWindowToolbarStylePreference;
|
||||||
}
|
}
|
||||||
|
|
||||||
- (void)close
|
- (void)close
|
||||||
|
@ -40,16 +40,16 @@ static inline NSString *keyEquivalentString(NSMenuItem *item)
|
||||||
- (NSInteger)numberOfRowsInTableView:(NSTableView *)tableView
|
- (NSInteger)numberOfRowsInTableView:(NSTableView *)tableView
|
||||||
{
|
{
|
||||||
if (self.playerListButton.selectedTag == 0) {
|
if (self.playerListButton.selectedTag == 0) {
|
||||||
return GBButtonCount;
|
return GBKeyboardButtonCount;
|
||||||
}
|
}
|
||||||
return GBGameBoyButtonCount;
|
return GBPerPlayerButtonCount;
|
||||||
}
|
}
|
||||||
|
|
||||||
- (unsigned) usesForKey:(unsigned) key
|
- (unsigned) usesForKey:(unsigned) key
|
||||||
{
|
{
|
||||||
unsigned ret = 0;
|
unsigned ret = 0;
|
||||||
for (unsigned player = 4; player--;) {
|
for (unsigned player = 4; player--;) {
|
||||||
for (unsigned button = player == 0? GBButtonCount:GBGameBoyButtonCount; button--;) {
|
for (unsigned button = player == 0? GBKeyboardButtonCount:GBPerPlayerButtonCount; button--;) {
|
||||||
NSNumber *other = [[NSUserDefaults standardUserDefaults] valueForKey:button_to_preference_name(button, player)];
|
NSNumber *other = [[NSUserDefaults standardUserDefaults] valueForKey:button_to_preference_name(button, player)];
|
||||||
if (other && [other unsignedIntValue] == key) {
|
if (other && [other unsignedIntValue] == key) {
|
||||||
ret++;
|
ret++;
|
||||||
|
@ -205,7 +205,7 @@ static inline NSString *keyEquivalentString(NSMenuItem *item)
|
||||||
if (joystick_configuration_state == GBUnderclock) {
|
if (joystick_configuration_state == GBUnderclock) {
|
||||||
[self.configureJoypadButton setTitle:@"Press Button for Slo-Mo"]; // Full name is too long :<
|
[self.configureJoypadButton setTitle:@"Press Button for Slo-Mo"]; // Full name is too long :<
|
||||||
}
|
}
|
||||||
else if (joystick_configuration_state < GBJoypadButtonCount) {
|
else if (joystick_configuration_state < GBTotalButtonCount) {
|
||||||
[self.configureJoypadButton setTitle:[NSString stringWithFormat:@"Press Button for %@", GBButtonNames[joystick_configuration_state]]];
|
[self.configureJoypadButton setTitle:[NSString stringWithFormat:@"Press Button for %@", GBButtonNames[joystick_configuration_state]]];
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
|
@ -227,7 +227,7 @@ static inline NSString *keyEquivalentString(NSMenuItem *item)
|
||||||
|
|
||||||
if (!button.isPressed) return;
|
if (!button.isPressed) return;
|
||||||
if (joystick_configuration_state == -1) return;
|
if (joystick_configuration_state == -1) return;
|
||||||
if (joystick_configuration_state == GBJoypadButtonCount) return;
|
if (joystick_configuration_state == GBTotalButtonCount) return;
|
||||||
if (!joystick_being_configured) {
|
if (!joystick_being_configured) {
|
||||||
joystick_being_configured = controller.uniqueID;
|
joystick_being_configured = controller.uniqueID;
|
||||||
}
|
}
|
||||||
|
@ -266,6 +266,8 @@ static inline NSString *keyEquivalentString(NSMenuItem *item)
|
||||||
[GBB] = JOYButtonUsageB,
|
[GBB] = JOYButtonUsageB,
|
||||||
[GBSelect] = JOYButtonUsageSelect,
|
[GBSelect] = JOYButtonUsageSelect,
|
||||||
[GBStart] = JOYButtonUsageStart,
|
[GBStart] = JOYButtonUsageStart,
|
||||||
|
[GBRapidA] = GBJoyKitRapidA,
|
||||||
|
[GBRapidB] = GBJoyKitRapidB,
|
||||||
[GBTurbo] = JOYButtonUsageL1,
|
[GBTurbo] = JOYButtonUsageL1,
|
||||||
[GBRewind] = JOYButtonUsageL2,
|
[GBRewind] = JOYButtonUsageL2,
|
||||||
[GBUnderclock] = JOYButtonUsageR1,
|
[GBUnderclock] = JOYButtonUsageR1,
|
||||||
|
@ -337,6 +339,70 @@ static inline NSString *keyEquivalentString(NSMenuItem *item)
|
||||||
else {
|
else {
|
||||||
[_colorPalettePopupButton selectItemWithTitle:[[NSUserDefaults standardUserDefaults] stringForKey:@"GBCurrentTheme"] ?: @""];
|
[_colorPalettePopupButton selectItemWithTitle:[[NSUserDefaults standardUserDefaults] stringForKey:@"GBCurrentTheme"] ?: @""];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
_fontSizeStepper.intValue = [[NSUserDefaults standardUserDefaults] integerForKey:@"GBDebuggerFontSize"];
|
||||||
|
[self updateFonts];
|
||||||
|
|
||||||
|
double cap = [[NSUserDefaults standardUserDefaults] doubleForKey:@"GBTurboCap"];
|
||||||
|
if (cap) {
|
||||||
|
_turboCapSlider.intValue = round(cap * 100);
|
||||||
|
_turboCapButton.state = NSOnState;
|
||||||
|
}
|
||||||
|
[self turboCapToggled:_turboCapButton];
|
||||||
|
}
|
||||||
|
|
||||||
|
- (IBAction)fontSizeChanged:(id)sender
|
||||||
|
{
|
||||||
|
NSString *selectedFont = [[NSUserDefaults standardUserDefaults] stringForKey:@"GBDebuggerFont"];
|
||||||
|
[[NSUserDefaults standardUserDefaults] setInteger:[sender intValue] forKey:@"GBDebuggerFontSize"];
|
||||||
|
[_fontPopupButton setDisplayTitle:[NSString stringWithFormat:@"%@ %upt", selectedFont, (unsigned)[[NSUserDefaults standardUserDefaults] integerForKey:@"GBDebuggerFontSize"]]];
|
||||||
|
}
|
||||||
|
|
||||||
|
- (IBAction)fontChanged:(id)sender
|
||||||
|
{
|
||||||
|
NSString *selectedFont = _fontPopupButton.selectedItem.title;
|
||||||
|
[[NSUserDefaults standardUserDefaults] setObject:selectedFont forKey:@"GBDebuggerFont"];
|
||||||
|
[_fontPopupButton setDisplayTitle:[NSString stringWithFormat:@"%@ %upt", selectedFont, (unsigned)[[NSUserDefaults standardUserDefaults] integerForKey:@"GBDebuggerFontSize"]]];
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
- (void)updateFonts
|
||||||
|
{
|
||||||
|
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
|
||||||
|
NSFontManager *fontManager = [NSFontManager sharedFontManager];
|
||||||
|
NSArray *allFamilies = [fontManager availableFontFamilies];
|
||||||
|
NSMutableSet *families = [NSMutableSet set];
|
||||||
|
for (NSString *family in allFamilies) {
|
||||||
|
if ([fontManager fontNamed:family hasTraits:NSFixedPitchFontMask]) {
|
||||||
|
[families addObject:family];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
bool hasSFMono = false;
|
||||||
|
if (@available(macOS 10.15, *)) {
|
||||||
|
hasSFMono = [[NSFont monospacedSystemFontOfSize:12 weight:NSFontWeightRegular].displayName containsString:@"SF"];
|
||||||
|
}
|
||||||
|
|
||||||
|
if (hasSFMono) {
|
||||||
|
[families addObject:@"SF Mono"];
|
||||||
|
}
|
||||||
|
|
||||||
|
NSArray *sortedFamilies = [[families allObjects] sortedArrayUsingSelector:@selector(compare:)];
|
||||||
|
|
||||||
|
dispatch_async(dispatch_get_main_queue(), ^{
|
||||||
|
if (![families containsObject:[[NSUserDefaults standardUserDefaults] stringForKey:@"GBDebuggerFont"]]) {
|
||||||
|
[[NSUserDefaults standardUserDefaults] removeObjectForKey:@"GBDebuggerFont"];
|
||||||
|
}
|
||||||
|
|
||||||
|
[_fontPopupButton.menu removeAllItems];
|
||||||
|
for (NSString *family in sortedFamilies) {
|
||||||
|
[_fontPopupButton addItemWithTitle:family];
|
||||||
|
}
|
||||||
|
NSString *selectedFont = [[NSUserDefaults standardUserDefaults] stringForKey:@"GBDebuggerFont"];
|
||||||
|
[_fontPopupButton selectItemWithTitle:selectedFont];
|
||||||
|
[_fontPopupButton setDisplayTitle:[NSString stringWithFormat:@"%@ %upt", selectedFont, (unsigned)[[NSUserDefaults standardUserDefaults] integerForKey:@"GBDebuggerFontSize"]]];
|
||||||
|
});
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
- (void)dealloc
|
- (void)dealloc
|
||||||
|
@ -461,7 +527,7 @@ static inline NSString *keyEquivalentString(NSMenuItem *item)
|
||||||
[GB_COLOR_CORRECTION_MODERN_BALANCED] = @"Emulates a modern display. Blue contrast is moderately enhanced at the cost of slight hue inaccuracy.",
|
[GB_COLOR_CORRECTION_MODERN_BALANCED] = @"Emulates a modern display. Blue contrast is moderately enhanced at the cost of slight hue inaccuracy.",
|
||||||
[GB_COLOR_CORRECTION_MODERN_BOOST_CONTRAST] = @"Like Modern – Balanced, but further boosts the contrast of greens and magentas that is lacking on the original hardware.",
|
[GB_COLOR_CORRECTION_MODERN_BOOST_CONTRAST] = @"Like Modern – Balanced, but further boosts the contrast of greens and magentas that is lacking on the original hardware.",
|
||||||
[GB_COLOR_CORRECTION_REDUCE_CONTRAST] = @"Slightly reduce the contrast to better represent the tint and contrast of the original display.",
|
[GB_COLOR_CORRECTION_REDUCE_CONTRAST] = @"Slightly reduce the contrast to better represent the tint and contrast of the original display.",
|
||||||
[GB_COLOR_CORRECTION_LOW_CONTRAST] = @"Harshly reduce the contrast to accurately represent the tint and low constrast of the original display.",
|
[GB_COLOR_CORRECTION_LOW_CONTRAST] = @"Harshly reduce the contrast to accurately represent the tint and low contrast of the original display.",
|
||||||
[GB_COLOR_CORRECTION_MODERN_ACCURATE] = @"Emulates a modern display. Colors have their hues and brightness corrected.",
|
[GB_COLOR_CORRECTION_MODERN_ACCURATE] = @"Emulates a modern display. Colors have their hues and brightness corrected.",
|
||||||
}) [self.colorCorrectionPopupButton.selectedItem.tag]
|
}) [self.colorCorrectionPopupButton.selectedItem.tag]
|
||||||
title:self.colorCorrectionPopupButton.selectedItem.title
|
title:self.colorCorrectionPopupButton.selectedItem.title
|
||||||
|
@ -496,4 +562,35 @@ static inline NSString *keyEquivalentString(NSMenuItem *item)
|
||||||
[GBJoyConManager sharedInstance].arrangementMode = false;
|
[GBJoyConManager sharedInstance].arrangementMode = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
- (IBAction)turboCapToggled:(NSButton *)sender
|
||||||
|
{
|
||||||
|
if (sender.state) {
|
||||||
|
_turboCapSlider.enabled = true;
|
||||||
|
[self turboCapChanged:_turboCapSlider];
|
||||||
|
if (@available(macOS 10.10, *)) {
|
||||||
|
_turboCapLabel.textColor = [NSColor labelColor];
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
_turboCapLabel.textColor = [NSColor blackColor];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
_turboCapSlider.enabled = false;
|
||||||
|
_turboCapLabel.enabled = false;
|
||||||
|
[[NSUserDefaults standardUserDefaults] setDouble:0 forKey:@"GBTurboCap"];
|
||||||
|
if (@available(macOS 10.10, *)) {
|
||||||
|
_turboCapLabel.textColor = [NSColor disabledControlTextColor];
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
_turboCapLabel.textColor = [NSColor colorWithWhite:0 alpha:0.25];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
- (IBAction)turboCapChanged:(NSSlider *)sender
|
||||||
|
{
|
||||||
|
_turboCapLabel.stringValue = [NSString stringWithFormat:@"%d%%", sender.intValue];
|
||||||
|
[[NSUserDefaults standardUserDefaults] setDouble:sender.doubleValue / 100.0 forKey:@"GBTurboCap"];
|
||||||
|
}
|
||||||
|
|
||||||
@end
|
@end
|
||||||
|
|
|
@ -1,8 +1,8 @@
|
||||||
<?xml version="1.0" encoding="UTF-8"?>
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
<document type="com.apple.InterfaceBuilder3.Cocoa.XIB" version="3.0" toolsVersion="14868" targetRuntime="MacOSX.Cocoa" propertyAccessControl="none" useAutolayout="YES" customObjectInstantitationMethod="direct">
|
<document type="com.apple.InterfaceBuilder3.Cocoa.XIB" version="3.0" toolsVersion="24093.7" targetRuntime="MacOSX.Cocoa" propertyAccessControl="none" useAutolayout="YES" customObjectInstantitationMethod="direct">
|
||||||
<dependencies>
|
<dependencies>
|
||||||
<deployment identifier="macosx"/>
|
<deployment identifier="macosx"/>
|
||||||
<plugIn identifier="com.apple.InterfaceBuilder.CocoaPlugin" version="14868"/>
|
<plugIn identifier="com.apple.InterfaceBuilder.CocoaPlugin" version="24093.7"/>
|
||||||
<capability name="documents saved in the Xcode 8 format" minToolsVersion="8.0"/>
|
<capability name="documents saved in the Xcode 8 format" minToolsVersion="8.0"/>
|
||||||
</dependencies>
|
</dependencies>
|
||||||
<objects>
|
<objects>
|
||||||
|
@ -25,7 +25,7 @@
|
||||||
<rect key="frame" x="0.0" y="0.0" width="332" height="221"/>
|
<rect key="frame" x="0.0" y="0.0" width="332" height="221"/>
|
||||||
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMinY="YES"/>
|
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMinY="YES"/>
|
||||||
<subviews>
|
<subviews>
|
||||||
<textField horizontalHuggingPriority="251" verticalHuggingPriority="750" id="H3v-X3-48q">
|
<textField focusRingType="none" horizontalHuggingPriority="251" verticalHuggingPriority="750" id="H3v-X3-48q">
|
||||||
<rect key="frame" x="18" y="192" width="296" height="19"/>
|
<rect key="frame" x="18" y="192" width="296" height="19"/>
|
||||||
<autoresizingMask key="autoresizingMask" flexibleMinY="YES"/>
|
<autoresizingMask key="autoresizingMask" flexibleMinY="YES"/>
|
||||||
<textFieldCell key="cell" lineBreakMode="clipping" alignment="center" title="Title" id="BwZ-Zj-sP6">
|
<textFieldCell key="cell" lineBreakMode="clipping" alignment="center" title="Title" id="BwZ-Zj-sP6">
|
||||||
|
@ -34,7 +34,7 @@
|
||||||
<color key="backgroundColor" name="textBackgroundColor" catalog="System" colorSpace="catalog"/>
|
<color key="backgroundColor" name="textBackgroundColor" catalog="System" colorSpace="catalog"/>
|
||||||
</textFieldCell>
|
</textFieldCell>
|
||||||
</textField>
|
</textField>
|
||||||
<textField horizontalHuggingPriority="251" verticalHuggingPriority="750" id="gaD-ZH-Beh">
|
<textField focusRingType="none" horizontalHuggingPriority="251" verticalHuggingPriority="750" id="gaD-ZH-Beh">
|
||||||
<rect key="frame" x="18" y="166" width="296" height="16"/>
|
<rect key="frame" x="18" y="166" width="296" height="16"/>
|
||||||
<autoresizingMask key="autoresizingMask" flexibleMinY="YES"/>
|
<autoresizingMask key="autoresizingMask" flexibleMinY="YES"/>
|
||||||
<textFieldCell key="cell" lineBreakMode="clipping" alignment="center" title="Author" id="IgT-r1-T38">
|
<textFieldCell key="cell" lineBreakMode="clipping" alignment="center" title="Author" id="IgT-r1-T38">
|
||||||
|
@ -59,7 +59,7 @@
|
||||||
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMinY="YES"/>
|
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMinY="YES"/>
|
||||||
<popUpButtonCell key="cell" type="roundTextured" bezelStyle="texturedRounded" alignment="center" lineBreakMode="truncatingTail" borderStyle="border" focusRingType="none" imageScaling="proportionallyDown" inset="2" id="YJh-dI-A5D">
|
<popUpButtonCell key="cell" type="roundTextured" bezelStyle="texturedRounded" alignment="center" lineBreakMode="truncatingTail" borderStyle="border" focusRingType="none" imageScaling="proportionallyDown" inset="2" id="YJh-dI-A5D">
|
||||||
<behavior key="behavior" pushIn="YES" lightByBackground="YES" lightByGray="YES"/>
|
<behavior key="behavior" pushIn="YES" lightByBackground="YES" lightByGray="YES"/>
|
||||||
<font key="font" metaFont="menu"/>
|
<font key="font" metaFont="message"/>
|
||||||
<menu key="menu" id="Knp-Ok-Pb4"/>
|
<menu key="menu" id="Knp-Ok-Pb4"/>
|
||||||
</popUpButtonCell>
|
</popUpButtonCell>
|
||||||
<connections>
|
<connections>
|
||||||
|
@ -67,7 +67,7 @@
|
||||||
</connections>
|
</connections>
|
||||||
</popUpButton>
|
</popUpButton>
|
||||||
<segmentedControl verticalHuggingPriority="750" fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="SRS-M5-VVL">
|
<segmentedControl verticalHuggingPriority="750" fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="SRS-M5-VVL">
|
||||||
<rect key="frame" x="247" y="129" width="68" height="24"/>
|
<rect key="frame" x="247" y="128" width="68" height="25"/>
|
||||||
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMinY="YES"/>
|
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMinY="YES"/>
|
||||||
<segmentedCell key="cell" borderStyle="border" alignment="left" style="rounded" trackingMode="momentary" id="cmq-I8-cFL">
|
<segmentedCell key="cell" borderStyle="border" alignment="left" style="rounded" trackingMode="momentary" id="cmq-I8-cFL">
|
||||||
<font key="font" metaFont="system"/>
|
<font key="font" metaFont="system"/>
|
||||||
|
@ -94,7 +94,7 @@
|
||||||
</customView>
|
</customView>
|
||||||
</subviews>
|
</subviews>
|
||||||
</customView>
|
</customView>
|
||||||
<textField horizontalHuggingPriority="251" verticalHuggingPriority="750" id="2dl-dH-E3J">
|
<textField focusRingType="none" horizontalHuggingPriority="251" verticalHuggingPriority="750" id="2dl-dH-E3J">
|
||||||
<rect key="frame" x="18" y="5" width="296" height="14"/>
|
<rect key="frame" x="18" y="5" width="296" height="14"/>
|
||||||
<autoresizingMask key="autoresizingMask" flexibleMinY="YES"/>
|
<autoresizingMask key="autoresizingMask" flexibleMinY="YES"/>
|
||||||
<textFieldCell key="cell" controlSize="small" lineBreakMode="clipping" alignment="center" title="Copyright" id="nM9-oF-OV9">
|
<textFieldCell key="cell" controlSize="small" lineBreakMode="clipping" alignment="center" title="Copyright" id="nM9-oF-OV9">
|
||||||
|
|
|
@ -11,23 +11,23 @@
|
||||||
|
|
||||||
@implementation GBTerminalTextFieldCell
|
@implementation GBTerminalTextFieldCell
|
||||||
{
|
{
|
||||||
GBTerminalTextView *field_editor;
|
GBTerminalTextView *_fieldEditor;
|
||||||
}
|
}
|
||||||
|
|
||||||
- (NSTextView *)fieldEditorForView:(NSTextField *)controlView
|
- (NSTextView *)fieldEditorForView:(NSTextField *)controlView
|
||||||
{
|
{
|
||||||
if (field_editor) {
|
if (_fieldEditor) {
|
||||||
field_editor.gb = self.gb;
|
_fieldEditor.gb = self.gb;
|
||||||
return field_editor;
|
return _fieldEditor;
|
||||||
}
|
}
|
||||||
field_editor = [[GBTerminalTextView alloc] init];
|
_fieldEditor = [[GBTerminalTextView alloc] init];
|
||||||
[field_editor setFieldEditor:true];
|
[_fieldEditor setFieldEditor:true];
|
||||||
field_editor.gb = self.gb;
|
_fieldEditor.gb = self.gb;
|
||||||
field_editor->_field = (NSTextField *)controlView;
|
_fieldEditor->_field = (NSTextField *)controlView;
|
||||||
((NSTextFieldCell *)controlView.cell).textInset =
|
((NSTextFieldCell *)controlView.cell).textInset =
|
||||||
field_editor.textContainerInset =
|
_fieldEditor.textContainerInset =
|
||||||
NSMakeSize(0, 2);
|
NSMakeSize(7, 2);
|
||||||
return field_editor;
|
return _fieldEditor;
|
||||||
}
|
}
|
||||||
|
|
||||||
@end
|
@end
|
||||||
|
@ -45,7 +45,7 @@
|
||||||
{
|
{
|
||||||
self = [super init];
|
self = [super init];
|
||||||
if (!self) {
|
if (!self) {
|
||||||
return NULL;
|
return nil;
|
||||||
}
|
}
|
||||||
lines = [[NSMutableOrderedSet alloc] init];
|
lines = [[NSMutableOrderedSet alloc] init];
|
||||||
return self;
|
return self;
|
||||||
|
|
|
@ -0,0 +1,5 @@
|
||||||
|
#import <Cocoa/Cocoa.h>
|
||||||
|
|
||||||
|
@interface GBTitledPopUpButton : NSPopUpButton
|
||||||
|
@property NSString *displayTitle;
|
||||||
|
@end
|
|
@ -0,0 +1,22 @@
|
||||||
|
#import "GBTitledPopUpButton.h"
|
||||||
|
|
||||||
|
@implementation GBTitledPopUpButton
|
||||||
|
|
||||||
|
- (void)setDisplayTitle:(NSString *)displayTitle
|
||||||
|
{
|
||||||
|
if (!displayTitle) {
|
||||||
|
((NSPopUpButtonCell *)self.cell).usesItemFromMenu = true;
|
||||||
|
((NSPopUpButtonCell *)self.cell).menuItem = nil;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
((NSPopUpButtonCell *)self.cell).usesItemFromMenu = false;
|
||||||
|
((NSPopUpButtonCell *)self.cell).menuItem = [[NSMenuItem alloc] initWithTitle:displayTitle action:nil keyEquivalent:@""];
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
- (NSString *)displayTitle
|
||||||
|
{
|
||||||
|
return ((NSPopUpButtonCell *)self.cell).menuItem.title;
|
||||||
|
}
|
||||||
|
|
||||||
|
@end
|
|
@ -0,0 +1,5 @@
|
||||||
|
#import <Cocoa/Cocoa.h>
|
||||||
|
|
||||||
|
@interface GBToolbarFieldCell : NSSearchFieldCell
|
||||||
|
|
||||||
|
@end
|
|
@ -0,0 +1,40 @@
|
||||||
|
#import "GBToolbarFieldCell.h"
|
||||||
|
#import <objc/runtime.h>
|
||||||
|
|
||||||
|
@interface NSTextFieldCell()
|
||||||
|
- (void)textDidChange:(id)sender;
|
||||||
|
@end
|
||||||
|
|
||||||
|
@implementation GBToolbarFieldCell
|
||||||
|
|
||||||
|
- (void)textDidChange:(id)sender
|
||||||
|
{
|
||||||
|
IMP imp = [NSTextFieldCell instanceMethodForSelector:_cmd];
|
||||||
|
method_setImplementation(class_getInstanceMethod([GBToolbarFieldCell class], _cmd), imp);
|
||||||
|
((void(*)(id, SEL, id))imp)(self, _cmd, sender);
|
||||||
|
}
|
||||||
|
|
||||||
|
- (void)endEditing:(NSText *)textObj
|
||||||
|
{
|
||||||
|
IMP imp = [NSTextFieldCell instanceMethodForSelector:_cmd];
|
||||||
|
method_setImplementation(class_getInstanceMethod([GBToolbarFieldCell class], _cmd), imp);
|
||||||
|
((void(*)(id, SEL, id))imp)(self, _cmd, textObj);
|
||||||
|
}
|
||||||
|
|
||||||
|
- (void)resetSearchButtonCell
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
- (void)resetCancelButtonCell
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
// We only need this hack on Solarium, avoid regressions
|
||||||
|
+ (instancetype)allocWithZone:(struct _NSZone *)zone
|
||||||
|
{
|
||||||
|
if (@available(macOS 26.0, *)) {
|
||||||
|
return [super allocWithZone:zone];
|
||||||
|
}
|
||||||
|
return (id)[NSTextFieldCell allocWithZone:zone];
|
||||||
|
}
|
||||||
|
@end
|
|
@ -0,0 +1,5 @@
|
||||||
|
#import <Cocoa/Cocoa.h>
|
||||||
|
|
||||||
|
@interface GBToolbarPopUpButtonCell : NSPopUpButtonCell
|
||||||
|
|
||||||
|
@end
|
|
@ -0,0 +1,17 @@
|
||||||
|
#import "GBToolbarPopUpButtonCell.h"
|
||||||
|
|
||||||
|
@implementation GBToolbarPopUpButtonCell
|
||||||
|
|
||||||
|
-(void)drawInteriorWithFrame:(NSRect)cellFrame inView:(NSView *)controlView
|
||||||
|
{
|
||||||
|
[super drawInteriorWithFrame:CGRectInset(cellFrame, 5, 0) inView:controlView];
|
||||||
|
}
|
||||||
|
|
||||||
|
+ (instancetype)allocWithZone:(struct _NSZone *)zone
|
||||||
|
{
|
||||||
|
if (@available(macOS 26.0, *)) {
|
||||||
|
return [super allocWithZone:zone];
|
||||||
|
}
|
||||||
|
return (id)[NSPopUpButtonCell allocWithZone:zone];
|
||||||
|
}
|
||||||
|
@end
|
177
Cocoa/GBView.m
|
@ -119,6 +119,9 @@ static const uint8_t workboy_vk_to_key[] = {
|
||||||
bool _mouseControlEnabled;
|
bool _mouseControlEnabled;
|
||||||
NSMutableDictionary<NSNumber *, JOYController *> *_controllerMapping;
|
NSMutableDictionary<NSNumber *, JOYController *> *_controllerMapping;
|
||||||
unsigned _lastPlayerCount;
|
unsigned _lastPlayerCount;
|
||||||
|
|
||||||
|
bool _rapidA[4], _rapidB[4];
|
||||||
|
uint8_t _rapidACount[4], _rapidBCount[4];
|
||||||
}
|
}
|
||||||
|
|
||||||
+ (instancetype)alloc
|
+ (instancetype)alloc
|
||||||
|
@ -145,6 +148,9 @@ static const uint8_t workboy_vk_to_key[] = {
|
||||||
[self observeStandardDefaultsKey:@"GBAspectRatioUnkept" withBlock:^(id newValue) {
|
[self observeStandardDefaultsKey:@"GBAspectRatioUnkept" withBlock:^(id newValue) {
|
||||||
[weakSelf setFrame:weakSelf.superview.frame];
|
[weakSelf setFrame:weakSelf.superview.frame];
|
||||||
}];
|
}];
|
||||||
|
[self observeStandardDefaultsKey:@"GBForceIntegerScale" withBlock:^(id newValue) {
|
||||||
|
[weakSelf setFrame:weakSelf.superview.frame];
|
||||||
|
}];
|
||||||
[self observeStandardDefaultsKey:@"JoyKitDefaultControllers" withBlock:^(id newValue) {
|
[self observeStandardDefaultsKey:@"JoyKitDefaultControllers" withBlock:^(id newValue) {
|
||||||
[weakSelf reassignControllers];
|
[weakSelf reassignControllers];
|
||||||
}];
|
}];
|
||||||
|
@ -279,7 +285,9 @@ static const uint8_t workboy_vk_to_key[] = {
|
||||||
|
|
||||||
- (void)setFrame:(NSRect)frame
|
- (void)setFrame:(NSRect)frame
|
||||||
{
|
{
|
||||||
frame = self.superview.frame;
|
NSView *superview = self.superview;
|
||||||
|
if (GB_unlikely(!superview)) return;
|
||||||
|
frame = superview.frame;
|
||||||
if (_gb && ![[NSUserDefaults standardUserDefaults] boolForKey:@"GBAspectRatioUnkept"]) {
|
if (_gb && ![[NSUserDefaults standardUserDefaults] boolForKey:@"GBAspectRatioUnkept"]) {
|
||||||
double ratio = frame.size.width / frame.size.height;
|
double ratio = frame.size.width / frame.size.height;
|
||||||
double width = GB_get_screen_width(_gb);
|
double width = GB_get_screen_width(_gb);
|
||||||
|
@ -297,6 +305,19 @@ static const uint8_t workboy_vk_to_key[] = {
|
||||||
frame.origin.x = 0;
|
frame.origin.x = 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (_gb && [[NSUserDefaults standardUserDefaults] boolForKey:@"GBForceIntegerScale"]) {
|
||||||
|
double factor = self.window.backingScaleFactor;
|
||||||
|
double width = GB_get_screen_width(_gb) / factor;
|
||||||
|
double height = GB_get_screen_height(_gb) / factor;
|
||||||
|
|
||||||
|
double new_width = floor(frame.size.width / width) * width;
|
||||||
|
double new_height = floor(frame.size.height / height) * height;
|
||||||
|
frame.origin.x += floor((frame.size.width - new_width) / 2);
|
||||||
|
frame.origin.y += floor((frame.size.height - new_height) / 2);
|
||||||
|
frame.size.width = new_width;
|
||||||
|
frame.size.height = new_height;
|
||||||
|
}
|
||||||
|
|
||||||
[super setFrame:frame];
|
[super setFrame:frame];
|
||||||
}
|
}
|
||||||
|
@ -343,6 +364,17 @@ static const uint8_t workboy_vk_to_key[] = {
|
||||||
(analogClockMultiplierValid && analogClockMultiplier < 1)) {
|
(analogClockMultiplierValid && analogClockMultiplier < 1)) {
|
||||||
[self.osdView displayText:@"Slow motion…"];
|
[self.osdView displayText:@"Slow motion…"];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
for (unsigned i = GB_get_player_count(_gb); i--;) {
|
||||||
|
if (_rapidA[i]) {
|
||||||
|
_rapidACount[i]++;
|
||||||
|
GB_set_key_state_for_player(_gb, GB_KEY_A, i, !(_rapidACount[i] & 2));
|
||||||
|
}
|
||||||
|
if (_rapidB[i]) {
|
||||||
|
_rapidBCount[i]++;
|
||||||
|
GB_set_key_state_for_player(_gb, GB_KEY_B, i, !(_rapidBCount[i] & 2));
|
||||||
|
}
|
||||||
|
}
|
||||||
[super flip];
|
[super flip];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -370,7 +402,7 @@ static const uint8_t workboy_vk_to_key[] = {
|
||||||
player_count = 2;
|
player_count = 2;
|
||||||
}
|
}
|
||||||
for (unsigned player = 0; player < player_count; player++) {
|
for (unsigned player = 0; player < player_count; player++) {
|
||||||
for (GBButton button = 0; button < GBButtonCount; button++) {
|
for (GBButton button = 0; button < GBKeyboardButtonCount; button++) {
|
||||||
NSNumber *key = [defaults valueForKey:button_to_preference_name(button, player)];
|
NSNumber *key = [defaults valueForKey:button_to_preference_name(button, player)];
|
||||||
if (!key) continue;
|
if (!key) continue;
|
||||||
|
|
||||||
|
@ -401,17 +433,38 @@ static const uint8_t workboy_vk_to_key[] = {
|
||||||
analogClockMultiplierValid = false;
|
analogClockMultiplierValid = false;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
case GBRapidA:
|
||||||
|
_rapidA[player] = true;
|
||||||
|
_rapidACount[player] = 0;
|
||||||
|
GB_set_key_state_for_player(_gb, GB_KEY_A, player, true);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case GBRapidB:
|
||||||
|
_rapidB[player] = true;
|
||||||
|
_rapidBCount[player] = 0;
|
||||||
|
GB_set_key_state_for_player(_gb, GB_KEY_B, player, true);
|
||||||
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
if (self.document.partner) {
|
if (self.document.partner) {
|
||||||
if (player == 0) {
|
if (player == 0) {
|
||||||
GB_set_key_state_for_player(_gb, (GB_key_t)button, 0, true);
|
GB_set_key_state_for_player(_gb, (GB_key_t)button, 0, true);
|
||||||
|
if ((GB_key_t)button <= GB_KEY_DOWN) {
|
||||||
|
GB_set_use_faux_analog_inputs(_gb, 0, false);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
GB_set_key_state_for_player(self.document.partner.gb, (GB_key_t)button, 0, true);
|
GB_set_key_state_for_player(self.document.partner.gb, (GB_key_t)button, 0, true);
|
||||||
|
if ((GB_key_t)button <= GB_KEY_DOWN) {
|
||||||
|
GB_set_use_faux_analog_inputs(self.document.partner.gb, 0, false);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
GB_set_key_state_for_player(_gb, (GB_key_t)button, player, true);
|
GB_set_key_state_for_player(_gb, (GB_key_t)button, player, true);
|
||||||
|
if ((GB_key_t)button <= GB_KEY_DOWN) {
|
||||||
|
GB_set_use_faux_analog_inputs(_gb, player, false);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -444,7 +497,7 @@ static const uint8_t workboy_vk_to_key[] = {
|
||||||
player_count = 2;
|
player_count = 2;
|
||||||
}
|
}
|
||||||
for (unsigned player = 0; player < player_count; player++) {
|
for (unsigned player = 0; player < player_count; player++) {
|
||||||
for (GBButton button = 0; button < GBButtonCount; button++) {
|
for (GBButton button = 0; button < GBKeyboardButtonCount; button++) {
|
||||||
NSNumber *key = [defaults valueForKey:button_to_preference_name(button, player)];
|
NSNumber *key = [defaults valueForKey:button_to_preference_name(button, player)];
|
||||||
if (!key) continue;
|
if (!key) continue;
|
||||||
|
|
||||||
|
@ -470,6 +523,16 @@ static const uint8_t workboy_vk_to_key[] = {
|
||||||
underclockKeyDown = false;
|
underclockKeyDown = false;
|
||||||
analogClockMultiplierValid = false;
|
analogClockMultiplierValid = false;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
case GBRapidA:
|
||||||
|
_rapidA[player] = false;
|
||||||
|
GB_set_key_state_for_player(_gb, GB_KEY_A, player, false);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case GBRapidB:
|
||||||
|
_rapidB[player] = false;
|
||||||
|
GB_set_key_state_for_player(_gb, GB_KEY_B, player, false);
|
||||||
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
if (self.document.partner) {
|
if (self.document.partner) {
|
||||||
|
@ -545,12 +608,63 @@ static const uint8_t workboy_vk_to_key[] = {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
- (bool)controller:(JOYController *)controller applicableForPlayer:(unsigned)player effectivePlayer:(unsigned *)effectivePlayer effectiveGB:(GB_gameboy_t **)effectiveGB
|
||||||
|
{
|
||||||
|
NSDictionary<NSNumber *, JOYController *> *controllerMapping = [self controllerMapping];
|
||||||
|
|
||||||
|
JOYController *preferredJoypad = controllerMapping[@(player)];
|
||||||
|
if (preferredJoypad && preferredJoypad != controller) return false; // The player has a different assigned controller
|
||||||
|
if (!preferredJoypad && self.playerCount != 1) return false; // The player has no assigned controller in multiplayer mode, prevent controller inputs
|
||||||
|
|
||||||
|
dispatch_async(dispatch_get_main_queue(), ^{
|
||||||
|
[controller setPlayerLEDs:[controller LEDMaskForPlayer:player]];
|
||||||
|
});
|
||||||
|
|
||||||
|
*effectiveGB = _gb;
|
||||||
|
*effectivePlayer = player;
|
||||||
|
|
||||||
|
if (player && self.document.partner) {
|
||||||
|
*effectiveGB = self.document.partner.gb;
|
||||||
|
*effectivePlayer = 0;
|
||||||
|
if (controller != self.document.partner.view->lastController) {
|
||||||
|
[self setRumble:0];
|
||||||
|
self.document.partner.view->lastController = controller;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
if (controller != lastController) {
|
||||||
|
[self setRumble:0];
|
||||||
|
lastController = controller;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
- (void)controller:(JOYController *)controller movedAxes2D:(JOYAxes2D *)axes
|
- (void)controller:(JOYController *)controller movedAxes2D:(JOYAxes2D *)axes
|
||||||
{
|
{
|
||||||
if (!_gb) return;
|
if (!_gb) return;
|
||||||
if ([self shouldControllerUseJoystickForMotion:controller]) {
|
/* Always handle only the most dominant 2D input. */
|
||||||
if (!self.mouseControlsActive) {
|
for (JOYAxes2D *otherAxes in controller.axes2D) {
|
||||||
GB_set_accelerometer_values(_gb, -axes.value.x, -axes.value.y);
|
if (otherAxes == axes) continue;
|
||||||
|
if (otherAxes.distance > axes.distance) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];
|
||||||
|
|
||||||
|
if ([self shouldControllerUseJoystickForMotion:controller] && !self.mouseControlsActive) {
|
||||||
|
GB_set_accelerometer_values(_gb, -axes.value.x, -axes.value.y);
|
||||||
|
}
|
||||||
|
else if ([defaults boolForKey:@"GBFauxAnalogInputs"]) {
|
||||||
|
unsigned playerCount = self.playerCount;
|
||||||
|
for (unsigned player = 0; player < playerCount; player++) {
|
||||||
|
unsigned effectivePlayer;
|
||||||
|
GB_gameboy_t *effectiveGB;
|
||||||
|
if (![self controller:controller applicableForPlayer:player effectivePlayer:&effectivePlayer effectiveGB:&effectiveGB]) continue;
|
||||||
|
|
||||||
|
GB_set_use_faux_analog_inputs(effectiveGB, effectivePlayer, true);
|
||||||
|
NSPoint position = axes.value;
|
||||||
|
GB_set_faux_analog_inputs(effectiveGB, effectivePlayer, position.x, position.y);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -614,18 +728,17 @@ static const uint8_t workboy_vk_to_key[] = {
|
||||||
IOPMAssertionDeclareUserActivity(CFSTR(""), kIOPMUserActiveLocal, &assertionID);
|
IOPMAssertionDeclareUserActivity(CFSTR(""), kIOPMUserActiveLocal, &assertionID);
|
||||||
|
|
||||||
|
|
||||||
NSDictionary<NSNumber *, JOYController *> *controllerMapping = [self controllerMapping];
|
NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];
|
||||||
|
bool fauxAnalog = [defaults boolForKey:@"GBFauxAnalogInputs"];
|
||||||
|
|
||||||
for (unsigned player = 0; player < playerCount; player++) {
|
for (unsigned player = 0; player < playerCount; player++) {
|
||||||
JOYController *preferredJoypad = controllerMapping[@(player)];
|
unsigned effectivePlayer;
|
||||||
if (preferredJoypad && preferredJoypad != controller) continue; // The player has a different assigned controller
|
GB_gameboy_t *effectiveGB;
|
||||||
if (!preferredJoypad && playerCount != 1) continue; // The player has no assigned controller in multiplayer mode, prevent controller inputs
|
if (![self controller:controller applicableForPlayer:player effectivePlayer:&effectivePlayer effectiveGB:&effectiveGB]) continue;
|
||||||
|
|
||||||
dispatch_async(dispatch_get_main_queue(), ^{
|
NSDictionary *mapping = [defaults dictionaryForKey:@"JoyKitInstanceMapping"][controller.uniqueID];
|
||||||
[controller setPlayerLEDs:[controller LEDMaskForPlayer:player]];
|
|
||||||
});
|
|
||||||
NSDictionary *mapping = [[NSUserDefaults standardUserDefaults] dictionaryForKey:@"JoyKitInstanceMapping"][controller.uniqueID];
|
|
||||||
if (!mapping) {
|
if (!mapping) {
|
||||||
mapping = [[NSUserDefaults standardUserDefaults] dictionaryForKey:@"JoyKitNameMapping"][controller.deviceName];
|
mapping = [defaults dictionaryForKey:@"JoyKitNameMapping"][controller.deviceName];
|
||||||
}
|
}
|
||||||
|
|
||||||
JOYButtonUsage usage = ((JOYButtonUsage)[mapping[n2s(button.uniqueID)] unsignedIntValue]) ?: button.usage;
|
JOYButtonUsage usage = ((JOYButtonUsage)[mapping[n2s(button.uniqueID)] unsignedIntValue]) ?: button.usage;
|
||||||
|
@ -633,25 +746,18 @@ static const uint8_t workboy_vk_to_key[] = {
|
||||||
usage = GB_inline_const(JOYButtonUsage[], {JOYButtonUsageY, JOYButtonUsageA, JOYButtonUsageB, JOYButtonUsageX})[(usage - JOYButtonUsageGeneric0) & 3];
|
usage = GB_inline_const(JOYButtonUsage[], {JOYButtonUsageY, JOYButtonUsageA, JOYButtonUsageB, JOYButtonUsageX})[(usage - JOYButtonUsageGeneric0) & 3];
|
||||||
}
|
}
|
||||||
|
|
||||||
GB_gameboy_t *effectiveGB = _gb;
|
if (usage >= JOYButtonUsageDPadLeft && usage <= JOYButtonUsageDPadDown) {
|
||||||
unsigned effectivePlayer = player;
|
if (fauxAnalog && button.type == JOYButtonTypeAxes2DEmulated) {
|
||||||
|
// This isn't a real button, it's an emulated Axes2D. We want to handle it as an Axes2D instead
|
||||||
if (player && self.document.partner) {
|
continue;
|
||||||
effectiveGB = self.document.partner.gb;
|
|
||||||
effectivePlayer = 0;
|
|
||||||
if (controller != self.document.partner.view->lastController) {
|
|
||||||
[self setRumble:0];
|
|
||||||
self.document.partner.view->lastController = controller;
|
|
||||||
}
|
}
|
||||||
}
|
else {
|
||||||
else {
|
// User used a digital direction input, revert to non-analog inputs
|
||||||
if (controller != lastController) {
|
GB_set_use_faux_analog_inputs(effectiveGB, effectivePlayer, false);
|
||||||
[self setRumble:0];
|
|
||||||
lastController = controller;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
switch (usage) {
|
switch ((unsigned)usage) {
|
||||||
|
|
||||||
case JOYButtonUsageNone: break;
|
case JOYButtonUsageNone: break;
|
||||||
case JOYButtonUsageA: GB_set_key_state_for_player(effectiveGB, GB_KEY_A, effectivePlayer, button.isPressed); break;
|
case JOYButtonUsageA: GB_set_key_state_for_player(effectiveGB, GB_KEY_A, effectivePlayer, button.isPressed); break;
|
||||||
|
@ -696,7 +802,16 @@ static const uint8_t workboy_vk_to_key[] = {
|
||||||
case JOYButtonUsageDPadUp: GB_set_key_state_for_player(effectiveGB, GB_KEY_UP, effectivePlayer, button.isPressed); break;
|
case JOYButtonUsageDPadUp: GB_set_key_state_for_player(effectiveGB, GB_KEY_UP, effectivePlayer, button.isPressed); break;
|
||||||
case JOYButtonUsageDPadDown: GB_set_key_state_for_player(effectiveGB, GB_KEY_DOWN, effectivePlayer, button.isPressed); break;
|
case JOYButtonUsageDPadDown: GB_set_key_state_for_player(effectiveGB, GB_KEY_DOWN, effectivePlayer, button.isPressed); break;
|
||||||
|
|
||||||
default:
|
case GBJoyKitRapidA:
|
||||||
|
_rapidA[effectivePlayer] = button.isPressed;
|
||||||
|
_rapidACount[effectivePlayer] = 0;
|
||||||
|
GB_set_key_state_for_player(_gb, GB_KEY_A, effectivePlayer, button.isPressed);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case GBJoyKitRapidB:
|
||||||
|
_rapidB[effectivePlayer] = button.isPressed;
|
||||||
|
_rapidBCount[effectivePlayer] = 0;
|
||||||
|
GB_set_key_state_for_player(_gb, GB_KEY_B, effectivePlayer, button.isPressed);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,5 @@
|
||||||
|
#import <Cocoa/Cocoa.h>
|
||||||
|
|
||||||
|
@interface GBWindow : NSWindow
|
||||||
|
|
||||||
|
@end
|
|
@ -0,0 +1,22 @@
|
||||||
|
#import "GBWindow.h"
|
||||||
|
|
||||||
|
@interface NSWindow(private)
|
||||||
|
- (void)_zoomFill:(id)sender;
|
||||||
|
@end
|
||||||
|
|
||||||
|
/*
|
||||||
|
For some reason, Apple replaced the alt + zoom button behavior to be "fill" rather than zoom.
|
||||||
|
I don't like that. It prevents SameBoy's integer scaling from working. Let's restore it.
|
||||||
|
*/
|
||||||
|
|
||||||
|
@implementation GBWindow
|
||||||
|
- (void)_zoomFill:(id)sender
|
||||||
|
{
|
||||||
|
if (sender == [self standardWindowButton:NSWindowZoomButton] &&
|
||||||
|
((self.currentEvent.modifierFlags & NSEventModifierFlagDeviceIndependentFlagsMask) == NSEventModifierFlagOption)) {
|
||||||
|
[self zoom:sender];
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
[super _zoomFill:sender];
|
||||||
|
}
|
||||||
|
@end
|
BIN
Cocoa/Icon.png
Before Width: | Height: | Size: 3.1 KiB After Width: | Height: | Size: 3.1 KiB |
Before Width: | Height: | Size: 9.3 KiB After Width: | Height: | Size: 9.3 KiB |
|
@ -22,7 +22,8 @@
|
||||||
<key>LSItemContentTypes</key>
|
<key>LSItemContentTypes</key>
|
||||||
<array>
|
<array>
|
||||||
<string>com.github.liji32.sameboy.gb</string>
|
<string>com.github.liji32.sameboy.gb</string>
|
||||||
<string>public.gbrom</string>
|
<string>public.gbrom</string>
|
||||||
|
<string>com.retroarch.gb</string>
|
||||||
</array>
|
</array>
|
||||||
<key>LSTypeIsPackage</key>
|
<key>LSTypeIsPackage</key>
|
||||||
<integer>0</integer>
|
<integer>0</integer>
|
||||||
|
@ -43,6 +44,7 @@
|
||||||
<key>LSItemContentTypes</key>
|
<key>LSItemContentTypes</key>
|
||||||
<array>
|
<array>
|
||||||
<string>com.github.liji32.sameboy.gbc</string>
|
<string>com.github.liji32.sameboy.gbc</string>
|
||||||
|
<string>com.retroarch.gbc</string>
|
||||||
</array>
|
</array>
|
||||||
<key>LSTypeIsPackage</key>
|
<key>LSTypeIsPackage</key>
|
||||||
<integer>0</integer>
|
<integer>0</integer>
|
||||||
|
@ -111,7 +113,9 @@
|
||||||
<key>CFBundleExecutable</key>
|
<key>CFBundleExecutable</key>
|
||||||
<string>SameBoy</string>
|
<string>SameBoy</string>
|
||||||
<key>CFBundleIconFile</key>
|
<key>CFBundleIconFile</key>
|
||||||
<string>AppIcon.icns</string>
|
<string>AppIcon</string>
|
||||||
|
<key>CFBundleIconName</key>
|
||||||
|
<string>AppIcon</string>
|
||||||
<key>CFBundleIdentifier</key>
|
<key>CFBundleIdentifier</key>
|
||||||
<string>com.github.liji32.sameboy</string>
|
<string>com.github.liji32.sameboy</string>
|
||||||
<key>LSApplicationCategoryType</key>
|
<key>LSApplicationCategoryType</key>
|
||||||
|
|
Before Width: | Height: | Size: 1.5 KiB After Width: | Height: | Size: 1.5 KiB |
Before Width: | Height: | Size: 2.8 KiB After Width: | Height: | Size: 2.8 KiB |
Before Width: | Height: | Size: 406 B After Width: | Height: | Size: 281 B |
Before Width: | Height: | Size: 689 B After Width: | Height: | Size: 461 B |
|
@ -4,10 +4,10 @@
|
||||||
@interface NSKeyboardShortcut : NSObject <NSCopying>
|
@interface NSKeyboardShortcut : NSObject <NSCopying>
|
||||||
|
|
||||||
+ (id)shortcutWithPreferencesEncoding:(NSString *)encoding;
|
+ (id)shortcutWithPreferencesEncoding:(NSString *)encoding;
|
||||||
+ (id)shortcutWithKeyEquivalent:(NSString *)key_equivalent modifierMask:(unsigned long long)mask;
|
+ (id)shortcutWithKeyEquivalent:(NSString *)key_equivalent modifierMask:(NSUInteger)mask;
|
||||||
- (id)initWithKeyEquivalent:(NSString *)key_equivalent modifierMask:(unsigned long long)mask;
|
- (id)initWithKeyEquivalent:(NSString *)key_equivalent modifierMask:(NSUInteger)mask;
|
||||||
|
|
||||||
@property(readonly) unsigned long long modifierMask;
|
@property(readonly) NSUInteger modifierMask;
|
||||||
@property(readonly) NSString *keyEquivalent;
|
@property(readonly) NSString *keyEquivalent;
|
||||||
@property(readonly) NSString *preferencesEncoding;
|
@property(readonly) NSString *preferencesEncoding;
|
||||||
@property(readonly) NSString *localizedModifierMaskDisplayName;
|
@property(readonly) NSString *localizedModifierMaskDisplayName;
|
||||||
|
|
|
@ -1,8 +1,8 @@
|
||||||
<?xml version="1.0" encoding="UTF-8"?>
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
<document type="com.apple.InterfaceBuilder3.Cocoa.XIB" version="3.0" toolsVersion="21507" targetRuntime="MacOSX.Cocoa" propertyAccessControl="none" useAutolayout="YES" customObjectInstantitationMethod="direct">
|
<document type="com.apple.InterfaceBuilder3.Cocoa.XIB" version="3.0" toolsVersion="24093.9" targetRuntime="MacOSX.Cocoa" propertyAccessControl="none" useAutolayout="YES" customObjectInstantitationMethod="direct">
|
||||||
<dependencies>
|
<dependencies>
|
||||||
<deployment identifier="macosx"/>
|
<deployment identifier="macosx"/>
|
||||||
<plugIn identifier="com.apple.InterfaceBuilder.CocoaPlugin" version="21507"/>
|
<plugIn identifier="com.apple.InterfaceBuilder.CocoaPlugin" version="24093.9"/>
|
||||||
</dependencies>
|
</dependencies>
|
||||||
<objects>
|
<objects>
|
||||||
<customObject id="-2" userLabel="File's Owner" customClass="NSApplication">
|
<customObject id="-2" userLabel="File's Owner" customClass="NSApplication">
|
||||||
|
@ -82,7 +82,7 @@
|
||||||
<action selector="openDocument:" target="-1" id="bVn-NM-KNZ"/>
|
<action selector="openDocument:" target="-1" id="bVn-NM-KNZ"/>
|
||||||
</connections>
|
</connections>
|
||||||
</menuItem>
|
</menuItem>
|
||||||
<menuItem title="Hot Swap Cartridge…" keyEquivalent="o" id="Rik-p8-QCf">
|
<menuItem title="Hot Swap Cartridge…" secondaryImage="arrow.down.left.arrow.up.right" catalog="system" keyEquivalent="o" id="Rik-p8-QCf">
|
||||||
<modifierMask key="keyEquivalentModifierMask" option="YES" command="YES"/>
|
<modifierMask key="keyEquivalentModifierMask" option="YES" command="YES"/>
|
||||||
<connections>
|
<connections>
|
||||||
<action selector="cartSwap:" target="-1" id="iXS-Ol-IS0"/>
|
<action selector="cartSwap:" target="-1" id="iXS-Ol-IS0"/>
|
||||||
|
@ -102,7 +102,7 @@
|
||||||
</menu>
|
</menu>
|
||||||
</menuItem>
|
</menuItem>
|
||||||
<menuItem isSeparatorItem="YES" id="m54-Is-iLE"/>
|
<menuItem isSeparatorItem="YES" id="m54-Is-iLE"/>
|
||||||
<menuItem title="New Cartridge Instance…" keyEquivalent="n" id="Vld-be-NZu">
|
<menuItem title="New Cartridge Instance…" secondaryImage="plus.square.on.square" catalog="system" keyEquivalent="n" id="Vld-be-NZu">
|
||||||
<connections>
|
<connections>
|
||||||
<action selector="newCartridgeInstance:" target="-1" id="GJc-xU-ZEr"/>
|
<action selector="newCartridgeInstance:" target="-1" id="GJc-xU-ZEr"/>
|
||||||
</connections>
|
</connections>
|
||||||
|
@ -158,7 +158,7 @@
|
||||||
</connections>
|
</connections>
|
||||||
</menuItem>
|
</menuItem>
|
||||||
<menuItem isSeparatorItem="YES" id="Aru-vr-frG"/>
|
<menuItem isSeparatorItem="YES" id="Aru-vr-frG"/>
|
||||||
<menuItem title="Find" id="efg-jw-GVP">
|
<menuItem title="Find" secondaryImage="text.page.badge.magnifyingglass" catalog="system" id="efg-jw-GVP">
|
||||||
<modifierMask key="keyEquivalentModifierMask"/>
|
<modifierMask key="keyEquivalentModifierMask"/>
|
||||||
<menu key="submenu" title="Find" id="4R6-IU-Jq6">
|
<menu key="submenu" title="Find" id="4R6-IU-Jq6">
|
||||||
<items>
|
<items>
|
||||||
|
@ -197,29 +197,73 @@
|
||||||
<modifierMask key="keyEquivalentModifierMask"/>
|
<modifierMask key="keyEquivalentModifierMask"/>
|
||||||
<menu key="submenu" title="Emulation" id="HyV-fh-RgO">
|
<menu key="submenu" title="Emulation" id="HyV-fh-RgO">
|
||||||
<items>
|
<items>
|
||||||
<menuItem title="Reset" keyEquivalent="r" id="p0i-Lt-sTg">
|
<menuItem title="Reset" secondaryImage="arrow.trianglehead.2.counterclockwise.rotate.90" catalog="system" keyEquivalent="r" id="p0i-Lt-sTg">
|
||||||
<connections>
|
<connections>
|
||||||
<action selector="reset:" target="-1" id="DKW-Bd-h3v"/>
|
<action selector="reset:" target="-1" id="DKW-Bd-h3v"/>
|
||||||
</connections>
|
</connections>
|
||||||
</menuItem>
|
</menuItem>
|
||||||
<menuItem title="Quick Reset" tag="-1" alternate="YES" keyEquivalent="r" id="uPG-01-49E">
|
<menuItem title="Quick Reset" secondaryImage="arrow.trianglehead.2.counterclockwise.rotate.90" catalog="system" tag="-1" alternate="YES" keyEquivalent="r" id="uPG-01-49E">
|
||||||
<modifierMask key="keyEquivalentModifierMask" option="YES" command="YES"/>
|
<modifierMask key="keyEquivalentModifierMask" option="YES" command="YES"/>
|
||||||
<connections>
|
<connections>
|
||||||
<action selector="reset:" target="-1" id="VV1-VP-L7g"/>
|
<action selector="reset:" target="-1" id="VV1-VP-L7g"/>
|
||||||
</connections>
|
</connections>
|
||||||
</menuItem>
|
</menuItem>
|
||||||
<menuItem title="Reload ROM" alternate="YES" keyEquivalent="R" id="eQP-Fb-nkz">
|
<menuItem title="Reload ROM" secondaryImage="arrow.trianglehead.2.counterclockwise.rotate.90" catalog="system" alternate="YES" keyEquivalent="R" id="eQP-Fb-nkz">
|
||||||
<connections>
|
<connections>
|
||||||
<action selector="reloadROM:" target="-1" id="BpN-8V-Csg"/>
|
<action selector="reloadROM:" target="-1" id="BpN-8V-Csg"/>
|
||||||
</connections>
|
</connections>
|
||||||
</menuItem>
|
</menuItem>
|
||||||
<menuItem title="Pause" keyEquivalent="p" id="4K4-hw-R7Q">
|
<menuItem title="Pause" secondaryImage="pause" catalog="system" keyEquivalent="p" id="4K4-hw-R7Q">
|
||||||
<connections>
|
<connections>
|
||||||
<action selector="togglePause:" target="-1" id="osW-wt-QAa"/>
|
<action selector="togglePause:" target="-1" id="osW-wt-QAa"/>
|
||||||
</connections>
|
</connections>
|
||||||
</menuItem>
|
</menuItem>
|
||||||
|
<menuItem title="Emulated Model" id="Cip-1S-4Zp">
|
||||||
|
<modifierMask key="keyEquivalentModifierMask"/>
|
||||||
|
<menu key="submenu" title="Emulated Model" id="MtH-V4-vUi">
|
||||||
|
<items>
|
||||||
|
<menuItem title="Pick Automatically" tag="6" id="GXg-yH-3dl">
|
||||||
|
<modifierMask key="keyEquivalentModifierMask"/>
|
||||||
|
<connections>
|
||||||
|
<action selector="reset:" target="-1" id="ao2-FI-kk1"/>
|
||||||
|
</connections>
|
||||||
|
</menuItem>
|
||||||
|
<menuItem isSeparatorItem="YES" id="Nyl-zW-Uez"/>
|
||||||
|
<menuItem title="Game Boy" tag="1" id="g7C-LA-VAr">
|
||||||
|
<modifierMask key="keyEquivalentModifierMask"/>
|
||||||
|
<connections>
|
||||||
|
<action selector="reset:" target="-1" id="rxG-cz-s1S"/>
|
||||||
|
</connections>
|
||||||
|
</menuItem>
|
||||||
|
<menuItem title="Game Boy Pocket/Light" tag="5" id="1bM-CT-hoW">
|
||||||
|
<modifierMask key="keyEquivalentModifierMask"/>
|
||||||
|
<connections>
|
||||||
|
<action selector="reset:" target="-1" id="U7l-BM-kB1"/>
|
||||||
|
</connections>
|
||||||
|
</menuItem>
|
||||||
|
<menuItem title="Super Game Boy" tag="4" id="vc7-yy-ARW">
|
||||||
|
<modifierMask key="keyEquivalentModifierMask"/>
|
||||||
|
<connections>
|
||||||
|
<action selector="reset:" target="-1" id="E4M-QG-ua9"/>
|
||||||
|
</connections>
|
||||||
|
</menuItem>
|
||||||
|
<menuItem title="Game Boy Color" tag="2" id="hdG-Bl-8nJ">
|
||||||
|
<modifierMask key="keyEquivalentModifierMask"/>
|
||||||
|
<connections>
|
||||||
|
<action selector="reset:" target="-1" id="xAz-cr-0u2"/>
|
||||||
|
</connections>
|
||||||
|
</menuItem>
|
||||||
|
<menuItem title="Game Boy Advance" tag="3" id="7jw-B1-tf5">
|
||||||
|
<modifierMask key="keyEquivalentModifierMask"/>
|
||||||
|
<connections>
|
||||||
|
<action selector="reset:" target="-1" id="xQk-4e-kd7"/>
|
||||||
|
</connections>
|
||||||
|
</menuItem>
|
||||||
|
</items>
|
||||||
|
</menu>
|
||||||
|
</menuItem>
|
||||||
<menuItem isSeparatorItem="YES" id="QIS-av-Byy"/>
|
<menuItem isSeparatorItem="YES" id="QIS-av-Byy"/>
|
||||||
<menuItem title="Save State" id="Hdz-ut-okE">
|
<menuItem title="Save State" secondaryImage="square.and.arrow.down" catalog="system" id="Hdz-ut-okE">
|
||||||
<modifierMask key="keyEquivalentModifierMask"/>
|
<modifierMask key="keyEquivalentModifierMask"/>
|
||||||
<menu key="submenu" title="Save State" id="Mxx-u1-M9D">
|
<menu key="submenu" title="Save State" id="Mxx-u1-M9D">
|
||||||
<items>
|
<items>
|
||||||
|
@ -276,7 +320,7 @@
|
||||||
</items>
|
</items>
|
||||||
</menu>
|
</menu>
|
||||||
</menuItem>
|
</menuItem>
|
||||||
<menuItem title="Load State" id="EXD-SL-cz4">
|
<menuItem title="Load State" secondaryImage="square.and.arrow.up" catalog="system" id="EXD-SL-cz4">
|
||||||
<modifierMask key="keyEquivalentModifierMask"/>
|
<modifierMask key="keyEquivalentModifierMask"/>
|
||||||
<menu key="submenu" title="Load State" id="l9D-Ej-sh2">
|
<menu key="submenu" title="Load State" id="l9D-Ej-sh2">
|
||||||
<items>
|
<items>
|
||||||
|
@ -344,7 +388,7 @@
|
||||||
</menu>
|
</menu>
|
||||||
</menuItem>
|
</menuItem>
|
||||||
<menuItem isSeparatorItem="YES" id="5GS-tt-E0a"/>
|
<menuItem isSeparatorItem="YES" id="5GS-tt-E0a"/>
|
||||||
<menuItem title="Save Screenshot" keyEquivalent="s" id="0J3-yf-iXs">
|
<menuItem title="Save Screenshot" secondaryImage="photo" catalog="system" keyEquivalent="s" id="0J3-yf-iXs">
|
||||||
<connections>
|
<connections>
|
||||||
<action selector="saveScreenshot:" target="-1" id="gJd-ml-J8p"/>
|
<action selector="saveScreenshot:" target="-1" id="gJd-ml-J8p"/>
|
||||||
</connections>
|
</connections>
|
||||||
|
@ -360,44 +404,13 @@
|
||||||
<action selector="copyScreenshot:" target="-1" id="XJC-EB-HNl"/>
|
<action selector="copyScreenshot:" target="-1" id="XJC-EB-HNl"/>
|
||||||
</connections>
|
</connections>
|
||||||
</menuItem>
|
</menuItem>
|
||||||
<menuItem isSeparatorItem="YES" id="zk7-gf-LXN"/>
|
|
||||||
<menuItem title="Game Boy" tag="1" id="g7C-LA-VAr">
|
|
||||||
<modifierMask key="keyEquivalentModifierMask"/>
|
|
||||||
<connections>
|
|
||||||
<action selector="reset:" target="-1" id="rxG-cz-s1S"/>
|
|
||||||
</connections>
|
|
||||||
</menuItem>
|
|
||||||
<menuItem title="Game Boy Pocket/Light" tag="5" id="1bM-CT-hoW">
|
|
||||||
<modifierMask key="keyEquivalentModifierMask"/>
|
|
||||||
<connections>
|
|
||||||
<action selector="reset:" target="-1" id="U7l-BM-kB1"/>
|
|
||||||
</connections>
|
|
||||||
</menuItem>
|
|
||||||
<menuItem title="Super Game Boy" tag="4" id="vc7-yy-ARW">
|
|
||||||
<modifierMask key="keyEquivalentModifierMask"/>
|
|
||||||
<connections>
|
|
||||||
<action selector="reset:" target="-1" id="E4M-QG-ua9"/>
|
|
||||||
</connections>
|
|
||||||
</menuItem>
|
|
||||||
<menuItem title="Game Boy Color" tag="2" id="hdG-Bl-8nJ">
|
|
||||||
<modifierMask key="keyEquivalentModifierMask"/>
|
|
||||||
<connections>
|
|
||||||
<action selector="reset:" target="-1" id="xAz-cr-0u2"/>
|
|
||||||
</connections>
|
|
||||||
</menuItem>
|
|
||||||
<menuItem title="Game Boy Advance" tag="3" id="7jw-B1-tf5">
|
|
||||||
<modifierMask key="keyEquivalentModifierMask"/>
|
|
||||||
<connections>
|
|
||||||
<action selector="reset:" target="-1" id="xQk-4e-kd7"/>
|
|
||||||
</connections>
|
|
||||||
</menuItem>
|
|
||||||
<menuItem isSeparatorItem="YES" id="DPb-Sh-5tg"/>
|
<menuItem isSeparatorItem="YES" id="DPb-Sh-5tg"/>
|
||||||
<menuItem title="Start Audio Recording…" keyEquivalent="A" id="1UK-8n-QPP">
|
<menuItem title="Start Audio Recording…" secondaryImage="record.circle" catalog="system" keyEquivalent="A" id="1UK-8n-QPP">
|
||||||
<connections>
|
<connections>
|
||||||
<action selector="toggleAudioRecording:" target="-1" id="YE5-mi-Yzd"/>
|
<action selector="toggleAudioRecording:" target="-1" id="YE5-mi-Yzd"/>
|
||||||
</connections>
|
</connections>
|
||||||
</menuItem>
|
</menuItem>
|
||||||
<menuItem title="Mute Sound" keyEquivalent="m" id="zo0-Rh-wTu">
|
<menuItem title="Mute Sound" secondaryImage="speaker.slash" catalog="system" keyEquivalent="m" id="zo0-Rh-wTu">
|
||||||
<connections>
|
<connections>
|
||||||
<action selector="mute:" target="-1" id="eK3-ea-ExJ"/>
|
<action selector="mute:" target="-1" id="eK3-ea-ExJ"/>
|
||||||
</connections>
|
</connections>
|
||||||
|
@ -414,18 +427,24 @@
|
||||||
<action selector="toggleCheats:" target="-1" id="gsw-UY-fhu"/>
|
<action selector="toggleCheats:" target="-1" id="gsw-UY-fhu"/>
|
||||||
</connections>
|
</connections>
|
||||||
</menuItem>
|
</menuItem>
|
||||||
<menuItem title="Show Cheats" id="LZV-QK-YXi">
|
<menuItem title="Show Cheats" id="Nf8-F1-YyD">
|
||||||
<modifierMask key="keyEquivalentModifierMask"/>
|
<modifierMask key="keyEquivalentModifierMask"/>
|
||||||
<connections>
|
<connections>
|
||||||
<action selector="showCheats:" target="-1" id="tfr-qM-q8X"/>
|
<action selector="showCheats:" target="-1" id="stn-Ei-aFE"/>
|
||||||
|
</connections>
|
||||||
|
</menuItem>
|
||||||
|
<menuItem title="Search Cheats" secondaryImage="text.page.badge.magnifyingglass" catalog="system" id="LZV-QK-YXi">
|
||||||
|
<modifierMask key="keyEquivalentModifierMask"/>
|
||||||
|
<connections>
|
||||||
|
<action selector="showCheatSearch:" target="-1" id="eI1-x0-ykn"/>
|
||||||
</connections>
|
</connections>
|
||||||
</menuItem>
|
</menuItem>
|
||||||
</items>
|
</items>
|
||||||
</menu>
|
</menu>
|
||||||
</menuItem>
|
</menuItem>
|
||||||
<menuItem title="Connectivity" id="IcW-ZC-4wb">
|
<menuItem title="Connect" id="IcW-ZC-4wb">
|
||||||
<modifierMask key="keyEquivalentModifierMask"/>
|
<modifierMask key="keyEquivalentModifierMask"/>
|
||||||
<menu key="submenu" title="Connectivity" id="BDM-Cv-BOm">
|
<menu key="submenu" title="Connect" id="BDM-Cv-BOm">
|
||||||
<items>
|
<items>
|
||||||
<menuItem title="None" id="SiH-Q4-OBY">
|
<menuItem title="None" id="SiH-Q4-OBY">
|
||||||
<modifierMask key="keyEquivalentModifierMask"/>
|
<modifierMask key="keyEquivalentModifierMask"/>
|
||||||
|
@ -433,7 +452,7 @@
|
||||||
<action selector="disconnectAllAccessories:" target="-1" id="5hY-9U-nRn"/>
|
<action selector="disconnectAllAccessories:" target="-1" id="5hY-9U-nRn"/>
|
||||||
</connections>
|
</connections>
|
||||||
</menuItem>
|
</menuItem>
|
||||||
<menuItem title="Game Link Cable & Infrared" id="V4S-Fo-xJK">
|
<menuItem title="Game Link Cable & Infrared" secondaryImage="cable.connector.horizontal" catalog="system" id="V4S-Fo-xJK">
|
||||||
<modifierMask key="keyEquivalentModifierMask"/>
|
<modifierMask key="keyEquivalentModifierMask"/>
|
||||||
<menu key="submenu" title="Game Link Cable & Infrared" id="6sJ-Wz-QLj">
|
<menu key="submenu" title="Game Link Cable & Infrared" id="6sJ-Wz-QLj">
|
||||||
<connections>
|
<connections>
|
||||||
|
@ -444,13 +463,13 @@
|
||||||
<action selector="nop:" target="-3" id="Bpa-0C-lkN"/>
|
<action selector="nop:" target="-3" id="Bpa-0C-lkN"/>
|
||||||
</connections>
|
</connections>
|
||||||
</menuItem>
|
</menuItem>
|
||||||
<menuItem title="Game Boy Printer" id="zHR-Ha-pOR">
|
<menuItem title="Game Boy Printer" secondaryImage="printer" catalog="system" id="zHR-Ha-pOR">
|
||||||
<modifierMask key="keyEquivalentModifierMask"/>
|
<modifierMask key="keyEquivalentModifierMask"/>
|
||||||
<connections>
|
<connections>
|
||||||
<action selector="connectPrinter:" target="-1" id="tl1-CL-tAw"/>
|
<action selector="connectPrinter:" target="-1" id="tl1-CL-tAw"/>
|
||||||
</connections>
|
</connections>
|
||||||
</menuItem>
|
</menuItem>
|
||||||
<menuItem title="Workboy" id="lo9-CX-BJj">
|
<menuItem title="Workboy" secondaryImage="keyboard" catalog="system" id="lo9-CX-BJj">
|
||||||
<modifierMask key="keyEquivalentModifierMask"/>
|
<modifierMask key="keyEquivalentModifierMask"/>
|
||||||
<connections>
|
<connections>
|
||||||
<action selector="connectWorkboy:" target="-1" id="6vS-bq-wAX"/>
|
<action selector="connectWorkboy:" target="-1" id="6vS-bq-wAX"/>
|
||||||
|
@ -463,14 +482,14 @@
|
||||||
<modifierMask key="keyEquivalentModifierMask"/>
|
<modifierMask key="keyEquivalentModifierMask"/>
|
||||||
<menu key="submenu" title="Develop" id="UVb-cc-at0">
|
<menu key="submenu" title="Develop" id="UVb-cc-at0">
|
||||||
<items>
|
<items>
|
||||||
<menuItem title="Developer Mode" id="Qx6-Tt-zZR">
|
<menuItem title="Developer Mode" secondaryImage="wrench.and.screwdriver" catalog="system" id="Qx6-Tt-zZR">
|
||||||
<modifierMask key="keyEquivalentModifierMask"/>
|
<modifierMask key="keyEquivalentModifierMask"/>
|
||||||
<connections>
|
<connections>
|
||||||
<action selector="toggleDeveloperMode:" target="-3" id="PIc-o3-bzb"/>
|
<action selector="toggleDeveloperMode:" target="-3" id="PIc-o3-bzb"/>
|
||||||
</connections>
|
</connections>
|
||||||
</menuItem>
|
</menuItem>
|
||||||
<menuItem isSeparatorItem="YES" id="66c-T0-8pW"/>
|
<menuItem isSeparatorItem="YES" id="66c-T0-8pW"/>
|
||||||
<menuItem title="Show Console" id="Wse-UY-Y9l">
|
<menuItem title="Show Console" secondaryImage="apple.terminal" catalog="system" id="Wse-UY-Y9l">
|
||||||
<modifierMask key="keyEquivalentModifierMask"/>
|
<modifierMask key="keyEquivalentModifierMask"/>
|
||||||
<connections>
|
<connections>
|
||||||
<action selector="showConsoleWindow:" target="-1" id="mFf-4i-jLG"/>
|
<action selector="showConsoleWindow:" target="-1" id="mFf-4i-jLG"/>
|
||||||
|
@ -482,14 +501,14 @@
|
||||||
</connections>
|
</connections>
|
||||||
</menuItem>
|
</menuItem>
|
||||||
<menuItem isSeparatorItem="YES" id="3If-Yf-U7B"/>
|
<menuItem isSeparatorItem="YES" id="3If-Yf-U7B"/>
|
||||||
<menuItem title="Break Debugger" keyEquivalent="c" id="uBD-GY-Doi">
|
<menuItem title="Break Debugger" secondaryImage="pause" catalog="system" keyEquivalent="c" id="uBD-GY-Doi">
|
||||||
<modifierMask key="keyEquivalentModifierMask" control="YES"/>
|
<modifierMask key="keyEquivalentModifierMask" control="YES"/>
|
||||||
<connections>
|
<connections>
|
||||||
<action selector="interrupt:" target="-1" id="ZmB-wG-fTs"/>
|
<action selector="interrupt:" target="-1" id="ZmB-wG-fTs"/>
|
||||||
</connections>
|
</connections>
|
||||||
</menuItem>
|
</menuItem>
|
||||||
<menuItem isSeparatorItem="YES" id="M6n-8G-LZS"/>
|
<menuItem isSeparatorItem="YES" id="M6n-8G-LZS"/>
|
||||||
<menuItem title="Audio Channels" id="Cib-LN-Y4o">
|
<menuItem title="Audio Channels" secondaryImage="speaker.wave.3" catalog="system" id="Cib-LN-Y4o">
|
||||||
<modifierMask key="keyEquivalentModifierMask"/>
|
<modifierMask key="keyEquivalentModifierMask"/>
|
||||||
<menu key="submenu" title="Audio Channels" id="l22-4p-yTK">
|
<menu key="submenu" title="Audio Channels" id="l22-4p-yTK">
|
||||||
<items>
|
<items>
|
||||||
|
@ -521,13 +540,13 @@
|
||||||
</menu>
|
</menu>
|
||||||
</menuItem>
|
</menuItem>
|
||||||
<menuItem isSeparatorItem="YES" id="v5c-ri-BoZ"/>
|
<menuItem isSeparatorItem="YES" id="v5c-ri-BoZ"/>
|
||||||
<menuItem title="Show Background and Window" state="on" id="yfD-Qd-zoz">
|
<menuItem title="Show Background and Window" state="on" secondaryImage="mountain.2" catalog="system" id="yfD-Qd-zoz">
|
||||||
<modifierMask key="keyEquivalentModifierMask"/>
|
<modifierMask key="keyEquivalentModifierMask"/>
|
||||||
<connections>
|
<connections>
|
||||||
<action selector="toggleDisplayBackground:" target="-1" id="p5b-1n-SPR"/>
|
<action selector="toggleDisplayBackground:" target="-1" id="p5b-1n-SPR"/>
|
||||||
</connections>
|
</connections>
|
||||||
</menuItem>
|
</menuItem>
|
||||||
<menuItem title="Show Objects" state="on" id="OWx-a0-vQk">
|
<menuItem title="Show Objects" state="on" secondaryImage="cube" catalog="system" id="OWx-a0-vQk">
|
||||||
<modifierMask key="keyEquivalentModifierMask"/>
|
<modifierMask key="keyEquivalentModifierMask"/>
|
||||||
<connections>
|
<connections>
|
||||||
<action selector="toggleDisplayObjects:" target="-1" id="8ie-ey-739"/>
|
<action selector="toggleDisplayObjects:" target="-1" id="8ie-ey-739"/>
|
||||||
|
@ -601,4 +620,24 @@
|
||||||
<point key="canvasLocation" x="140" y="260"/>
|
<point key="canvasLocation" x="140" y="260"/>
|
||||||
</menu>
|
</menu>
|
||||||
</objects>
|
</objects>
|
||||||
|
<resources>
|
||||||
|
<image name="apple.terminal" catalog="system" width="18" height="14"/>
|
||||||
|
<image name="arrow.down.left.arrow.up.right" catalog="system" width="18" height="17"/>
|
||||||
|
<image name="arrow.trianglehead.2.counterclockwise.rotate.90" catalog="system" width="16" height="15"/>
|
||||||
|
<image name="cable.connector.horizontal" catalog="system" width="19" height="7"/>
|
||||||
|
<image name="cube" catalog="system" width="16" height="17"/>
|
||||||
|
<image name="keyboard" catalog="system" width="19" height="13"/>
|
||||||
|
<image name="mountain.2" catalog="system" width="25" height="14"/>
|
||||||
|
<image name="pause" catalog="system" width="9" height="13"/>
|
||||||
|
<image name="photo" catalog="system" width="18" height="14"/>
|
||||||
|
<image name="plus.square.on.square" catalog="system" width="17" height="16"/>
|
||||||
|
<image name="printer" catalog="system" width="18" height="16"/>
|
||||||
|
<image name="record.circle" catalog="system" width="15" height="15"/>
|
||||||
|
<image name="speaker.slash" catalog="system" width="14" height="16"/>
|
||||||
|
<image name="speaker.wave.3" catalog="system" width="22" height="15"/>
|
||||||
|
<image name="square.and.arrow.down" catalog="system" width="15" height="17"/>
|
||||||
|
<image name="square.and.arrow.up" catalog="system" width="15" height="18"/>
|
||||||
|
<image name="text.page.badge.magnifyingglass" catalog="system" width="15" height="18"/>
|
||||||
|
<image name="wrench.and.screwdriver" catalog="system" width="19" height="18"/>
|
||||||
|
</resources>
|
||||||
</document>
|
</document>
|
||||||
|
|
|
@ -3,8 +3,8 @@
|
||||||
#import <objc/runtime.h>
|
#import <objc/runtime.h>
|
||||||
|
|
||||||
@interface NSTextFieldCell ()
|
@interface NSTextFieldCell ()
|
||||||
- (CGRect)_textLayerDrawingRectForCellFrame:(CGRect)rect;
|
|
||||||
@property NSSize textInset;
|
@property NSSize textInset;
|
||||||
|
- (bool)_isEditingInView:(NSView *)view;
|
||||||
@end
|
@end
|
||||||
|
|
||||||
@implementation NSTextFieldCell (Inset)
|
@implementation NSTextFieldCell (Inset)
|
||||||
|
@ -19,21 +19,59 @@
|
||||||
return [objc_getAssociatedObject(self, _cmd) sizeValue];
|
return [objc_getAssociatedObject(self, _cmd) sizeValue];
|
||||||
}
|
}
|
||||||
|
|
||||||
- (CGRect)_textLayerDrawingRectForCellFrameHook:(CGRect)rect
|
- (void)drawWithFrameHook:(NSRect)cellFrame inView:(NSView *)controlView
|
||||||
{
|
{
|
||||||
CGRect ret = [self _textLayerDrawingRectForCellFrameHook:rect];
|
|
||||||
NSSize inset = self.textInset;
|
NSSize inset = self.textInset;
|
||||||
ret.origin.x += inset.width;
|
if (self.drawsBackground) {
|
||||||
ret.origin.y += inset.height;
|
[self.backgroundColor setFill];
|
||||||
ret.size.width -= inset.width;
|
if ([self _isEditingInView:controlView]) {
|
||||||
ret.size.height -= inset.height;
|
NSRectFill(cellFrame);
|
||||||
return ret;
|
}
|
||||||
|
else {
|
||||||
|
NSRectFill(NSMakeRect(cellFrame.origin.x, cellFrame.origin.y,
|
||||||
|
cellFrame.size.width, inset.height));
|
||||||
|
NSRectFill(NSMakeRect(cellFrame.origin.x, cellFrame.origin.y + cellFrame.size.height - inset.height,
|
||||||
|
cellFrame.size.width, inset.height));
|
||||||
|
|
||||||
|
NSRectFill(NSMakeRect(cellFrame.origin.x, cellFrame.origin.y + inset.height,
|
||||||
|
inset.width, cellFrame.size.height - inset.height * 2));
|
||||||
|
NSRectFill(NSMakeRect(cellFrame.origin.x + cellFrame.size.width - inset.width, cellFrame.origin.y + inset.height,
|
||||||
|
inset.width, cellFrame.size.height - inset.height * 2));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
cellFrame.origin.x += inset.width;
|
||||||
|
cellFrame.origin.y += inset.height;
|
||||||
|
cellFrame.size.width -= inset.width * 2;
|
||||||
|
cellFrame.size.height -= inset.height * 2;
|
||||||
|
[self drawWithFrameHook:cellFrame inView:controlView];
|
||||||
}
|
}
|
||||||
|
|
||||||
+ (void)load
|
+ (void)load
|
||||||
{
|
{
|
||||||
method_exchangeImplementations(class_getInstanceMethod(self, @selector(_textLayerDrawingRectForCellFrame:)),
|
method_exchangeImplementations(class_getInstanceMethod(self, @selector(drawWithFrame:inView:)),
|
||||||
class_getInstanceMethod(self, @selector(_textLayerDrawingRectForCellFrameHook:)));
|
class_getInstanceMethod(self, @selector(drawWithFrameHook:inView:)));
|
||||||
|
}
|
||||||
|
|
||||||
|
@end
|
||||||
|
|
||||||
|
|
||||||
|
@implementation NSTextField (Inset)
|
||||||
|
|
||||||
|
- (bool)wantsUpdateLayerHook
|
||||||
|
{
|
||||||
|
CGSize inset = ((NSTextFieldCell *)self.cell).textInset;
|
||||||
|
if (inset.width || inset.height) return false;
|
||||||
|
return [self wantsUpdateLayerHook];
|
||||||
|
}
|
||||||
|
|
||||||
|
+ (void)load
|
||||||
|
{
|
||||||
|
Method method = class_getInstanceMethod(self, @selector(wantsUpdateLayer));
|
||||||
|
if (class_addMethod(self, @selector(wantsUpdateLayer), method_getImplementation(method), method_getTypeEncoding(method))) {
|
||||||
|
method = class_getInstanceMethod(self, @selector(wantsUpdateLayer));
|
||||||
|
}
|
||||||
|
method_exchangeImplementations(method,
|
||||||
|
class_getInstanceMethod(self, @selector(wantsUpdateLayerHook)));
|
||||||
}
|
}
|
||||||
|
|
||||||
@end
|
@end
|
||||||
|
|
|
@ -6,7 +6,7 @@ static id nop(id self, SEL _cmd)
|
||||||
return nil;
|
return nil;
|
||||||
}
|
}
|
||||||
|
|
||||||
static double blah(id self, SEL _cmd)
|
static double minSize(id self, SEL _cmd)
|
||||||
{
|
{
|
||||||
return 80.0;
|
return 80.0;
|
||||||
}
|
}
|
||||||
|
@ -18,7 +18,7 @@ static double blah(id self, SEL _cmd)
|
||||||
// Prevent collapsing toolbar items into menu items, they don't work in that form
|
// Prevent collapsing toolbar items into menu items, they don't work in that form
|
||||||
method_setImplementation(class_getInstanceMethod(self, @selector(menuFormRepresentation)), (IMP)nop);
|
method_setImplementation(class_getInstanceMethod(self, @selector(menuFormRepresentation)), (IMP)nop);
|
||||||
// Prevent over-agressive collapsing of the Printer Feed menu
|
// Prevent over-agressive collapsing of the Printer Feed menu
|
||||||
method_setImplementation(class_getInstanceMethod(NSClassFromString(@"NSToolbarTitleView"), @selector(minSize)), (IMP)blah);
|
method_setImplementation(class_getInstanceMethod(NSClassFromString(@"NSToolbarTitleView"), @selector(minSize)), (IMP)minSize);
|
||||||
}
|
}
|
||||||
|
|
||||||
@end
|
@end
|
||||||
|
|
|
@ -1,8 +1,8 @@
|
||||||
<?xml version="1.0" encoding="UTF-8"?>
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
<document type="com.apple.InterfaceBuilder3.Cocoa.XIB" version="3.0" toolsVersion="11762" systemVersion="16D32" targetRuntime="MacOSX.Cocoa" propertyAccessControl="none" useAutolayout="YES" customObjectInstantitationMethod="direct">
|
<document type="com.apple.InterfaceBuilder3.Cocoa.XIB" version="3.0" toolsVersion="21507" targetRuntime="MacOSX.Cocoa" propertyAccessControl="none" useAutolayout="YES" customObjectInstantitationMethod="direct">
|
||||||
<dependencies>
|
<dependencies>
|
||||||
<deployment identifier="macosx"/>
|
<deployment identifier="macosx"/>
|
||||||
<plugIn identifier="com.apple.InterfaceBuilder.CocoaPlugin" version="11762"/>
|
<plugIn identifier="com.apple.InterfaceBuilder.CocoaPlugin" version="21507"/>
|
||||||
<capability name="documents saved in the Xcode 8 format" minToolsVersion="8.0"/>
|
<capability name="documents saved in the Xcode 8 format" minToolsVersion="8.0"/>
|
||||||
</dependencies>
|
</dependencies>
|
||||||
<objects>
|
<objects>
|
||||||
|
@ -13,7 +13,7 @@
|
||||||
</customObject>
|
</customObject>
|
||||||
<customObject id="-1" userLabel="First Responder" customClass="FirstResponder"/>
|
<customObject id="-1" userLabel="First Responder" customClass="FirstResponder"/>
|
||||||
<customObject id="-3" userLabel="Application" customClass="NSObject"/>
|
<customObject id="-3" userLabel="Application" customClass="NSObject"/>
|
||||||
<textField verticalHuggingPriority="750" horizontalCompressionResistancePriority="250" id="oUc-bq-d5t">
|
<textField verticalHuggingPriority="750" horizontalCompressionResistancePriority="250" allowsCharacterPickerTouchBarItem="YES" id="oUc-bq-d5t">
|
||||||
<rect key="frame" x="0.0" y="0.0" width="66" height="17"/>
|
<rect key="frame" x="0.0" y="0.0" width="66" height="17"/>
|
||||||
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
|
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
|
||||||
<textFieldCell key="cell" controlSize="mini" sendsActionOnEndEditing="YES" alignment="left" title="Test" id="xyx-iy-kse">
|
<textFieldCell key="cell" controlSize="mini" sendsActionOnEndEditing="YES" alignment="left" title="Test" id="xyx-iy-kse">
|
||||||
|
|
|
@ -0,0 +1,8 @@
|
||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
|
||||||
|
<plist version="1.0">
|
||||||
|
<dict>
|
||||||
|
<key>com.apple.security.device.camera</key>
|
||||||
|
<true/>
|
||||||
|
</dict>
|
||||||
|
</plist>
|
|
@ -0,0 +1,168 @@
|
||||||
|
#import <Cocoa/Cocoa.h>
|
||||||
|
#import <objc/runtime.h>
|
||||||
|
|
||||||
|
// Comment out to debug
|
||||||
|
#define NSLog(...)
|
||||||
|
|
||||||
|
// Solarium has weird proportions, we need to fix them.
|
||||||
|
@implementation NSControl (SolariumFixer)
|
||||||
|
|
||||||
|
- (void)awakeFromNib
|
||||||
|
{
|
||||||
|
if (@available(macOS 26.0, *)) {
|
||||||
|
if ([self.superview isKindOfClass:objc_getClass("NSToolbarItemViewer")]) return;
|
||||||
|
|
||||||
|
if ([self isKindOfClass:[NSStepper class]]) {
|
||||||
|
NSLog(@"Stepper needs adjustment: %s in window %@", sel_getName(self.action), self.window.title);
|
||||||
|
CGRect frame = self.frame;
|
||||||
|
frame.origin.y += 1;
|
||||||
|
self.frame = frame;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (self.controlSize != NSControlSizeRegular) return;
|
||||||
|
|
||||||
|
if ([self isKindOfClass:[NSPopUpButton class]] ) {
|
||||||
|
NSLog(@"Popup button needs adjustment: %@ in window %@", ((NSButton *)self).title, self.window.title);
|
||||||
|
CGRect frame = self.frame;
|
||||||
|
if (frame.size.height != 25) {
|
||||||
|
NSLog(@"%@ in window %@ has the wrong height!", ((NSButton *)self).title, self.window.title);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
frame.size.width -= 2 + 5; // Remove 5 from the right and 2 from the left
|
||||||
|
frame.origin.x += 2;
|
||||||
|
frame.origin.y += 2;
|
||||||
|
self.frame = frame;
|
||||||
|
}
|
||||||
|
else if ([self isKindOfClass:[NSSegmentedControl class]] ) {
|
||||||
|
NSLog(@"Segmented button needs adjustment: %s in window %@", sel_getName(self.action), self.window.title);
|
||||||
|
CGRect frame = self.frame;
|
||||||
|
if (frame.size.height != 25) {
|
||||||
|
NSLog(@"%s in window %@ has the wrong height!", sel_getName(self.action), self.window.title);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
frame.origin.x += 8;
|
||||||
|
frame.origin.y += 1;
|
||||||
|
self.frame = frame;
|
||||||
|
}
|
||||||
|
else if ([self isKindOfClass:[NSTextField class]]) {
|
||||||
|
NSTextField *field = (id)self;
|
||||||
|
if (![field isBezeled]) return;
|
||||||
|
NSLog(@"Text field needs adjustment: %@ in window %@", ((NSTextField *)self).placeholderString, self.window.title);
|
||||||
|
CGRect frame = self.frame;
|
||||||
|
if (frame.size.height == 21) {
|
||||||
|
frame.size.height = 24;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
NSLog(@"%@ in window %@ has the wrong height!", ((NSTextField *)self).placeholderString, self.window.title);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
frame.size.width -= 1 + 1; // Remove 1 from the right and 1 from the left
|
||||||
|
frame.origin.x += 1;
|
||||||
|
frame.origin.y -= 1;
|
||||||
|
|
||||||
|
self.frame = frame;
|
||||||
|
}
|
||||||
|
else if ([self isKindOfClass:[NSButton class]]) {
|
||||||
|
NSLog(@"Button: %@ in window %@", @(sel_getName(self.action)), self.window.title);
|
||||||
|
NSButton *button = (id)self;
|
||||||
|
if (!button.isBordered) return;
|
||||||
|
if (button.bezelStyle == NSBezelStylePush) {
|
||||||
|
NSLog(@"Button needs adjustment: %@ in window %@", @(sel_getName(self.action)), self.window.title);
|
||||||
|
CGRect frame = self.frame;
|
||||||
|
frame.size.width -= 7 + 7; // Remove 7 from the right and 7 from the left
|
||||||
|
frame.origin.x += 7;
|
||||||
|
frame.origin.y += 5;
|
||||||
|
if (frame.size.height == 32) {
|
||||||
|
frame.size.height = 25;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
NSLog(@"%@ in window %@ has the wrong height!", @(sel_getName(self.action)), self.window.title);
|
||||||
|
} self.frame = frame;
|
||||||
|
}
|
||||||
|
else if (button.bezelStyle == NSBezelStyleRegularSquare) {
|
||||||
|
CGRect frame = self.frame;
|
||||||
|
if (frame.size.height != 18) return;
|
||||||
|
NSLog(@"Check/Radio needs adjustment: %@ in window %@", ((NSButton *)self).title, self.window.title);
|
||||||
|
frame.size.width -= 2;
|
||||||
|
frame.origin.x += 2;
|
||||||
|
frame.origin.y += 1;
|
||||||
|
frame.size.height = 16;
|
||||||
|
self.frame = frame;
|
||||||
|
}
|
||||||
|
else if (button.bezelStyle == NSBezelStyleHelpButton) {
|
||||||
|
CGRect frame = self.frame;
|
||||||
|
NSLog(@"Help button needs adjustment: %@ in window %@", ((NSButton *)self).title, self.window.title);
|
||||||
|
frame.origin.y += 2;
|
||||||
|
self.frame = frame;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if ([self isKindOfClass:[NSSlider class]]) {
|
||||||
|
NSLog(@"Slider needs adjustment: %s in window %@", sel_getName(self.action), self.window.title);
|
||||||
|
CGRect frame = self.frame;
|
||||||
|
frame.origin.y += 3;
|
||||||
|
self.frame = frame;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@end
|
||||||
|
|
||||||
|
@implementation NSToolbarItem (SolariumFixer)
|
||||||
|
|
||||||
|
static CGSize minSizeHook(id self, SEL _cmd)
|
||||||
|
{
|
||||||
|
return CGSizeMake(8, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
- (void)awakeFromNib
|
||||||
|
{
|
||||||
|
if (@available(macOS 26.0, *)) {
|
||||||
|
NSLog(@"Toolbar item %@ has view %@", self.label, self.view);
|
||||||
|
if ([self.view isKindOfClass:[NSTextField class]]) {
|
||||||
|
NSLog(@"Handling (Text field)");
|
||||||
|
self.bordered = true;
|
||||||
|
|
||||||
|
NSSize maxSize = self.maxSize;
|
||||||
|
maxSize.height = 36;
|
||||||
|
self.maxSize = maxSize;
|
||||||
|
|
||||||
|
NSSize minSize = self.minSize;
|
||||||
|
minSize.height = 36;
|
||||||
|
self.minSize = minSize;
|
||||||
|
|
||||||
|
((NSTextField *)self.view).backgroundColor = [NSColor clearColor];
|
||||||
|
((NSTextField *)self.view).bezeled = false;
|
||||||
|
((NSTextField *)self.view).bordered = true;
|
||||||
|
|
||||||
|
// Work around even more AppKit bugs
|
||||||
|
self.toolbar.displayMode++;
|
||||||
|
self.toolbar.displayMode--;
|
||||||
|
}
|
||||||
|
else if ([self.view isKindOfClass:[NSPopUpButton class]]) {
|
||||||
|
NSLog(@"Handling (Pop up button)");
|
||||||
|
self.bordered = true;
|
||||||
|
|
||||||
|
NSSize maxSize = self.maxSize;
|
||||||
|
maxSize.height = 28;
|
||||||
|
self.maxSize = maxSize;
|
||||||
|
|
||||||
|
NSSize minSize = self.minSize;
|
||||||
|
minSize.height = 28;
|
||||||
|
self.minSize = minSize;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (@available(macOS 11.0, *)) { // While at it, make macOS 11-15 a bit more consistent
|
||||||
|
if ([self.view isKindOfClass:[NSTextField class]]) {
|
||||||
|
((NSTextField *)self.view).bezelStyle = NSTextFieldRoundedBezel;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
+ (void)load
|
||||||
|
{
|
||||||
|
if (@available(macOS 26.0, *)) {
|
||||||
|
method_setImplementation(class_getInstanceMethod(objc_getClass("NSToolbarFlexibleSpaceItem"), @selector(minSize)),
|
||||||
|
(void *)minSizeHook);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@end
|
Before Width: | Height: | Size: 527 B After Width: | Height: | Size: 180 B |
Before Width: | Height: | Size: 884 B After Width: | Height: | Size: 1.0 KiB |
|
@ -21,7 +21,6 @@
|
||||||
<customObject id="-3" userLabel="Application" customClass="NSObject"/>
|
<customObject id="-3" userLabel="Application" customClass="NSObject"/>
|
||||||
<window title="Update Available" allowsToolTipsWhenApplicationIsInactive="NO" autorecalculatesKeyViewLoop="NO" restorable="NO" releasedWhenClosed="NO" visibleAtLaunch="NO" animationBehavior="default" id="QvC-M9-y7g">
|
<window title="Update Available" allowsToolTipsWhenApplicationIsInactive="NO" autorecalculatesKeyViewLoop="NO" restorable="NO" releasedWhenClosed="NO" visibleAtLaunch="NO" animationBehavior="default" id="QvC-M9-y7g">
|
||||||
<windowStyleMask key="styleMask" titled="YES" closable="YES" resizable="YES"/>
|
<windowStyleMask key="styleMask" titled="YES" closable="YES" resizable="YES"/>
|
||||||
<windowPositionMask key="initialPositionMask" leftStrut="YES" rightStrut="YES" topStrut="YES" bottomStrut="YES"/>
|
|
||||||
<rect key="contentRect" x="196" y="240" width="480" height="360"/>
|
<rect key="contentRect" x="196" y="240" width="480" height="360"/>
|
||||||
<rect key="screenRect" x="0.0" y="0.0" width="2560" height="1417"/>
|
<rect key="screenRect" x="0.0" y="0.0" width="2560" height="1417"/>
|
||||||
<view key="contentView" wantsLayer="YES" id="EiT-Mj-1SZ">
|
<view key="contentView" wantsLayer="YES" id="EiT-Mj-1SZ">
|
||||||
|
@ -97,7 +96,6 @@ DQ
|
||||||
<point key="canvasLocation" x="217" y="267"/>
|
<point key="canvasLocation" x="217" y="267"/>
|
||||||
</window>
|
</window>
|
||||||
<window title="Window" allowsToolTipsWhenApplicationIsInactive="NO" autorecalculatesKeyViewLoop="NO" restorable="NO" releasedWhenClosed="NO" visibleAtLaunch="NO" frameAutosaveName="" animationBehavior="default" id="2Gy-QG-FoA">
|
<window title="Window" allowsToolTipsWhenApplicationIsInactive="NO" autorecalculatesKeyViewLoop="NO" restorable="NO" releasedWhenClosed="NO" visibleAtLaunch="NO" frameAutosaveName="" animationBehavior="default" id="2Gy-QG-FoA">
|
||||||
<windowPositionMask key="initialPositionMask" leftStrut="YES" rightStrut="YES" topStrut="YES" bottomStrut="YES"/>
|
|
||||||
<rect key="contentRect" x="283" y="305" width="512" height="61"/>
|
<rect key="contentRect" x="283" y="305" width="512" height="61"/>
|
||||||
<rect key="screenRect" x="0.0" y="0.0" width="2560" height="1417"/>
|
<rect key="screenRect" x="0.0" y="0.0" width="2560" height="1417"/>
|
||||||
<view key="contentView" id="jjT-Z5-15Q">
|
<view key="contentView" id="jjT-Z5-15Q">
|
||||||
|
@ -125,7 +123,7 @@ Gw
|
||||||
<textField horizontalHuggingPriority="251" verticalHuggingPriority="750" fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="wIm-GX-c6B">
|
<textField horizontalHuggingPriority="251" verticalHuggingPriority="750" fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="wIm-GX-c6B">
|
||||||
<rect key="frame" x="58" y="15" width="359" height="24"/>
|
<rect key="frame" x="58" y="15" width="359" height="24"/>
|
||||||
<autoresizingMask key="autoresizingMask" widthSizable="YES" flexibleMinY="YES"/>
|
<autoresizingMask key="autoresizingMask" widthSizable="YES" flexibleMinY="YES"/>
|
||||||
<textFieldCell key="cell" lineBreakMode="clipping" title="Downloading update..." id="qmF-X1-v5B">
|
<textFieldCell key="cell" lineBreakMode="clipping" title="Downloading update…" id="qmF-X1-v5B">
|
||||||
<font key="font" usesAppearanceFont="YES"/>
|
<font key="font" usesAppearanceFont="YES"/>
|
||||||
<color key="textColor" name="labelColor" catalog="System" colorSpace="catalog"/>
|
<color key="textColor" name="labelColor" catalog="System" colorSpace="catalog"/>
|
||||||
<color key="backgroundColor" name="textBackgroundColor" catalog="System" colorSpace="catalog"/>
|
<color key="backgroundColor" name="textBackgroundColor" catalog="System" colorSpace="catalog"/>
|
||||||
|
|
Before Width: | Height: | Size: 1.5 KiB After Width: | Height: | Size: 1.5 KiB |
Before Width: | Height: | Size: 3.1 KiB After Width: | Height: | Size: 3.1 KiB |
Before Width: | Height: | Size: 407 B After Width: | Height: | Size: 299 B |
Before Width: | Height: | Size: 832 B After Width: | Height: | Size: 569 B |