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
|
||||
SDL/*.h linguist-language=C
|
||||
Windows/*.h linguist-language=C
|
||||
XdgThumbnailer/*.h linguist-language=C
|
||||
Cocoa/*.h linguist-language=Objective-C
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
case `echo $1 | cut -d '-' -f 1` in
|
||||
ubuntu)
|
||||
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`
|
||||
curl -L https://github.com/rednex/rgbds/archive/v0.6.0.zip > rgbds.zip
|
||||
|
|
|
@ -11,7 +11,7 @@ jobs:
|
|||
strategy:
|
||||
fail-fast: false
|
||||
matrix:
|
||||
os: [macos-latest, ubuntu-latest, ubuntu-20.04]
|
||||
os: [macos-latest, ubuntu-latest, ubuntu-22.04]
|
||||
cc: [gcc, clang]
|
||||
include:
|
||||
- os: macos-latest
|
||||
|
@ -35,7 +35,7 @@ jobs:
|
|||
run: |
|
||||
./.github/actions/sanity_tests.sh
|
||||
- name: Upload binaries
|
||||
uses: actions/upload-artifact@v3
|
||||
uses: actions/upload-artifact@v4
|
||||
with:
|
||||
name: sameboy-canary-${{ matrix.os }}-${{ matrix.cc }}
|
||||
path: |
|
||||
|
|
|
@ -5,8 +5,8 @@
|
|||
@property (nonatomic, strong) void (^renderBlock)(UInt32 sampleRate, UInt32 nFrames, GB_sample_t *buffer);
|
||||
@property (nonatomic, readonly) UInt32 rate;
|
||||
@property (nonatomic, readonly, getter=isPlaying) bool playing;
|
||||
-(void) start;
|
||||
-(void) stop;
|
||||
-(id) initWithRendererBlock:(void (^)(UInt32 sampleRate, UInt32 nFrames, GB_sample_t *buffer)) block
|
||||
- (void)start;
|
||||
- (void)stop;
|
||||
- (id)initWithRendererBlock:(void (^)(UInt32 sampleRate, UInt32 nFrames, GB_sample_t *buffer)) block
|
||||
andSampleRate:(UInt32) rate;
|
||||
@end
|
||||
|
|
|
@ -23,7 +23,7 @@ static OSStatus render(
|
|||
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
|
||||
{
|
||||
if (!(self = [super init])) {
|
||||
|
|
|
@ -32,5 +32,5 @@ typedef enum {
|
|||
- (void) createInternalView;
|
||||
- (uint32_t *)currentBuffer;
|
||||
- (uint32_t *)previousBuffer;
|
||||
|
||||
- (instancetype)mirroredView;
|
||||
@end
|
||||
|
|
|
@ -6,10 +6,13 @@
|
|||
unsigned _currentBuffer;
|
||||
GB_frame_blending_mode_t _frameBlendingMode;
|
||||
bool _oddFrame;
|
||||
GBViewBase *_parent;
|
||||
__weak GBViewBase *_child;
|
||||
}
|
||||
|
||||
- (void)screenSizeChanged
|
||||
{
|
||||
if (_parent) return;
|
||||
if (_imageBuffers[0]) free(_imageBuffers[0]);
|
||||
if (_imageBuffers[1]) free(_imageBuffers[1]);
|
||||
if (_imageBuffers[2]) free(_imageBuffers[2]);
|
||||
|
@ -23,12 +26,15 @@
|
|||
|
||||
- (void)flip
|
||||
{
|
||||
if (_parent) return;
|
||||
_currentBuffer = (_currentBuffer + 1) % self.numberOfBuffers;
|
||||
_oddFrame = GB_is_odd_frame(_gb);
|
||||
[_child flip];
|
||||
}
|
||||
|
||||
- (unsigned) numberOfBuffers
|
||||
{
|
||||
assert(!_parent);
|
||||
return _frameBlendingMode? 3 : 2;
|
||||
}
|
||||
|
||||
|
@ -39,16 +45,23 @@
|
|||
|
||||
- (uint32_t *)currentBuffer
|
||||
{
|
||||
if (GB_unlikely(_parent)) {
|
||||
return [_parent currentBuffer];
|
||||
}
|
||||
return _imageBuffers[_currentBuffer];
|
||||
}
|
||||
|
||||
- (uint32_t *)previousBuffer
|
||||
{
|
||||
if (GB_unlikely(_parent)) {
|
||||
return [_parent previousBuffer];
|
||||
}
|
||||
return _imageBuffers[(_currentBuffer + 2) % self.numberOfBuffers];
|
||||
}
|
||||
|
||||
- (uint32_t *) pixels
|
||||
{
|
||||
assert(!_parent);
|
||||
return _imageBuffers[(_currentBuffer + 1) % self.numberOfBuffers];
|
||||
}
|
||||
|
||||
|
@ -56,10 +69,14 @@
|
|||
{
|
||||
_frameBlendingMode = frameBlendingMode;
|
||||
[self setNeedsDisplay];
|
||||
[_child setNeedsDisplay];
|
||||
}
|
||||
|
||||
- (GB_frame_blending_mode_t)frameBlendingMode
|
||||
{
|
||||
if (GB_unlikely(_parent)) {
|
||||
return [_parent frameBlendingMode];
|
||||
}
|
||||
if (_frameBlendingMode == GB_FRAME_BLENDING_MODE_ACCURATE) {
|
||||
if (!_gb || GB_is_sgb(_gb)) {
|
||||
return GB_FRAME_BLENDING_MODE_SIMPLE;
|
||||
|
@ -71,6 +88,7 @@
|
|||
|
||||
- (void)dealloc
|
||||
{
|
||||
if (_parent) return;
|
||||
free(_imageBuffers[0]);
|
||||
free(_imageBuffers[1]);
|
||||
free(_imageBuffers[2]);
|
||||
|
@ -82,4 +100,22 @@
|
|||
[self setNeedsDisplay:true];
|
||||
}
|
||||
#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
|
||||
|
|
|
@ -25,6 +25,7 @@ static const vector_float2 rect[] =
|
|||
vector_float2 _outputResolution;
|
||||
id<MTLCommandBuffer> _commandBuffer;
|
||||
bool _waitedForFrame;
|
||||
_Atomic unsigned _pendingFrames;
|
||||
}
|
||||
|
||||
+ (bool)isSupported
|
||||
|
@ -236,8 +237,11 @@ static const vector_float2 rect[] =
|
|||
- (void)flip
|
||||
{
|
||||
[super flip];
|
||||
if (_pendingFrames == 2) return;
|
||||
_pendingFrames++;
|
||||
dispatch_async(dispatch_get_main_queue(), ^{
|
||||
[(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:
|
||||
|
||||
| Offset | Content |
|
||||
|--------|---------------------------------------|
|
||||
| 0 | A four-letter ASCII identifier |
|
||||
| 4 | Length of the block, excluding header |
|
||||
|--------|-----------------------------------------------------------|
|
||||
| 0 | A four-letter ASCII identifier |
|
||||
| 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).
|
||||
|
||||
|
@ -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)
|
||||
* 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 END block with non-zero length
|
||||
* An END block with non-zero length
|
||||
|
|
|
@ -1,2 +1,2 @@
|
|||
DEF AGB = 1
|
||||
include "cgb_boot.asm"
|
||||
DEF AGB = 1
|
||||
include "cgb_boot.asm"
|
||||
|
|
|
@ -1,2 +1,2 @@
|
|||
DEF CGB0 = 1
|
||||
include "cgb_boot.asm"
|
||||
DEF CGB0 = 1
|
||||
include "cgb_boot.asm"
|
||||
|
|
|
@ -1,2 +1,2 @@
|
|||
DEF FAST = 1
|
||||
include "cgb_boot.asm"
|
||||
DEF FAST = 1
|
||||
include "cgb_boot.asm"
|
||||
|
|
|
@ -1,14 +1,14 @@
|
|||
; SameBoy DMG bootstrap ROM
|
||||
|
||||
INCLUDE "hardware.inc"
|
||||
include "sameboot.inc"
|
||||
|
||||
SECTION "BootCode", ROM0[$0]
|
||||
SECTION "BootCode", ROM0[$0000]
|
||||
Start:
|
||||
; Init stack pointer
|
||||
ld sp, $fffe
|
||||
ld sp, $FFFE
|
||||
|
||||
; Clear memory VRAM
|
||||
ld hl, $8000
|
||||
ld hl, _VRAM
|
||||
xor a
|
||||
|
||||
.clearVRAMLoop
|
||||
|
@ -17,24 +17,25 @@ Start:
|
|||
jr z, .clearVRAMLoop
|
||||
|
||||
; Init Audio
|
||||
ld a, $80
|
||||
ld a, AUDENA_ON
|
||||
ldh [rNR52], a
|
||||
assert AUDENA_ON == AUDLEN_DUTY_50
|
||||
ldh [rNR11], a
|
||||
ld a, $f3
|
||||
ldh [rNR12], a
|
||||
ldh [rNR51], a
|
||||
ld a, $F3
|
||||
ldh [rNR12], a ; Envelope $F, decreasing, sweep $3
|
||||
ldh [rNR51], a ; Channels 1+2+3+4 left, channels 1+2 right
|
||||
ld a, $77
|
||||
ldh [rNR50], a
|
||||
ldh [rNR50], a ; Volume $7, left and right
|
||||
|
||||
; Init BG palette
|
||||
ld a, $54
|
||||
ld a, %01_01_01_00
|
||||
ldh [rBGP], a
|
||||
|
||||
; Load logo from ROM.
|
||||
; 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.
|
||||
ld de, $104 ; Logo start
|
||||
ld hl, $8010 ; This is where we load the tiles in VRAM
|
||||
ld de, NintendoLogo
|
||||
ld hl, _VRAM + $10 ; This is where we load the tiles in VRAM
|
||||
|
||||
.loadLogoLoop
|
||||
ld a, [de] ; Read 2 rows
|
||||
|
@ -43,45 +44,45 @@ Start:
|
|||
call DoubleBitsAndWriteRow
|
||||
inc de
|
||||
ld a, e
|
||||
xor $34 ; End of logo
|
||||
xor LOW(NintendoLogoEnd)
|
||||
jr nz, .loadLogoLoop
|
||||
|
||||
; Load trademark symbol
|
||||
ld de, TrademarkSymbol
|
||||
ld c,$08
|
||||
ld c, TrademarkSymbolEnd - TrademarkSymbol
|
||||
.loadTrademarkSymbolLoop:
|
||||
ld a,[de]
|
||||
ld a, [de]
|
||||
inc de
|
||||
ldi [hl],a
|
||||
ldi [hl], a
|
||||
inc hl
|
||||
dec c
|
||||
jr nz, .loadTrademarkSymbolLoop
|
||||
|
||||
; Set up tilemap
|
||||
ld a,$19 ; Trademark symbol
|
||||
ld [$9910], a ; ... put in the superscript position
|
||||
ld hl,$992f ; Bottom right corner of the logo
|
||||
ld c,$c ; Tiles in a logo row
|
||||
ld a, $19 ; Trademark symbol tile ID
|
||||
ld [_SCRN0 + 8 * SCRN_VX_B + 16], a ; ... put in the superscript position
|
||||
ld hl, _SCRN0 + 9 * SCRN_VX_B + 15 ; Bottom right corner of the logo
|
||||
ld c, 12 ; Tiles in a logo row
|
||||
.tilemapLoop
|
||||
dec a
|
||||
jr z, .tilemapDone
|
||||
ldd [hl], a
|
||||
dec c
|
||||
jr nz, .tilemapLoop
|
||||
ld l,$0f ; Jump to top row
|
||||
ld l, $0F ; Jump to top row
|
||||
jr .tilemapLoop
|
||||
.tilemapDone
|
||||
|
||||
ld a, 30
|
||||
ldh [rSCY], a
|
||||
|
||||
|
||||
; Turn on LCD
|
||||
ld a, $91
|
||||
ld a, LCDCF_ON | LCDCF_BLK01 | LCDCF_BGON
|
||||
ldh [rLCDC], a
|
||||
|
||||
ld d, (-119) & $FF
|
||||
ld d, LOW(-119)
|
||||
ld c, 15
|
||||
|
||||
|
||||
.animate
|
||||
call WaitFrame
|
||||
ld a, d
|
||||
|
@ -94,41 +95,41 @@ Start:
|
|||
ld a, c
|
||||
cp 8
|
||||
jr nz, .noPaletteChange
|
||||
ld a, $A8
|
||||
ld a, %10_10_10_00
|
||||
ldh [rBGP], a
|
||||
.noPaletteChange
|
||||
dec c
|
||||
jr nz, .animate
|
||||
ld a, $fc
|
||||
ld a, %11_11_11_00
|
||||
ldh [rBGP], a
|
||||
|
||||
|
||||
; Play first sound
|
||||
ld a, $83
|
||||
call PlaySound
|
||||
ld b, 5
|
||||
call WaitBFrames
|
||||
; Play second sound
|
||||
ld a, $c1
|
||||
ld a, $C1
|
||||
call PlaySound
|
||||
|
||||
|
||||
|
||||
|
||||
; Wait ~1 second
|
||||
ld b, 60
|
||||
call WaitBFrames
|
||||
|
||||
|
||||
; Set registers to match the original DMG boot
|
||||
IF DEF(MGB)
|
||||
ld hl, $FFB0
|
||||
lb hl, BOOTUP_A_MGB, %10110000
|
||||
ELSE
|
||||
ld hl, $01B0
|
||||
lb hl, BOOTUP_A_DMG, %10110000
|
||||
ENDC
|
||||
push hl
|
||||
pop af
|
||||
ld hl, $014D
|
||||
ld bc, $0013
|
||||
ld de, $00D8
|
||||
|
||||
ld hl, HeaderChecksum
|
||||
lb bc, 0, LOW(rNR13) ; $0013
|
||||
lb de, 0, $D8 ; $00D8
|
||||
|
||||
; Boot the game
|
||||
jp BootGame
|
||||
|
||||
|
@ -155,7 +156,7 @@ DoubleBitsAndWriteRow:
|
|||
|
||||
WaitFrame:
|
||||
push hl
|
||||
ld hl, $FF0F
|
||||
ld hl, rIF
|
||||
res 0, [hl]
|
||||
.wait
|
||||
bit 0, [hl]
|
||||
|
@ -171,14 +172,25 @@ WaitBFrames:
|
|||
|
||||
PlaySound:
|
||||
ldh [rNR13], a
|
||||
ld a, $87
|
||||
ld a, AUDHIGH_RESTART | $7
|
||||
ldh [rNR14], a
|
||||
ret
|
||||
|
||||
|
||||
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:
|
||||
ldh [rBANK], a ; unmap boot ROM
|
||||
ldh [rBANK], a ; unmap boot ROM
|
||||
|
|
|
@ -1,9 +1,16 @@
|
|||
;*
|
||||
;* Gameboy Hardware definitions
|
||||
;* https://github.com/gbdev/hardware.inc
|
||||
;*
|
||||
;* Based on Jones' hardware.inc
|
||||
;* 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.2 - 18-Jul-97 : Added revision check macro
|
||||
;* 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.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.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
|
||||
FAIL "This version of 'hardware.inc' requires RGBDS version 0.5.0 or later."
|
||||
|
@ -41,14 +59,31 @@ ENDC
|
|||
IF !DEF(HARDWARE_INC)
|
||||
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
|
||||
;NOTE: REVISION NUMBER CHANGES MUST BE ADDED
|
||||
;TO SECOND PARAMETER IN FOLLOWING LINE.
|
||||
IF \1 > 4.5 ;PUT REVISION NUMBER HERE
|
||||
WARN "Version \1 or later of 'hardware.inc' is required."
|
||||
DEF CUR_VER equs "4,9,1" ; ** UPDATE THIS LINE WHEN CHANGING THE REVISION NUMBER **
|
||||
|
||||
DEF MIN_VER equs STRRPL("\1", ".", ",")
|
||||
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
|
||||
\nENDM"""
|
||||
INTERNAL_CHK
|
||||
___internal {CUR_VER}, {MIN_VER},0,0
|
||||
PURGE CUR_VER, MIN_VER, INTERNAL_CHK, ___internal
|
||||
ENDM
|
||||
|
||||
|
||||
;***************************************************************************
|
||||
;*
|
||||
;* General memory region constants
|
||||
;*
|
||||
;***************************************************************************
|
||||
|
||||
DEF _VRAM EQU $8000 ; $8000->$9FFF
|
||||
DEF _SCRN0 EQU $9800 ; $9800->$9BFF
|
||||
DEF _SCRN1 EQU $9C00 ; $9C00->$9FFF
|
||||
|
@ -60,17 +95,80 @@ DEF _IO EQU $FF00 ; $FF00->$FF7F,$FFFF
|
|||
DEF _AUD3WAVERAM EQU $FF30 ; $FF30->$FF3F
|
||||
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.
|
||||
DEF rRAMB EQU $4000 ; $4000->$5fff - Bit 3 enables rumble (if present)
|
||||
;***************************************************************************
|
||||
;*
|
||||
;* MBC registers
|
||||
;*
|
||||
;***************************************************************************
|
||||
|
||||
; *** 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 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_SOURCE EQU %00000001 ;Shift Clock (0=External Clock, 1=Internal Clock)
|
||||
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_SOURCE EQU %00000001 ; Shift Clock (0=External Clock, 1=Internal Clock)
|
||||
|
||||
DEF SCB_START EQU 7
|
||||
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_WINOFF EQU %00000000 ; Window Display
|
||||
DEF LCDCF_WINON EQU %00100000 ; Window Display
|
||||
DEF LCDCF_BG8800 EQU %00000000 ; BG & Window Tile Data Select
|
||||
DEF LCDCF_BG8000 EQU %00010000 ; BG & Window Tile Data Select
|
||||
DEF LCDCF_BLK21 EQU %00000000 ; 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_BG9C00 EQU %00001000 ; BG Tile Map Display Select
|
||||
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_WIN9C00 EQU 6 ; Window Tile Map Display Select
|
||||
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_OBJ16 EQU 2 ; OBJ Construction
|
||||
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_LO EQU %00000000
|
||||
|
||||
DEF RPB_LED_ON EQU 0
|
||||
DEF RPB_DATAIN EQU 1
|
||||
|
||||
|
||||
; --
|
||||
; -- BCPS ($FF68)
|
||||
; -- Background Color Palette Specification (R/W)
|
||||
; -- BCPS/BGPI ($FF68)
|
||||
; -- Background Color Palette Specification (aka Background Palette Index) (R/W)
|
||||
; --
|
||||
DEF rBCPS EQU $FF68
|
||||
DEF rBGPI EQU rBCPS
|
||||
|
||||
DEF BCPSF_AUTOINC EQU %10000000 ; Auto Increment (0=Disabled, 1=Increment after Writing)
|
||||
DEF BCPSB_AUTOINC EQU 7
|
||||
DEF BGPIF_AUTOINC EQU BCPSF_AUTOINC
|
||||
DEF BGPIB_AUTOINC EQU BCPSB_AUTOINC
|
||||
|
||||
|
||||
; --
|
||||
; -- BCPD ($FF69)
|
||||
; -- Background Color Palette Data (R/W)
|
||||
; -- BCPD/BGPD ($FF69)
|
||||
; -- Background Color Palette Data (aka Background Palette Data) (R/W)
|
||||
; --
|
||||
DEF rBCPD EQU $FF69
|
||||
DEF rBGPD EQU rBCPD
|
||||
|
||||
|
||||
; --
|
||||
; -- OCPS ($FF6A)
|
||||
; -- Object Color Palette Specification (R/W)
|
||||
; -- OCPS/OBPI ($FF6A)
|
||||
; -- Object Color Palette Specification (aka Object Background Palette Index) (R/W)
|
||||
; --
|
||||
DEF rOCPS EQU $FF6A
|
||||
DEF rOBPI EQU rOCPS
|
||||
|
||||
DEF OCPSF_AUTOINC EQU %10000000 ; Auto Increment (0=Disabled, 1=Increment after Writing)
|
||||
DEF OCPSB_AUTOINC EQU 7
|
||||
DEF OBPIF_AUTOINC EQU OCPSF_AUTOINC
|
||||
DEF OBPIB_AUTOINC EQU OCPSB_AUTOINC
|
||||
|
||||
|
||||
; --
|
||||
; -- OCPD ($FF6B)
|
||||
; -- Object Color Palette Data (R/W)
|
||||
; -- OCPD/OBPD ($FF6B)
|
||||
; -- Object Color Palette Data (aka Object Background Palette Data) (R/W)
|
||||
; --
|
||||
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
|
||||
|
||||
|
||||
; 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)
|
||||
; -- Interrupt Enable (R/W)
|
||||
|
@ -790,7 +903,6 @@ DEF AUDENV_DOWN EQU %00000000
|
|||
; -- Can be used with AUD1HIGH, AUD2HIGH, AUD3HIGH
|
||||
; -- See AUD1HIGH for more info
|
||||
; --
|
||||
|
||||
DEF AUDHIGH_RESTART EQU %10000000
|
||||
DEF AUDHIGH_LENGTH_ON EQU %01000000
|
||||
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
|
||||
DEF CART_COMPATIBLE_DMG EQU $00
|
||||
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_128KB EQU 4 ; 16 banks
|
||||
|
||||
DEF CART_SRAM_ENABLE EQU $0A
|
||||
DEF CART_SRAM_DISABLE EQU $00
|
||||
|
||||
; $014A Destination code
|
||||
DEF CART_DEST_JAPANESE EQU $00
|
||||
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_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_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)
|
||||
|
||||
|
||||
;*
|
||||
;* 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.
|
||||
|
||||
DEF IEF_LCDC EQU %00000010 ; LCDC (see STAT)
|
||||
|
@ -983,6 +1105,9 @@ DEF _VRAM8000 EQU _VRAM
|
|||
DEF _VRAM8800 EQU _VRAM+$800
|
||||
DEF _VRAM9000 EQU _VRAM+$1000
|
||||
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
|
||||
|
|
|
@ -1,2 +1,2 @@
|
|||
DEF MGB = 1
|
||||
include "dmg_boot.asm"
|
||||
DEF MGB = 1
|
||||
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
|
||||
include "sgb_boot.asm"
|
||||
DEF SGB2 = 1
|
||||
include "sgb_boot.asm"
|
||||
|
|
|
@ -1,14 +1,14 @@
|
|||
; SameBoy SGB bootstrap ROM
|
||||
|
||||
INCLUDE "hardware.inc"
|
||||
include "sameboot.inc"
|
||||
|
||||
SECTION "BootCode", ROM0[$0]
|
||||
SECTION "BootCode", ROM0[$0000]
|
||||
Start:
|
||||
; Init stack pointer
|
||||
ld sp, $fffe
|
||||
ld sp, $FFFE
|
||||
|
||||
; Clear memory VRAM
|
||||
ld hl, $8000
|
||||
ld hl, _VRAM
|
||||
xor a
|
||||
|
||||
.clearVRAMLoop
|
||||
|
@ -17,24 +17,25 @@ Start:
|
|||
jr z, .clearVRAMLoop
|
||||
|
||||
; Init Audio
|
||||
ld a, $80
|
||||
ld a, AUDENA_ON
|
||||
ldh [rNR52], a
|
||||
assert AUDENA_ON == AUDLEN_DUTY_50
|
||||
ldh [rNR11], a
|
||||
ld a, $f3
|
||||
ldh [rNR12], a
|
||||
ldh [rNR51], a
|
||||
ld a, $F3
|
||||
ldh [rNR12], a ; Envelope $F, decreasing, sweep $3
|
||||
ldh [rNR51], a ; Channels 1+2+3+4 left, channels 1+2 right
|
||||
ld a, $77
|
||||
ldh [rNR50], a
|
||||
ldh [rNR50], a ; Volume $7, left and right
|
||||
|
||||
; Init BG palette to white
|
||||
ld a, $0
|
||||
ld a, %00_00_00_00
|
||||
ldh [rBGP], a
|
||||
|
||||
; Load logo from ROM.
|
||||
; 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.
|
||||
ld de, $104 ; Logo start
|
||||
ld hl, $8010 ; This is where we load the tiles in VRAM
|
||||
ld de, NintendoLogo
|
||||
ld hl, _VRAM + $10 ; This is where we load the tiles in VRAM
|
||||
|
||||
.loadLogoLoop
|
||||
ld a, [de] ; Read 2 rows
|
||||
|
@ -43,82 +44,82 @@ Start:
|
|||
call DoubleBitsAndWriteRow
|
||||
inc de
|
||||
ld a, e
|
||||
xor $34 ; End of logo
|
||||
xor LOW(NintendoLogoEnd)
|
||||
jr nz, .loadLogoLoop
|
||||
|
||||
; Load trademark symbol
|
||||
ld de, TrademarkSymbol
|
||||
ld c,$08
|
||||
ld c, TrademarkSymbolEnd - TrademarkSymbol
|
||||
.loadTrademarkSymbolLoop:
|
||||
ld a,[de]
|
||||
ld a, [de]
|
||||
inc de
|
||||
ldi [hl],a
|
||||
ldi [hl], a
|
||||
inc hl
|
||||
dec c
|
||||
jr nz, .loadTrademarkSymbolLoop
|
||||
|
||||
; Set up tilemap
|
||||
ld a,$19 ; Trademark symbol
|
||||
ld [$9910], a ; ... put in the superscript position
|
||||
ld hl,$992f ; Bottom right corner of the logo
|
||||
ld c,$c ; Tiles in a logo row
|
||||
ld a, $19 ; Trademark symbol tile ID
|
||||
ld [_SCRN0 + 8 * SCRN_VX_B + 16], a ; ... put in the superscript position
|
||||
ld hl, _SCRN0 + 9 * SCRN_VX_B + 15 ; Bottom right corner of the logo
|
||||
ld c, 12 ; Tiles in a logo row
|
||||
.tilemapLoop
|
||||
dec a
|
||||
jr z, .tilemapDone
|
||||
ldd [hl], a
|
||||
dec c
|
||||
jr nz, .tilemapLoop
|
||||
ld l,$0f ; Jump to top row
|
||||
ld l, $0F ; Jump to top row
|
||||
jr .tilemapLoop
|
||||
.tilemapDone
|
||||
|
||||
; Turn on LCD
|
||||
ld a, $91
|
||||
ld a, LCDCF_ON | LCDCF_BLK01 | LCDCF_BGON
|
||||
ldh [rLCDC], a
|
||||
|
||||
ld a, $f1 ; Packet magic, increases by 2 for every packet
|
||||
ldh [_HRAM], a
|
||||
ld hl, $104 ; Header start
|
||||
|
||||
ld a, $F1 ; Packet magic, increases by 2 for every packet
|
||||
ldh [hCommand], a
|
||||
ld hl, NintendoLogo ; Header start
|
||||
|
||||
xor a
|
||||
ld c, a ; JOYP
|
||||
|
||||
.sendCommand
|
||||
xor a
|
||||
ld [c], a
|
||||
ldh [c], a
|
||||
ld a, $30
|
||||
ld [c], a
|
||||
|
||||
ldh a, [_HRAM]
|
||||
ldh [c], a
|
||||
|
||||
ldh a, [hCommand]
|
||||
call SendByte
|
||||
push hl
|
||||
ld b, $e
|
||||
|
||||
ld b, 14
|
||||
ld d, 0
|
||||
|
||||
.checksumLoop
|
||||
call ReadHeaderByte
|
||||
add d
|
||||
ld d, a
|
||||
dec b
|
||||
jr nz, .checksumLoop
|
||||
|
||||
|
||||
; Send checksum
|
||||
call SendByte
|
||||
pop hl
|
||||
|
||||
ld b, $e
|
||||
|
||||
ld b, 14
|
||||
.sendLoop
|
||||
call ReadHeaderByte
|
||||
call SendByte
|
||||
dec b
|
||||
jr nz, .sendLoop
|
||||
|
||||
|
||||
; Done bit
|
||||
ld a, $20
|
||||
ld [c], a
|
||||
ldh [c], a
|
||||
ld a, $30
|
||||
ld [c], a
|
||||
|
||||
ldh [c], a
|
||||
|
||||
; Wait 4 frames
|
||||
ld e, 4
|
||||
ld a, 1
|
||||
|
@ -126,41 +127,41 @@ Start:
|
|||
xor a
|
||||
.waitLoop
|
||||
ldh [rIF], a
|
||||
db $76 ; halt, compatible with rgbds 0.5-0.8
|
||||
halt
|
||||
nop
|
||||
dec e
|
||||
jr nz, .waitLoop
|
||||
ldh [rIE], a
|
||||
|
||||
|
||||
; Update command
|
||||
ldh a, [_HRAM]
|
||||
ldh a, [hCommand]
|
||||
add 2
|
||||
ldh [_HRAM], a
|
||||
|
||||
ldh [hCommand], a
|
||||
|
||||
ld a, $58
|
||||
cp l
|
||||
jr nz, .sendCommand
|
||||
|
||||
|
||||
; Write to sound registers for DMG compatibility
|
||||
ld c, $13
|
||||
ld a, $c1
|
||||
ld [c], a
|
||||
ld c, LOW(rNR13)
|
||||
ld a, $C1
|
||||
ldh [c], a
|
||||
inc c
|
||||
ld a, 7
|
||||
ld [c], a
|
||||
|
||||
ld a, $7
|
||||
ldh [c], a
|
||||
|
||||
; Init BG palette
|
||||
ld a, $fc
|
||||
ld a, %11_11_11_00
|
||||
ldh [rBGP], a
|
||||
|
||||
|
||||
; Set registers to match the original SGB boot
|
||||
IF DEF(SGB2)
|
||||
ld a, $FF
|
||||
ld a, BOOTUP_A_MGB
|
||||
ELSE
|
||||
ld a, 1
|
||||
ld a, BOOTUP_A_DMG
|
||||
ENDC
|
||||
ld hl, $c060
|
||||
|
||||
ld hl, $C060
|
||||
|
||||
; Boot the game
|
||||
jp BootGame
|
||||
|
||||
|
@ -184,9 +185,9 @@ SendByte:
|
|||
jr c, .zeroBit
|
||||
add a ; 10 -> 20
|
||||
.zeroBit
|
||||
ld [c], a
|
||||
ldh [c], a
|
||||
ld a, $30
|
||||
ld [c], a
|
||||
ldh [c], a
|
||||
dec d
|
||||
ret z
|
||||
jr .loop
|
||||
|
@ -212,8 +213,23 @@ DoubleBitsAndWriteRow:
|
|||
ret
|
||||
|
||||
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:
|
||||
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 "GBSplitView.h"
|
||||
#import "GBVisualizerView.h"
|
||||
#import "GBCPUView.h"
|
||||
#import "GBOSDView.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 GBPaletteView;
|
||||
@class GBObjectView;
|
||||
|
@ -67,14 +80,19 @@
|
|||
@property IBOutlet GBDebuggerButton *debuggerNextButton;
|
||||
@property IBOutlet GBDebuggerButton *debuggerStepButton;
|
||||
@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;
|
||||
-(uint8_t) readMemory:(uint16_t) addr;
|
||||
-(void) writeMemory:(uint16_t) addr value:(uint8_t)value;
|
||||
-(void) performAtomicBlock: (void (^)())block;
|
||||
-(void) connectLinkCable:(NSMenuItem *)sender;
|
||||
-(int)loadStateFile:(const char *)path noErrorOnNotFound:(bool)noErrorOnFileNotFound;
|
||||
- (void) performAtomicBlock: (void (^)())block;
|
||||
- (void) connectLinkCable:(NSMenuItem *)sender;
|
||||
- (int)loadStateFile:(const char *)path noErrorOnNotFound:(bool)noErrorOnFileNotFound;
|
||||
- (NSString *)captureOutputForBlock: (void (^)())block;
|
||||
- (NSFont *)debuggerFontOfSize:(unsigned)size;
|
||||
@end
|
||||
|
||||
|
|
536
Cocoa/Document.m
|
@ -11,6 +11,7 @@
|
|||
#import "GBTerminalTextFieldCell.h"
|
||||
#import "BigSurToolbar.h"
|
||||
#import "GBPaletteEditorController.h"
|
||||
#import "GBCheatSearchController.h"
|
||||
#import "GBObjectView.h"
|
||||
#import "GBPaletteView.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: 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 ()
|
||||
@property GBAudioClient *audioClient;
|
||||
|
@ -100,6 +91,7 @@ enum model {
|
|||
bool _logToSideView;
|
||||
bool _shouldClearSideView;
|
||||
enum model _currentModel;
|
||||
bool _usesAutoModel;
|
||||
|
||||
bool _rewind;
|
||||
bool _modelsChanging;
|
||||
|
@ -126,6 +118,8 @@ enum model {
|
|||
|
||||
NSDate *_fileModificationTime;
|
||||
__weak NSThread *_emulationThread;
|
||||
|
||||
GBCheatSearchController *_cheatSearchController;
|
||||
}
|
||||
|
||||
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];
|
||||
}
|
||||
|
||||
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);
|
||||
[self log:string withAttributes: attributes];
|
||||
|
@ -263,6 +257,7 @@ static void debuggerReloadCallback(GB_gameboy_t *gb)
|
|||
|
||||
case MODEL_NONE:
|
||||
case MODEL_QUICK_RESET:
|
||||
case MODEL_AUTO:
|
||||
case MODEL_CGB:
|
||||
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_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_enable_skipped_frame_vblank_callbacks(&_gb, true);
|
||||
GB_set_log_callback(&_gb, (GB_log_callback_t) consoleLog);
|
||||
GB_set_input_callback(&_gb, (GB_input_callback_t) consoleInput);
|
||||
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_set_rumble_callback(&_gb, rumbleCallback);
|
||||
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;
|
||||
__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"]);
|
||||
[self observeStandardDefaultsKey:@"GBBorderMode" withBlock:^(NSNumber *value) {
|
||||
_borderModeChanged = true;
|
||||
weakSelf->_borderModeChanged = true;
|
||||
}];
|
||||
|
||||
[self observeStandardDefaultsKey:@"GBHighpassFilter" withBlock:^(NSNumber *value) {
|
||||
|
@ -342,6 +338,20 @@ static void debuggerReloadCallback(GB_gameboy_t *gb)
|
|||
[self observeStandardDefaultsKey:@"GBRumbleMode" withBlock:^(NSNumber *value) {
|
||||
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
|
||||
|
@ -356,11 +366,29 @@ static void debuggerReloadCallback(GB_gameboy_t *gb)
|
|||
|
||||
- (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) {
|
||||
dispatch_async(dispatch_get_main_queue(), ^{
|
||||
[_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) {
|
||||
[self.view flip];
|
||||
if (_borderModeChanged) {
|
||||
|
@ -677,15 +705,46 @@ static unsigned *multiplication_table_for_frequency(unsigned frequency)
|
|||
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
|
||||
{
|
||||
[self stop];
|
||||
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];
|
||||
_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) {
|
||||
GB_quick_reset(&_gb);
|
||||
}
|
||||
|
@ -696,21 +755,12 @@ static unsigned *multiplication_table_for_frequency(unsigned frequency)
|
|||
if (old_width != GB_get_screen_width(&_gb)) {
|
||||
[self.view screenSizeChanged];
|
||||
}
|
||||
|
||||
[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];
|
||||
if (_gbsTracks) {
|
||||
[self changeGBSTrack:sender];
|
||||
}
|
||||
|
||||
if (_hexController) {
|
||||
/* 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
|
||||
{
|
||||
[super windowControllerDidLoadNib:aController];
|
||||
// Interface Builder bug?
|
||||
[self.consoleWindow setContentSize:self.consoleWindow.minSize];
|
||||
[self.consoleWindow setContentSize:self.consoleWindow.frame.size];
|
||||
/* Close Open Panels, if any */
|
||||
for (NSWindow *window in [[NSApplication sharedApplication] windows]) {
|
||||
if ([window isKindOfClass:[NSOpenPanel class]]) {
|
||||
|
@ -765,7 +896,7 @@ static unsigned *multiplication_table_for_frequency(unsigned frequency)
|
|||
NSMutableParagraphStyle *paragraph_style = [[NSMutableParagraphStyle alloc] init];
|
||||
[paragraph_style setLineSpacing:2];
|
||||
|
||||
self.debuggerSideViewInput.font = [NSFont userFixedPitchFontOfSize:12];
|
||||
self.debuggerSideViewInput.font = [self debuggerFontOfSize:0];
|
||||
self.debuggerSideViewInput.textColor = [NSColor whiteColor];
|
||||
self.debuggerSideViewInput.defaultParagraphStyle = paragraph_style;
|
||||
[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.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]];
|
||||
if (@available(macOS 11.0, *)) {
|
||||
self.consoleWindow.subtitle = [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;
|
||||
|
||||
|
@ -871,19 +1009,10 @@ static unsigned *multiplication_table_for_frequency(unsigned frequency)
|
|||
[self observeStandardDefaultsKey:@"GBVolume" withBlock:^(id newValue) {
|
||||
weakSelf->_volume = [[NSUserDefaults standardUserDefaults] doubleForKey:@"GBVolume"];
|
||||
}];
|
||||
|
||||
if ([[NSUserDefaults standardUserDefaults] boolForKey:@"EmulateDMG"]) {
|
||||
_currentModel = MODEL_DMG;
|
||||
}
|
||||
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;
|
||||
}
|
||||
|
||||
|
||||
_currentModel = [[NSUserDefaults standardUserDefaults] integerForKey:@"GBEmulatedModel"];
|
||||
_usesAutoModel = _currentModel == MODEL_AUTO;
|
||||
|
||||
[self initCommon];
|
||||
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.font = [self debuggerFontOfSize:12];
|
||||
[_hexController setBytesPerColumn:1];
|
||||
[_hexController setEditMode:HFOverwriteMode];
|
||||
|
||||
|
@ -946,6 +1076,16 @@ static unsigned *multiplication_table_for_frequency(unsigned frequency)
|
|||
[self.memoryView addSubview: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;
|
||||
}
|
||||
|
||||
|
@ -1045,6 +1185,17 @@ static unsigned *multiplication_table_for_frequency(unsigned frequency)
|
|||
if (@available(macOS 10.10, *)) {
|
||||
_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
|
||||
|
@ -1125,7 +1276,7 @@ static bool is_path_writeable(const char *path)
|
|||
return true;
|
||||
}
|
||||
|
||||
- (int) loadROM
|
||||
- (int)loadROM
|
||||
{
|
||||
__block int ret = 0;
|
||||
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_cheats(&_gb, self.chtPath.UTF8String);
|
||||
GB_load_cheats(&_gb, self.chtPath.UTF8String, true);
|
||||
dispatch_async(dispatch_get_main_queue(), ^{
|
||||
[self.cheatWindowController cheatsUpdated];
|
||||
});
|
||||
|
@ -1177,6 +1328,9 @@ static bool is_path_writeable(const char *path)
|
|||
[GBWarningPopover popoverWithContents:rom_warnings onWindow:self.mainWindow];
|
||||
}
|
||||
_fileModificationTime = [[NSFileManager defaultManager] attributesOfItemAtPath:fileName error:nil][NSFileModificationDate];
|
||||
if (_usesAutoModel) {
|
||||
_currentModel = [self bestModelForROM];
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
@ -1206,6 +1360,7 @@ static bool is_path_writeable(const char *path)
|
|||
[self.vramWindow close];
|
||||
[self.printerFeedWindow close];
|
||||
[self.cheatsWindow close];
|
||||
[_cheatSearchController.window close];
|
||||
[super close];
|
||||
}
|
||||
|
||||
|
@ -1215,6 +1370,8 @@ static bool is_path_writeable(const char *path)
|
|||
GB_debugger_break(&_gb);
|
||||
[self start];
|
||||
[self.consoleWindow makeKeyAndOrderFront:nil];
|
||||
double secondUsage = GB_debugger_get_second_cpu_usage(&_gb);
|
||||
_cpuCounter.stringValue = [NSString stringWithFormat:@"%.2f%%", secondUsage * 100];
|
||||
[self.consoleInput becomeFirstResponder];
|
||||
}
|
||||
|
||||
|
@ -1243,14 +1400,19 @@ static bool is_path_writeable(const char *path)
|
|||
- (BOOL)validateUserInterfaceItem:(id<NSValidatedUserInterfaceItem>)anItem
|
||||
{
|
||||
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:)) {
|
||||
[(NSMenuItem *)anItem setState:self.isPaused];
|
||||
return !GB_debugger_is_stopped(&_gb);
|
||||
}
|
||||
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:)) {
|
||||
if (![[NSUserDefaults standardUserDefaults] boolForKey:@"DeveloperMode"]) {
|
||||
|
@ -1291,6 +1453,9 @@ static bool is_path_writeable(const char *path)
|
|||
else if ([anItem action] == @selector(decreaseWindowSize:)) {
|
||||
return [self newRect:NULL forWindow:_mainWindow action:GBWindowResizeActionDecrease];
|
||||
}
|
||||
else if ([anItem action] == @selector(reloadROM:)) {
|
||||
return !_gbsTracks;
|
||||
}
|
||||
|
||||
return [super validateUserInterfaceItem:anItem];
|
||||
}
|
||||
|
@ -1432,7 +1597,9 @@ enum GBWindowResizeAction
|
|||
[self reloadVRAMData: nil];
|
||||
|
||||
[textView.textStorage appendAttributedString:_pendingConsoleOutput];
|
||||
[textView scrollToEndOfDocument:nil];
|
||||
if (!_logToSideView) {
|
||||
[textView scrollToEndOfDocument:nil];
|
||||
}
|
||||
if ([[NSUserDefaults standardUserDefaults] boolForKey:@"DeveloperMode"]) {
|
||||
[self.consoleWindow orderFront:nil];
|
||||
}
|
||||
|
@ -1441,7 +1608,7 @@ enum GBWindowResizeAction
|
|||
[_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
|
||||
if (_capturedOutput) {
|
||||
|
@ -1450,7 +1617,7 @@ enum GBWindowResizeAction
|
|||
}
|
||||
|
||||
|
||||
NSFont *font = [NSFont userFixedPitchFontOfSize:12];
|
||||
NSFont *font = [self debuggerFontOfSize:0];
|
||||
NSUnderlineStyle underline = NSUnderlineStyleNone;
|
||||
if (attributes & GB_LOG_BOLD) {
|
||||
font = [[NSFontManager sharedFontManager] convertFont:font toHaveTrait:NSBoldFontMask];
|
||||
|
@ -1490,7 +1657,9 @@ enum GBWindowResizeAction
|
|||
|
||||
- (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
|
||||
|
@ -1691,18 +1860,6 @@ enum GBWindowResizeAction
|
|||
[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
|
||||
{
|
||||
while (!GB_is_inited(&_gb));
|
||||
|
@ -1763,6 +1920,11 @@ enum GBWindowResizeAction
|
|||
if (self.memoryWindow.isVisible) {
|
||||
[_hexController reloadData];
|
||||
}
|
||||
if (_cheatSearchController.window.isVisible) {
|
||||
if ([_cheatSearchController.tableView editedColumn] != 2) {
|
||||
[_cheatSearchController.tableView reloadData];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
- (IBAction) reloadVRAMData: (id) sender
|
||||
|
@ -1847,124 +2009,130 @@ enum GBWindowResizeAction
|
|||
|
||||
- (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:^{
|
||||
uint16_t addr;
|
||||
uint16_t bank;
|
||||
if (GB_debugger_evaluate(&_gb, [[sender stringValue] UTF8String], &addr, &bank)) {
|
||||
return;
|
||||
if (GB_debugger_evaluate(&_gb, [expression UTF8String], &addr, &bank)) {
|
||||
fail = true;
|
||||
}
|
||||
|
||||
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) {
|
||||
NSBeep();
|
||||
[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
|
||||
{
|
||||
NSString *expression = [sender stringValue];
|
||||
__block uint16_t addr, bank;
|
||||
__block bool fail = false;
|
||||
NSString *error = [self captureOutputForBlock:^{
|
||||
uint16_t addr, bank;
|
||||
if (GB_debugger_evaluate(&_gb, [[sender stringValue] UTF8String], &addr, &bank)) {
|
||||
if (GB_debugger_evaluate(&_gb, [expression UTF8String], &addr, &bank)) {
|
||||
fail = true;
|
||||
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) {
|
||||
NSBeep();
|
||||
[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
|
||||
|
@ -2002,9 +2170,8 @@ enum GBWindowResizeAction
|
|||
}
|
||||
byteArray.selectedBank = bank;
|
||||
_statusRep.bankForDescription = bank;
|
||||
if (bank != (uint16_t)-1) {
|
||||
[self.memoryBankInput setStringValue:[NSString stringWithFormat:@"$%x", byteArray.selectedBank]];
|
||||
}
|
||||
[self.memoryBankInput setStringValue:(bank == (uint16_t)-1)? @"" :
|
||||
[NSString stringWithFormat:@"$%x", byteArray.selectedBank]];
|
||||
|
||||
[_hexController reloadData];
|
||||
for (NSView *view in self.memoryView.subviews) {
|
||||
|
@ -2047,7 +2214,7 @@ enum GBWindowResizeAction
|
|||
NSError *error;
|
||||
AVCaptureDevice *device = [AVCaptureDevice defaultDeviceWithMediaType: AVMediaTypeVideo];
|
||||
AVCaptureDeviceInput *input = [AVCaptureDeviceInput deviceInputWithDevice: device error: &error];
|
||||
CMVideoDimensions dimensions = CMVideoFormatDescriptionGetDimensions([[[device formats] lastObject] formatDescription]);
|
||||
CMVideoDimensions dimensions = CMVideoFormatDescriptionGetDimensions([[device activeFormat] formatDescription]);
|
||||
|
||||
if (!input) {
|
||||
GB_camera_updated(&_gb);
|
||||
|
@ -2344,9 +2511,16 @@ enum GBWindowResizeAction
|
|||
- (void)setFileURL:(NSURL *)fileURL
|
||||
{
|
||||
[super setFileURL:fileURL];
|
||||
self.consoleWindow.title = [NSString stringWithFormat:@"Debug Console – %@", [[fileURL path] lastPathComponent]];
|
||||
self.memoryWindow.title = [NSString stringWithFormat:@"Memory – %@", [[fileURL path] lastPathComponent]];
|
||||
self.vramWindow.title = [NSString stringWithFormat:@"VRAM Viewer – %@", [[fileURL path] lastPathComponent]];
|
||||
if (@available(macOS 11.0, *)) {
|
||||
self.consoleWindow.subtitle = [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]];
|
||||
}
|
||||
}
|
||||
|
||||
- (BOOL)splitView:(GBSplitView *)splitView canCollapseSubview:(NSView *)subview;
|
||||
|
@ -2388,6 +2562,14 @@ enum GBWindowResizeAction
|
|||
[self.cheatsWindow makeKeyAndOrderFront:nil];
|
||||
}
|
||||
|
||||
- (IBAction)showCheatSearch:(id)sender
|
||||
{
|
||||
if (!_cheatSearchController) {
|
||||
_cheatSearchController = [GBCheatSearchController controllerWithDocument:self];
|
||||
}
|
||||
[_cheatSearchController.window makeKeyAndOrderFront:sender];
|
||||
}
|
||||
|
||||
- (IBAction)toggleCheats:(id)sender
|
||||
{
|
||||
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(&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);
|
||||
_slave = partner;
|
||||
partner->_master = self;
|
||||
GB_set_turbo_cap(&partner->_gb, 0);
|
||||
_linkOffset = 0;
|
||||
GB_set_serial_transfer_bit_start_callback(&_gb, _linkCableBitStart);
|
||||
GB_set_serial_transfer_bit_start_callback(&partner->_gb, _linkCableBitStart);
|
||||
|
@ -2773,4 +2958,15 @@ enum GBWindowResizeAction
|
|||
[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
|
||||
|
|
|
@ -1,8 +1,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>
|
||||
<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="documents saved in the Xcode 8 format" minToolsVersion="8.0"/>
|
||||
</dependencies>
|
||||
|
@ -15,15 +15,19 @@
|
|||
<outlet property="consoleInput" destination="l22-S8-uji" id="Heu-am-YgB"/>
|
||||
<outlet property="consoleOutput" destination="doS-dM-hnl" id="Gn5-ju-Wb0"/>
|
||||
<outlet property="consoleWindow" destination="21F-Ah-yHX" id="eQ4-ug-LsT"/>
|
||||
<outlet property="debuggerBackstepButton" destination="onn-R8-3vg" id="gi1-dC-tJj"/>
|
||||
<outlet property="debuggerContinueButton" destination="G4h-KO-Z3g" id="Dad-5e-XYM"/>
|
||||
<outlet property="debuggerFinishButton" destination="vtb-n5-Qlz" id="9vv-fJ-gxp"/>
|
||||
<outlet property="debuggerNextButton" destination="cOi-Rs-9gS" id="Xjx-uM-D0u"/>
|
||||
<outlet property="cpuCounter" destination="xdx-GC-Tb8" id="oSn-U3-qvg"/>
|
||||
<outlet property="cpuView" destination="aBf-yU-8M0" id="RIb-Fj-lvt"/>
|
||||
<outlet property="debugBar" destination="sah-kv-6KJ" id="24d-aM-rs5"/>
|
||||
<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="debuggerSideViewInput" destination="w0g-eK-jM4" id="GBf-WK-ryI"/>
|
||||
<outlet property="debuggerSidebarEffectView" destination="4Z2-33-dYY" id="Ja6-bC-rQg"/>
|
||||
<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="feedImageView" destination="Ar0-nN-eop" id="wHa-St-o4G"/>
|
||||
<outlet property="gridButton" destination="fL6-2S-Rgd" id="jtV-jh-GHC"/>
|
||||
|
@ -52,7 +56,7 @@
|
|||
</customObject>
|
||||
<customObject id="-1" userLabel="First Responder" customClass="FirstResponder"/>
|
||||
<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"/>
|
||||
<windowCollectionBehavior key="collectionBehavior" fullScreenPrimary="YES"/>
|
||||
<rect key="contentRect" x="0.0" y="0.0" width="160" height="144"/>
|
||||
|
@ -86,41 +90,41 @@
|
|||
</connections>
|
||||
<point key="canvasLocation" x="293" y="347"/>
|
||||
</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"/>
|
||||
<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"/>
|
||||
<value key="minSize" type="size" width="921" height="400"/>
|
||||
<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"/>
|
||||
<subviews>
|
||||
<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"/>
|
||||
</box>
|
||||
<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"/>
|
||||
<subviews>
|
||||
<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"/>
|
||||
<subviews>
|
||||
<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"/>
|
||||
<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"/>
|
||||
<subviews>
|
||||
<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"/>
|
||||
<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"/>
|
||||
<size key="minSize" width="591" height="349"/>
|
||||
<size key="minSize" width="591" height="429"/>
|
||||
<size key="maxSize" width="1160" height="10000000"/>
|
||||
<color key="insertionPointColor" name="controlTextColor" catalog="System" colorSpace="catalog"/>
|
||||
<allowedInputSourceLocales>
|
||||
|
@ -134,7 +138,7 @@
|
|||
<autoresizingMask key="autoresizingMask"/>
|
||||
</scroller>
|
||||
<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"/>
|
||||
</scroller>
|
||||
</scrollView>
|
||||
|
@ -153,106 +157,112 @@
|
|||
<action selector="consoleInput:" target="-2" id="ylQ-vw-ARS"/>
|
||||
</connections>
|
||||
</textField>
|
||||
<box verticalHuggingPriority="750" fixedFrame="YES" boxType="separator" translatesAutoresizingMaskIntoConstraints="NO" id="xJr-K6-B4B">
|
||||
<rect key="frame" x="0.0" y="49" width="591" height="4"/>
|
||||
<customView id="sah-kv-6KJ">
|
||||
<rect key="frame" x="0.0" y="26" width="591" height="26"/>
|
||||
<autoresizingMask key="autoresizingMask" widthSizable="YES" flexibleMaxY="YES"/>
|
||||
</box>
|
||||
<box verticalHuggingPriority="750" fixedFrame="YES" boxType="separator" translatesAutoresizingMaskIntoConstraints="NO" id="9DF-fj-a2v">
|
||||
<rect key="frame" x="0.0" y="24" width="591" height="4"/>
|
||||
<autoresizingMask key="autoresizingMask" widthSizable="YES" flexibleMaxY="YES"/>
|
||||
</box>
|
||||
<button verticalHuggingPriority="750" fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="G4h-KO-Z3g" customClass="GBDebuggerButton">
|
||||
<rect key="frame" x="2" y="26" width="26" height="26"/>
|
||||
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMaxY="YES"/>
|
||||
<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">
|
||||
<behavior key="behavior" pushIn="YES" lightByBackground="YES" lightByGray="YES"/>
|
||||
<font key="font" metaFont="system"/>
|
||||
</buttonCell>
|
||||
<color key="contentTintColor" name="controlAccentColor" catalog="System" colorSpace="catalog"/>
|
||||
<connections>
|
||||
<action selector="debuggerButtonPressed:" target="-2" id="SjG-90-8dJ"/>
|
||||
<outlet property="textField" destination="l22-S8-uji" id="NZ8-eJ-Uyd"/>
|
||||
</connections>
|
||||
</button>
|
||||
<button verticalHuggingPriority="750" fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="cOi-Rs-9gS" customClass="GBDebuggerButton">
|
||||
<rect key="frame" x="28" y="26" width="26" height="26"/>
|
||||
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMaxY="YES"/>
|
||||
<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">
|
||||
<behavior key="behavior" pushIn="YES" lightByBackground="YES" lightByGray="YES"/>
|
||||
<font key="font" metaFont="system"/>
|
||||
</buttonCell>
|
||||
<connections>
|
||||
<action selector="debuggerButtonPressed:" target="-2" id="g7E-UM-SHV"/>
|
||||
<outlet property="textField" destination="l22-S8-uji" id="1uM-AA-yHi"/>
|
||||
</connections>
|
||||
</button>
|
||||
<button verticalHuggingPriority="750" fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="DsN-Ce-QoH" customClass="GBDebuggerButton">
|
||||
<rect key="frame" x="54" y="26" width="26" height="26"/>
|
||||
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMaxY="YES"/>
|
||||
<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">
|
||||
<behavior key="behavior" pushIn="YES" lightByBackground="YES" lightByGray="YES"/>
|
||||
<font key="font" metaFont="system"/>
|
||||
</buttonCell>
|
||||
<connections>
|
||||
<action selector="debuggerButtonPressed:" target="-2" id="QMw-82-HKJ"/>
|
||||
<outlet property="textField" destination="l22-S8-uji" id="qaF-TF-cwg"/>
|
||||
</connections>
|
||||
</button>
|
||||
<button verticalHuggingPriority="750" fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="vtb-n5-Qlz" customClass="GBDebuggerButton">
|
||||
<rect key="frame" x="78" y="26" width="26" height="26"/>
|
||||
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMaxY="YES"/>
|
||||
<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">
|
||||
<behavior key="behavior" pushIn="YES" lightByBackground="YES" lightByGray="YES"/>
|
||||
<font key="font" metaFont="system"/>
|
||||
</buttonCell>
|
||||
<connections>
|
||||
<action selector="debuggerButtonPressed:" target="-2" id="krr-9m-Jfz"/>
|
||||
<outlet property="textField" destination="l22-S8-uji" id="uYK-tU-BnO"/>
|
||||
</connections>
|
||||
</button>
|
||||
<button verticalHuggingPriority="750" fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="oCa-UH-1mi" customClass="GBDebuggerButton">
|
||||
<rect key="frame" x="563" y="26" width="26" height="26"/>
|
||||
<autoresizingMask key="autoresizingMask" flexibleMinX="YES" flexibleMaxY="YES"/>
|
||||
<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">
|
||||
<behavior key="behavior" pushIn="YES" lightByBackground="YES" lightByGray="YES"/>
|
||||
<font key="font" metaFont="system"/>
|
||||
</buttonCell>
|
||||
<connections>
|
||||
<action selector="debuggerButtonPressed:" target="-2" id="PwN-rf-AcB"/>
|
||||
<outlet property="textField" destination="l22-S8-uji" id="blK-B3-MWI"/>
|
||||
</connections>
|
||||
</button>
|
||||
<button verticalHuggingPriority="750" fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="onn-R8-3vg" customClass="GBDebuggerButton">
|
||||
<rect key="frame" x="102" y="26" width="26" height="26"/>
|
||||
<autoresizingMask key="autoresizingMask" flexibleMaxX="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">
|
||||
<behavior key="behavior" pushIn="YES" lightByBackground="YES" lightByGray="YES"/>
|
||||
<font key="font" metaFont="system"/>
|
||||
</buttonCell>
|
||||
<connections>
|
||||
<action selector="debuggerButtonPressed:" target="-2" id="S9a-jV-Z6g"/>
|
||||
<outlet property="textField" destination="l22-S8-uji" id="1gw-Lc-QFS"/>
|
||||
</connections>
|
||||
</button>
|
||||
<subviews>
|
||||
<button verticalHuggingPriority="750" fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="ybQ-jy-NgI" customClass="GBDebuggerButton">
|
||||
<rect key="frame" x="4" y="0.0" width="26" height="26"/>
|
||||
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMaxY="YES"/>
|
||||
<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">
|
||||
<behavior key="behavior" pushIn="YES" lightByBackground="YES" lightByGray="YES"/>
|
||||
<font key="font" metaFont="system"/>
|
||||
</buttonCell>
|
||||
<color key="contentTintColor" name="controlAccentColor" catalog="System" colorSpace="catalog"/>
|
||||
<connections>
|
||||
<action selector="debuggerButtonPressed:" target="-2" id="8pX-u8-oFG"/>
|
||||
<outlet property="textField" destination="l22-S8-uji" id="cIZ-tr-dAu"/>
|
||||
</connections>
|
||||
</button>
|
||||
<button verticalHuggingPriority="750" fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="jdD-yP-Nr6" customClass="GBDebuggerButton">
|
||||
<rect key="frame" x="80" y="0.0" width="26" height="26"/>
|
||||
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMaxY="YES"/>
|
||||
<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">
|
||||
<behavior key="behavior" pushIn="YES" lightByBackground="YES" lightByGray="YES"/>
|
||||
<font key="font" metaFont="system"/>
|
||||
</buttonCell>
|
||||
<connections>
|
||||
<action selector="debuggerButtonPressed:" target="-2" id="FXb-hO-cEh"/>
|
||||
<outlet property="textField" destination="l22-S8-uji" id="IPT-hF-MHv"/>
|
||||
</connections>
|
||||
</button>
|
||||
<button verticalHuggingPriority="750" fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="tTP-Zs-Ohu" customClass="GBDebuggerButton">
|
||||
<rect key="frame" x="30" y="0.0" width="26" height="26"/>
|
||||
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMaxY="YES"/>
|
||||
<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">
|
||||
<behavior key="behavior" pushIn="YES" lightByBackground="YES" lightByGray="YES"/>
|
||||
<font key="font" metaFont="system"/>
|
||||
</buttonCell>
|
||||
<connections>
|
||||
<action selector="debuggerButtonPressed:" target="-2" id="qL6-Mz-v2a"/>
|
||||
<outlet property="textField" destination="l22-S8-uji" id="MRn-cs-a9T"/>
|
||||
</connections>
|
||||
</button>
|
||||
<button verticalHuggingPriority="750" fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="E87-Uq-f2l" customClass="GBDebuggerButton">
|
||||
<rect key="frame" x="104" y="0.0" width="26" height="26"/>
|
||||
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMaxY="YES"/>
|
||||
<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">
|
||||
<behavior key="behavior" pushIn="YES" lightByBackground="YES" lightByGray="YES"/>
|
||||
<font key="font" metaFont="system"/>
|
||||
</buttonCell>
|
||||
<connections>
|
||||
<action selector="debuggerButtonPressed:" target="-2" id="vyO-14-k3A"/>
|
||||
<outlet property="textField" destination="l22-S8-uji" id="f5e-xA-0En"/>
|
||||
</connections>
|
||||
</button>
|
||||
<button verticalHuggingPriority="750" fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="fsQ-dD-A8C" customClass="GBDebuggerButton">
|
||||
<rect key="frame" x="56" y="0.0" width="26" height="26"/>
|
||||
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMaxY="YES"/>
|
||||
<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">
|
||||
<behavior key="behavior" pushIn="YES" lightByBackground="YES" lightByGray="YES"/>
|
||||
<font key="font" metaFont="system"/>
|
||||
</buttonCell>
|
||||
<connections>
|
||||
<action selector="debuggerButtonPressed:" target="-2" id="6DD-pu-gwc"/>
|
||||
<outlet property="textField" destination="l22-S8-uji" id="ILQ-oy-iGc"/>
|
||||
</connections>
|
||||
</button>
|
||||
<box verticalHuggingPriority="750" fixedFrame="YES" boxType="separator" translatesAutoresizingMaskIntoConstraints="NO" id="8bt-2t-EIG">
|
||||
<rect key="frame" x="-2" y="23" width="593" height="4"/>
|
||||
<autoresizingMask key="autoresizingMask" widthSizable="YES" flexibleMaxY="YES"/>
|
||||
</box>
|
||||
<box verticalHuggingPriority="750" fixedFrame="YES" boxType="separator" translatesAutoresizingMaskIntoConstraints="NO" id="eSO-2z-QHX">
|
||||
<rect key="frame" x="-2" y="-2" width="593" height="4"/>
|
||||
<autoresizingMask key="autoresizingMask" widthSizable="YES" flexibleMaxY="YES"/>
|
||||
</box>
|
||||
<button verticalHuggingPriority="750" fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="0Jt-TO-8CM" customClass="GBDebuggerButton">
|
||||
<rect key="frame" x="561" y="0.0" width="26" height="26"/>
|
||||
<autoresizingMask key="autoresizingMask" flexibleMinX="YES" flexibleMaxY="YES"/>
|
||||
<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">
|
||||
<behavior key="behavior" pushIn="YES" lightByBackground="YES" lightByGray="YES"/>
|
||||
<font key="font" metaFont="system"/>
|
||||
</buttonCell>
|
||||
<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>
|
||||
</customView>
|
||||
<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"/>
|
||||
<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">
|
||||
<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"/>
|
||||
<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"/>
|
||||
<subviews>
|
||||
<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"/>
|
||||
<color key="textColor" name="textColor" 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"/>
|
||||
<color key="insertionPointColor" name="controlTextColor" catalog="System" colorSpace="catalog"/>
|
||||
<allowedInputSourceLocales>
|
||||
|
@ -266,27 +276,27 @@
|
|||
<autoresizingMask key="autoresizingMask"/>
|
||||
</scroller>
|
||||
<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"/>
|
||||
</scroller>
|
||||
</scrollView>
|
||||
<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"/>
|
||||
</box>
|
||||
<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"/>
|
||||
<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"/>
|
||||
<subviews>
|
||||
<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"/>
|
||||
<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"/>
|
||||
<size key="minSize" width="329" height="354"/>
|
||||
<size key="minSize" width="329" height="339"/>
|
||||
<size key="maxSize" width="1160" height="10000000"/>
|
||||
<color key="insertionPointColor" name="controlTextColor" catalog="System" colorSpace="catalog"/>
|
||||
<allowedInputSourceLocales>
|
||||
|
@ -301,10 +311,38 @@
|
|||
<autoresizingMask key="autoresizingMask"/>
|
||||
</scroller>
|
||||
<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"/>
|
||||
</scroller>
|
||||
</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>
|
||||
</customView>
|
||||
</subviews>
|
||||
|
@ -318,9 +356,12 @@
|
|||
</splitView>
|
||||
</subviews>
|
||||
</view>
|
||||
<connections>
|
||||
<outlet property="ownerWindow" destination="xOd-HO-29H" id="beo-JZ-Ekb"/>
|
||||
</connections>
|
||||
<point key="canvasLocation" x="347.5" y="-29"/>
|
||||
</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"/>
|
||||
<windowCollectionBehavior key="collectionBehavior" fullScreenAuxiliary="YES"/>
|
||||
<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"/>
|
||||
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
|
||||
</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>
|
||||
<toolbarItem implicitItemIdentifier="NSToolbarSpaceItem" id="WUk-8p-S6B"/>
|
||||
<toolbarItem implicitItemIdentifier="NSToolbarFlexibleSpaceItem" id="E3z-um-6KG"/>
|
||||
<toolbarItem implicitItemIdentifier="4F6AAE25-1E9D-4111-9E5B-91F0792E56CD" label="Address Space" paletteLabel="Address Space" id="VTy-lj-K0H">
|
||||
<nil key="toolTip"/>
|
||||
<size key="minSize" width="100" height="25"/>
|
||||
<size key="maxSize" width="130" height="25"/>
|
||||
<size key="minSize" width="160" height="25"/>
|
||||
<size key="maxSize" width="160" height="25"/>
|
||||
<popUpButton key="view" verticalHuggingPriority="750" id="vfJ-vu-gqJ">
|
||||
<rect key="frame" x="0.0" y="14" width="128" height="25"/>
|
||||
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMinY="YES"/>
|
||||
<popUpButtonCell key="cell" type="roundTextured" bezelStyle="texturedRounded" alignment="left" lineBreakMode="truncatingTail" borderStyle="border" imageScaling="proportionallyDown" inset="2" id="bpD-j9-omo">
|
||||
<rect key="frame" x="0.0" y="14" width="160" height="25"/>
|
||||
<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" customClass="GBToolbarPopUpButtonCell">
|
||||
<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">
|
||||
<items>
|
||||
<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">
|
||||
<nil key="toolTip"/>
|
||||
<size key="minSize" width="64" height="22"/>
|
||||
<size key="maxSize" width="64" height="22"/>
|
||||
<textField key="view" verticalHuggingPriority="750" id="rdV-q6-hc6">
|
||||
<size key="maxSize" width="80" height="22"/>
|
||||
<textField key="view" focusRingType="none" verticalHuggingPriority="750" id="rdV-q6-hc6">
|
||||
<rect key="frame" x="0.0" y="14" width="64" height="22"/>
|
||||
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMinY="YES"/>
|
||||
<textFieldCell key="cell" scrollable="YES" lineBreakMode="clipping" selectable="YES" editable="YES" sendsActionOnEndEditing="YES" state="on" borderStyle="bezel" id="JCn-Y1-eHS">
|
||||
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
|
||||
<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"/>
|
||||
<color key="textColor" name="controlTextColor" catalog="System" colorSpace="catalog"/>
|
||||
<color key="backgroundColor" name="textBackgroundColor" catalog="System" colorSpace="catalog"/>
|
||||
</textFieldCell>
|
||||
<connections>
|
||||
<action selector="hexUpdateBank:" target="-2" id="Mx9-WI-wgO"/>
|
||||
</connections>
|
||||
</textField>
|
||||
</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"/>
|
||||
<size key="minSize" width="96" height="22"/>
|
||||
<size key="maxSize" width="128" height="22"/>
|
||||
<textField key="view" verticalHuggingPriority="750" id="EJd-jG-hmH">
|
||||
<rect key="frame" x="0.0" y="14" width="96" height="22"/>
|
||||
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMinY="YES"/>
|
||||
<textFieldCell key="cell" scrollable="YES" lineBreakMode="clipping" selectable="YES" editable="YES" state="on" borderStyle="bezel" bezelStyle="round" id="vg5-Nn-abb">
|
||||
<size key="minSize" width="160" height="22"/>
|
||||
<size key="maxSize" width="160" height="22"/>
|
||||
<textField key="view" focusRingType="none" verticalHuggingPriority="750" id="EJd-jG-hmH">
|
||||
<rect key="frame" x="0.0" y="14" width="160" height="22"/>
|
||||
<autoresizingMask key="autoresizingMask" widthSizable="YES"/>
|
||||
<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"/>
|
||||
<color key="textColor" name="controlTextColor" catalog="System" colorSpace="catalog"/>
|
||||
<color key="backgroundColor" name="textBackgroundColor" catalog="System" colorSpace="catalog"/>
|
||||
</textFieldCell>
|
||||
<connections>
|
||||
<action selector="hexGoTo:" target="-2" id="7WG-8C-SK8"/>
|
||||
|
@ -400,15 +439,18 @@
|
|||
<toolbarItem reference="rLO-D7-zRG"/>
|
||||
</defaultToolbarItems>
|
||||
</toolbar>
|
||||
<connections>
|
||||
<outlet property="ownerWindow" destination="xOd-HO-29H" id="wCE-dT-kGv"/>
|
||||
</connections>
|
||||
<point key="canvasLocation" x="-185" y="61"/>
|
||||
</window>
|
||||
<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"/>
|
||||
<windowCollectionBehavior key="collectionBehavior" fullScreenAuxiliary="YES"/>
|
||||
<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"/>
|
||||
<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"/>
|
||||
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
|
||||
<subviews>
|
||||
|
@ -416,7 +458,7 @@
|
|||
<rect key="frame" x="0.0" y="406" width="512" height="5"/>
|
||||
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMinY="YES"/>
|
||||
</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"/>
|
||||
<autoresizingMask key="autoresizingMask" widthSizable="YES" flexibleMaxY="YES"/>
|
||||
<textFieldCell key="cell" controlSize="small" scrollable="YES" lineBreakMode="clipping" sendsActionOnEndEditing="YES" alignment="center" id="umk-4r-VNg">
|
||||
|
@ -549,7 +591,7 @@
|
|||
</connections>
|
||||
</popUpButton>
|
||||
<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"/>
|
||||
<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"/>
|
||||
|
@ -567,7 +609,7 @@
|
|||
</connections>
|
||||
</popUpButton>
|
||||
<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"/>
|
||||
<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"/>
|
||||
|
@ -635,21 +677,19 @@
|
|||
</tabView>
|
||||
</subviews>
|
||||
</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>
|
||||
<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"/>
|
||||
<size key="minSize" width="100" height="25"/>
|
||||
<size key="maxSize" width="268" height="25"/>
|
||||
<segmentedControl key="view" verticalHuggingPriority="750" id="Aul-vO-dCK">
|
||||
<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">
|
||||
<font key="font" metaFont="system"/>
|
||||
<segments>
|
||||
<segment label="Tileset" selected="YES"/>
|
||||
<segment label="Tilemap" tag="1"/>
|
||||
<segment label="Tilemap"/>
|
||||
<segment label="Objects"/>
|
||||
<segment label="Palettes"/>
|
||||
</segments>
|
||||
|
@ -667,9 +707,12 @@
|
|||
</defaultToolbarItems>
|
||||
</toolbar>
|
||||
<contentBorderThickness minY="24"/>
|
||||
<connections>
|
||||
<outlet property="ownerWindow" destination="xOd-HO-29H" id="hkb-AH-4fo"/>
|
||||
</connections>
|
||||
<point key="canvasLocation" x="182" y="760"/>
|
||||
</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"/>
|
||||
<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"/>
|
||||
|
@ -685,7 +728,7 @@
|
|||
</imageView>
|
||||
</subviews>
|
||||
</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>
|
||||
<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"/>
|
||||
|
@ -717,168 +760,30 @@
|
|||
<toolbarItem reference="L6N-6G-UWl"/>
|
||||
</defaultToolbarItems>
|
||||
</toolbar>
|
||||
<connections>
|
||||
<outlet property="ownerWindow" destination="xOd-HO-29H" id="8Lk-t1-HNi"/>
|
||||
</connections>
|
||||
<point key="canvasLocation" x="-159" y="356"/>
|
||||
</window>
|
||||
<window title="Cheats" allowsToolTipsWhenApplicationIsInactive="NO" autorecalculatesKeyViewLoop="NO" restorable="NO" releasedWhenClosed="NO" visibleAtLaunch="NO" frameAutosaveName="" animationBehavior="default" id="4Yb-Np-JrF" customClass="NSPanel">
|
||||
<windowStyleMask key="styleMask" titled="YES" closable="YES"/>
|
||||
<rect key="contentRect" x="0.0" y="0.0" width="692" height="272"/>
|
||||
<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" miniaturizable="YES" resizable="YES"/>
|
||||
<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"/>
|
||||
<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">
|
||||
<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"/>
|
||||
<subviews>
|
||||
<view id="fWr-0i-K1d" customClass="GBOptionalVisualEffectView">
|
||||
<rect key="frame" x="0.0" y="0.0" width="294" height="272"/>
|
||||
<autoresizingMask key="autoresizingMask" flexibleMaxX="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"/>
|
||||
<scrollView autohidesScrollers="YES" horizontalLineScroll="26" horizontalPageScroll="10" verticalLineScroll="26" verticalPageScroll="10" usesPredominantAxisScrolling="NO" id="6rU-Xg-KHc">
|
||||
<rect key="frame" x="-1" y="143" width="606" height="259"/>
|
||||
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
|
||||
<clipView key="contentView" id="mzf-yu-RID">
|
||||
<rect key="frame" x="1" y="1" width="398" height="273"/>
|
||||
<autoresizingMask key="autoresizingMask"/>
|
||||
<rect key="frame" x="1" y="1" width="604" height="257"/>
|
||||
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
|
||||
<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">
|
||||
<rect key="frame" x="0.0" y="0.0" width="398" height="256"/>
|
||||
<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="604" height="240"/>
|
||||
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
|
||||
<size key="intercellSpacing" width="3" height="2"/>
|
||||
<color key="backgroundColor" name="controlBackgroundColor" catalog="System" colorSpace="catalog"/>
|
||||
|
@ -889,13 +794,13 @@
|
|||
<color key="textColor" name="headerTextColor" catalog="System" colorSpace="catalog"/>
|
||||
<color key="backgroundColor" name="headerColor" catalog="System" colorSpace="catalog"/>
|
||||
</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"/>
|
||||
<font key="font" metaFont="system"/>
|
||||
</buttonCell>
|
||||
<tableColumnResizingMask key="resizingMask" resizeWithTable="YES" userResizable="YES"/>
|
||||
</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">
|
||||
<color key="textColor" name="headerTextColor" catalog="System" colorSpace="catalog"/>
|
||||
<color key="backgroundColor" name="headerColor" catalog="System" colorSpace="catalog"/>
|
||||
|
@ -906,24 +811,24 @@
|
|||
</buttonCell>
|
||||
<tableColumnResizingMask key="resizingMask" resizeWithTable="YES" userResizable="YES"/>
|
||||
</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">
|
||||
<color key="textColor" name="headerTextColor" catalog="System" colorSpace="catalog"/>
|
||||
<color key="backgroundColor" name="headerColor" catalog="System" colorSpace="catalog"/>
|
||||
</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"/>
|
||||
<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 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">
|
||||
<color key="textColor" name="headerTextColor" catalog="System" colorSpace="catalog"/>
|
||||
<color key="backgroundColor" name="headerColor" catalog="System" colorSpace="catalog"/>
|
||||
</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"/>
|
||||
<color key="textColor" name="controlTextColor" catalog="System" colorSpace="catalog"/>
|
||||
<color key="backgroundColor" name="controlBackgroundColor" catalog="System" colorSpace="catalog"/>
|
||||
|
@ -939,7 +844,7 @@
|
|||
</subviews>
|
||||
</clipView>
|
||||
<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"/>
|
||||
</scroller>
|
||||
<scroller key="verticalScroller" hidden="YES" wantsLayer="YES" verticalHuggingPriority="750" doubleValue="1" horizontal="NO" id="zET-KH-qF4">
|
||||
|
@ -947,13 +852,159 @@
|
|||
<autoresizingMask key="autoresizingMask"/>
|
||||
</scroller>
|
||||
<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"/>
|
||||
</tableHeaderView>
|
||||
</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>
|
||||
</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>
|
||||
<customObject id="v7q-gT-jHT" customClass="GBCheatWindowController">
|
||||
<connections>
|
||||
|
@ -975,7 +1026,7 @@
|
|||
<image name="HelpTemplate" width="14" height="14"/>
|
||||
<image name="InterruptTemplate" width="14" height="14"/>
|
||||
<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="StepTemplate" width="14" height="14"/>
|
||||
<image name="printer" catalog="system" width="18" height="16"/>
|
||||
|
|
|
@ -22,5 +22,6 @@
|
|||
@property (strong) IBOutlet NSButton *updateProgressButton;
|
||||
@property (strong) IBOutlet NSWindow *updateProgressWindow;
|
||||
@property (strong) IBOutlet NSProgressIndicator *updateProgressSpinner;
|
||||
- (void)updateThemesDefault:(bool)overwrite;
|
||||
@end
|
||||
|
||||
|
|
159
Cocoa/GBApp.m
|
@ -8,9 +8,15 @@
|
|||
#import <JoyKit/JoyKit.h>
|
||||
#import <WebKit/WebKit.h>
|
||||
#import <mach-o/dyld.h>
|
||||
#include <sys/mount.h>
|
||||
#include <sys/xattr.h>
|
||||
|
||||
#define UPDATE_SERVER "https://sameboy.github.io"
|
||||
|
||||
@interface NSToolbarItem(private)
|
||||
- (NSButton *)_view;
|
||||
@end
|
||||
|
||||
static uint32_t color_to_int(NSColor *color)
|
||||
{
|
||||
color = [color colorUsingColorSpace:[NSColorSpace deviceRGBColorSpace]];
|
||||
|
@ -40,14 +46,26 @@ static uint32_t color_to_int(NSColor *color)
|
|||
- (void) applicationDidFinishLaunching:(NSNotification *)notification
|
||||
{
|
||||
// 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];
|
||||
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]]) {
|
||||
[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:@{
|
||||
@"GBRight": @(kVK_RightArrow),
|
||||
@"GBLeft": @(kVK_LeftArrow),
|
||||
|
@ -83,8 +101,24 @@ static uint32_t color_to_int(NSColor *color)
|
|||
@"GBJoyConAutoPair": @YES,
|
||||
@"GBJoyConsDefaultsToHorizontal": @YES,
|
||||
|
||||
@"GBEmulatedModel": @(MODEL_AUTO),
|
||||
|
||||
@"GBDebuggerFont": hasSFMono? @"SF Mono" : @"Menlo",
|
||||
@"GBDebuggerFontSize": @12,
|
||||
|
||||
@"GBColorPalette": @1,
|
||||
@"GBTurboCap": @0,
|
||||
|
||||
// Default themes
|
||||
@"GBThemes": @{
|
||||
@"Canyon": @{
|
||||
@"BrightnessBias": @0.1227009965823247,
|
||||
@"Colors": @[@0xff0c1e20, @0xff122b91, @0xff466aa2, @0xfff1efae, @0xfff1efae],
|
||||
@"DisabledLCDColor": @NO,
|
||||
@"HueBias": @0.01782661816105247,
|
||||
@"HueBiasStrength": @1,
|
||||
@"Manual": @NO,
|
||||
},
|
||||
@"Desert": @{
|
||||
@"BrightnessBias": @0.0,
|
||||
@"Colors": @[@0xff302f3e, @0xff576674, @0xff839ba4, @0xffb1d0d2, @0xffb7d7d8],
|
||||
|
@ -109,6 +143,30 @@ static uint32_t color_to_int(NSColor *color)
|
|||
@"HueBiasStrength": @0.18424738545816732,
|
||||
@"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": @{
|
||||
@"BrightnessBias": @0.0,
|
||||
@"Colors": @[@0xff3c2136, @0xff942e84, @0xffc7699d, @0xfff1e4b0, @0xfff6f9b2],
|
||||
|
@ -117,6 +175,22 @@ static uint32_t color_to_int(NSColor *color)
|
|||
@"HueBiasStrength": @0.65018052788844627,
|
||||
@"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": @{
|
||||
@"BrightnessBias": @-0.48079556772908372,
|
||||
@"Colors": @[@0xff215200, @0xff1f7306, @0xff169e34, @0xff03ceb8, @0xff00d4d1],
|
||||
|
@ -125,6 +199,14 @@ static uint32_t color_to_int(NSColor *color)
|
|||
@"HueBiasStrength": @0.34337649402390436,
|
||||
@"Manual": @NO,
|
||||
},
|
||||
@"Rose": @{
|
||||
@"BrightnessBias": @0.2727272808551788,
|
||||
@"Colors": @[@0xff001500, @0xff4e1fae, @0xff865ac4, @0xffb7e6d3, @0xffbdffd4],
|
||||
@"DisabledLCDColor": @YES,
|
||||
@"HueBias": @0.9238900924101472,
|
||||
@"HueBiasStrength": @0.9957716464996338,
|
||||
@"Manual": @NO,
|
||||
},
|
||||
@"Seaweed": @{
|
||||
@"BrightnessBias": @-0.28532744023904377,
|
||||
@"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"]) {
|
||||
[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
|
||||
|
@ -216,7 +323,10 @@ static uint32_t color_to_int(NSColor *color)
|
|||
[item.image setSize:NSMakeSize(16, 16)];
|
||||
[items addObject:item];
|
||||
}
|
||||
menu.itemArray = items;
|
||||
[menu removeAllItems];
|
||||
for (NSMenuItem *item in items) {
|
||||
[menu addItem:item];
|
||||
}
|
||||
}
|
||||
|
||||
- (IBAction) showPreferences: (id) sender
|
||||
|
@ -232,9 +342,8 @@ static uint32_t color_to_int(NSColor *color)
|
|||
#ifndef UPDATE_SUPPORT
|
||||
[_preferencesWindow.toolbar removeItemAtIndex:4];
|
||||
#endif
|
||||
if (@available(macOS 11.0, *)) {
|
||||
[_preferencesWindow.toolbar insertItemWithItemIdentifier:NSToolbarFlexibleSpaceItemIdentifier atIndex:0];
|
||||
[_preferencesWindow.toolbar insertItemWithItemIdentifier:NSToolbarFlexibleSpaceItemIdentifier atIndex:_preferencesWindow.toolbar.items.count];
|
||||
for (unsigned i = _preferencesWindow.toolbar.items.count; i--;) {
|
||||
[_preferencesWindow.toolbar.items[i] _view].imageScaling = NSImageScaleNone;
|
||||
}
|
||||
}
|
||||
[_preferencesWindow makeKeyAndOrderFront:self];
|
||||
|
@ -294,7 +403,12 @@ static uint32_t color_to_int(NSColor *color)
|
|||
else {
|
||||
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.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: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;
|
||||
atexit_b(^{
|
||||
execl(executablePath.UTF8String, executablePath.UTF8String, "--update-launch", NULL);
|
||||
|
@ -669,4 +791,27 @@ static uint32_t color_to_int(NSColor *color)
|
|||
- (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
|
||||
|
|
|
@ -7,20 +7,24 @@ typedef enum {
|
|||
GBB,
|
||||
GBSelect,
|
||||
GBStart,
|
||||
GBRapidA,
|
||||
GBRapidB,
|
||||
GBTurbo,
|
||||
GBRewind,
|
||||
GBUnderclock,
|
||||
GBHotkey1,
|
||||
GBHotkey2,
|
||||
GBJoypadButtonCount,
|
||||
GBButtonCount = GBUnderclock + 1,
|
||||
GBGameBoyButtonCount = GBStart + 1,
|
||||
GBTotalButtonCount,
|
||||
GBKeyboardButtonCount = GBUnderclock + 1,
|
||||
GBPerPlayerButtonCount = GBRapidB + 1,
|
||||
} GBButton;
|
||||
|
||||
#define GBJoyKitHotkey1 JOYButtonUsageGeneric0 + 0x100
|
||||
#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)
|
||||
{
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
#import <Foundation/Foundation.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 {
|
||||
dispatch_async(dispatch_get_main_queue(), ^{
|
||||
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) {
|
||||
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
|
||||
{
|
||||
[super drawKnob:knobRect];
|
||||
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;
|
||||
NSBezierPath *path = nil;
|
||||
if (@available(macos 26.0, *)) {
|
||||
NSRect peekRect = knobRect;
|
||||
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;
|
||||
if (!self.enabled) {
|
||||
color = [color colorWithAlphaComponent:0.5];
|
||||
}
|
||||
[color setFill];
|
||||
NSBezierPath *path = [NSBezierPath bezierPathWithOvalInRect:peekRect];
|
||||
[path fill];
|
||||
[[NSColor colorWithWhite:0 alpha:0.25] setStroke];
|
||||
[path setLineWidth:0.5];
|
||||
|
|
|
@ -44,7 +44,8 @@
|
|||
}
|
||||
|
||||
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 y = 0; y < 2; y++) {
|
||||
NSRect rect = parent.scrollRect;
|
||||
|
|
|
@ -16,7 +16,7 @@
|
|||
static GBJoyConManager *manager = nil;
|
||||
static dispatch_once_t onceToken;
|
||||
dispatch_once(&onceToken, ^{
|
||||
manager = [[self alloc] _init];
|
||||
manager = [[super allocWithZone:nil] _init];
|
||||
});
|
||||
return manager;
|
||||
}
|
||||
|
@ -32,6 +32,16 @@
|
|||
return ret;
|
||||
}
|
||||
|
||||
+ (instancetype)allocWithZone:(struct _NSZone *)zone
|
||||
{
|
||||
return [self sharedInstance];
|
||||
}
|
||||
|
||||
+ (instancetype)alloc
|
||||
{
|
||||
return [self sharedInstance];
|
||||
}
|
||||
|
||||
- (instancetype)init
|
||||
{
|
||||
return [self.class sharedInstance];
|
||||
|
|
|
@ -57,6 +57,9 @@
|
|||
uint8_t length = document.oamCount;
|
||||
bool cgb = GB_is_cgb(document.gb);
|
||||
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++) {
|
||||
GBObjectViewItem *item = _items[i];
|
||||
if (i >= length) {
|
||||
|
@ -64,6 +67,13 @@
|
|||
}
|
||||
else {
|
||||
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.position.stringValue = [NSString stringWithFormat:@"(%d, %d)",
|
||||
((signed)(unsigned)info[i].x) - 8,
|
||||
|
|
|
@ -1,8 +1,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>
|
||||
<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"/>
|
||||
</dependencies>
|
||||
<objects>
|
||||
|
|
|
@ -29,11 +29,12 @@
|
|||
- (instancetype)initWithFrame:(NSRect)frameRect pixelFormat:(NSOpenGLPixelFormat *)format
|
||||
{
|
||||
__unsafe_unretained GBOpenGLView *weakSelf = self;
|
||||
self = [super initWithFrame:frameRect pixelFormat:format];
|
||||
[self observeStandardDefaultsKey:@"GBFilter" withBlock:^(id newValue) {
|
||||
weakSelf.shader = nil;
|
||||
[weakSelf setNeedsDisplay:true];
|
||||
|
||||
}];
|
||||
return [super initWithFrame:frameRect pixelFormat:format];
|
||||
return self;
|
||||
}
|
||||
@end
|
||||
|
|
|
@ -14,5 +14,7 @@
|
|||
@property (weak) IBOutlet NSSlider *hueStrengthSlider;
|
||||
@property (weak) IBOutlet NSTableView *themesList;
|
||||
@property (weak) IBOutlet NSMenu *menu;
|
||||
@property (weak) IBOutlet NSSegmentedControl *segmentControl;
|
||||
@property IBOutlet NSMenu *segmentMenu;
|
||||
+ (const GB_palette_t *)userPalette;
|
||||
@end
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
#import "GBPaletteEditorController.h"
|
||||
#import "GBHueSliderCell.h"
|
||||
#import "GBApp.h"
|
||||
#import <Core/gb.h>
|
||||
|
||||
#define MAGIC 'SBPL'
|
||||
|
@ -199,11 +200,17 @@ static double blend(double from, double to, double position)
|
|||
if (theme && themes[theme]) {
|
||||
unsigned index = [[themes.allKeys sortedArrayUsingSelector:@selector(localizedCaseInsensitiveCompare:)] indexOfObject:theme];
|
||||
[_themesList selectRowIndexes:[NSIndexSet indexSetWithIndex:index] byExtendingSelection:false];
|
||||
[_themesList scrollRowToVisible:index];
|
||||
}
|
||||
else {
|
||||
[_themesList selectRowIndexes:[NSIndexSet indexSetWithIndex:0] byExtendingSelection:false];
|
||||
[_themesList scrollRowToVisible:0];
|
||||
}
|
||||
[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
|
||||
|
@ -360,19 +367,48 @@ static double blend(double from, double to, double position)
|
|||
}
|
||||
[defaults setObject:newName forKey:@"GBCurrentTheme"];
|
||||
[self savePalette:sender];
|
||||
[self.themesList reloadData];
|
||||
[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
|
||||
{
|
||||
[sender.window.sheetParent endSheet:sender.window];
|
||||
}
|
||||
|
||||
- (instancetype)init
|
||||
+ (instancetype)alloc
|
||||
{
|
||||
static id singleton = nil;
|
||||
if (singleton) return singleton;
|
||||
return (singleton = [super init]);
|
||||
return (singleton = [super allocWithZone:nil]);
|
||||
}
|
||||
|
||||
+ (instancetype)allocWithZone:(struct _NSZone *)zone
|
||||
{
|
||||
return [self alloc];
|
||||
}
|
||||
|
||||
@end
|
||||
|
|
|
@ -43,6 +43,7 @@
|
|||
GB_gameboy_t *gb = document.gb;
|
||||
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);
|
||||
NSFont *font = [document debuggerFontOfSize:13];
|
||||
|
||||
for (unsigned i = 0; i < 4 * 8 * 2; i++) {
|
||||
uint8_t index = i % (4 * 8);
|
||||
|
@ -58,6 +59,7 @@
|
|||
field.stringValue = [NSString stringWithFormat:@"$%04X", color];
|
||||
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.font = font;
|
||||
field.backgroundColor = [NSColor colorWithRed:(nativeColor & 0xFF) / 255.0
|
||||
green:((nativeColor >> 8) & 0xFF) / 255.0
|
||||
blue:((nativeColor >> 16) & 0xFF) / 255.0
|
||||
|
|
|
@ -1,8 +1,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>
|
||||
<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"/>
|
||||
</dependencies>
|
||||
<objects>
|
||||
|
@ -22,44 +22,44 @@
|
|||
<rect key="frame" x="0.0" y="0.0" width="512" height="24"/>
|
||||
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMinY="YES"/>
|
||||
<subviews>
|
||||
<textField verticalHuggingPriority="750" fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="ypt-t4-Mf3">
|
||||
<rect key="frame" x="131" y="0.0" width="96" height="24"/>
|
||||
<textField focusRingType="none" verticalHuggingPriority="750" fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="ypt-t4-Mf3">
|
||||
<rect key="frame" x="131" y="0.0" width="95" height="24"/>
|
||||
<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"/>
|
||||
<color key="textColor" white="0.0" alpha="1" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/>
|
||||
<color key="backgroundColor" white="1" alpha="1" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/>
|
||||
</textFieldCell>
|
||||
</textField>
|
||||
<textField verticalHuggingPriority="750" fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="KkX-Z8-Sqi">
|
||||
<rect key="frame" x="226" y="0.0" width="96" height="24"/>
|
||||
<textField focusRingType="none" verticalHuggingPriority="750" fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="KkX-Z8-Sqi">
|
||||
<rect key="frame" x="226" y="0.0" width="95" height="24"/>
|
||||
<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"/>
|
||||
<color key="textColor" white="0.0" alpha="1" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/>
|
||||
<color key="backgroundColor" white="1" alpha="1" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/>
|
||||
</textFieldCell>
|
||||
</textField>
|
||||
<textField verticalHuggingPriority="750" fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="jDk-Ej-4yI">
|
||||
<rect key="frame" x="321" y="0.0" width="96" height="24"/>
|
||||
<textField focusRingType="none" verticalHuggingPriority="750" fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="jDk-Ej-4yI">
|
||||
<rect key="frame" x="321" y="0.0" width="95" height="24"/>
|
||||
<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"/>
|
||||
<color key="textColor" white="0.0" alpha="1" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/>
|
||||
<color key="backgroundColor" white="1" alpha="1" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/>
|
||||
</textFieldCell>
|
||||
</textField>
|
||||
<textField verticalHuggingPriority="750" fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="7PI-YE-fTk">
|
||||
<rect key="frame" x="416" y="0.0" width="96" height="24"/>
|
||||
<textField focusRingType="none" verticalHuggingPriority="750" fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="7PI-YE-fTk">
|
||||
<rect key="frame" x="416" y="0.0" width="95" height="24"/>
|
||||
<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"/>
|
||||
<color key="textColor" white="0.0" alpha="1" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/>
|
||||
<color key="backgroundColor" white="1" alpha="1" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/>
|
||||
</textFieldCell>
|
||||
</textField>
|
||||
<textField horizontalHuggingPriority="251" verticalHuggingPriority="750" fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="NOK-yI-LKh">
|
||||
<rect key="frame" x="4" y="0.0" width="121" height="20"/>
|
||||
<textField focusRingType="none" horizontalHuggingPriority="251" verticalHuggingPriority="750" fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="NOK-yI-LKh">
|
||||
<rect key="frame" x="8" y="0.0" width="121" height="20"/>
|
||||
<autoresizingMask key="autoresizingMask"/>
|
||||
<textFieldCell key="cell" lineBreakMode="clipping" title="Background 0" id="qM4-cY-SDE">
|
||||
<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 <JoyKit/JoyKit.h>
|
||||
#import "GBPaletteEditorController.h"
|
||||
#import "GBTitledPopUpButton.h"
|
||||
|
||||
@interface GBPreferencesWindow : NSWindow <NSTableViewDelegate, NSTableViewDataSource, JOYListener>
|
||||
@property IBOutlet NSTableView *controlsTableView;
|
||||
|
@ -18,4 +19,10 @@
|
|||
@property IBOutlet NSPopUpButton *colorPalettePopupButton;
|
||||
@property IBOutlet NSPopUpButton *hotkey1PopupButton;
|
||||
@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
|
||||
|
|
|
@ -20,7 +20,7 @@
|
|||
|
||||
- (NSWindowToolbarStyle)toolbarStyle
|
||||
{
|
||||
return NSWindowToolbarStyleExpanded;
|
||||
return NSWindowToolbarStylePreference;
|
||||
}
|
||||
|
||||
- (void)close
|
||||
|
@ -40,16 +40,16 @@ static inline NSString *keyEquivalentString(NSMenuItem *item)
|
|||
- (NSInteger)numberOfRowsInTableView:(NSTableView *)tableView
|
||||
{
|
||||
if (self.playerListButton.selectedTag == 0) {
|
||||
return GBButtonCount;
|
||||
return GBKeyboardButtonCount;
|
||||
}
|
||||
return GBGameBoyButtonCount;
|
||||
return GBPerPlayerButtonCount;
|
||||
}
|
||||
|
||||
- (unsigned) usesForKey:(unsigned) key
|
||||
{
|
||||
unsigned ret = 0;
|
||||
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)];
|
||||
if (other && [other unsignedIntValue] == key) {
|
||||
ret++;
|
||||
|
@ -205,7 +205,7 @@ static inline NSString *keyEquivalentString(NSMenuItem *item)
|
|||
if (joystick_configuration_state == GBUnderclock) {
|
||||
[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]]];
|
||||
}
|
||||
else {
|
||||
|
@ -227,7 +227,7 @@ static inline NSString *keyEquivalentString(NSMenuItem *item)
|
|||
|
||||
if (!button.isPressed) return;
|
||||
if (joystick_configuration_state == -1) return;
|
||||
if (joystick_configuration_state == GBJoypadButtonCount) return;
|
||||
if (joystick_configuration_state == GBTotalButtonCount) return;
|
||||
if (!joystick_being_configured) {
|
||||
joystick_being_configured = controller.uniqueID;
|
||||
}
|
||||
|
@ -266,6 +266,8 @@ static inline NSString *keyEquivalentString(NSMenuItem *item)
|
|||
[GBB] = JOYButtonUsageB,
|
||||
[GBSelect] = JOYButtonUsageSelect,
|
||||
[GBStart] = JOYButtonUsageStart,
|
||||
[GBRapidA] = GBJoyKitRapidA,
|
||||
[GBRapidB] = GBJoyKitRapidB,
|
||||
[GBTurbo] = JOYButtonUsageL1,
|
||||
[GBRewind] = JOYButtonUsageL2,
|
||||
[GBUnderclock] = JOYButtonUsageR1,
|
||||
|
@ -337,6 +339,70 @@ static inline NSString *keyEquivalentString(NSMenuItem *item)
|
|||
else {
|
||||
[_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
|
||||
|
@ -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_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_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.",
|
||||
}) [self.colorCorrectionPopupButton.selectedItem.tag]
|
||||
title:self.colorCorrectionPopupButton.selectedItem.title
|
||||
|
@ -496,4 +562,35 @@ static inline NSString *keyEquivalentString(NSMenuItem *item)
|
|||
[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
|
||||
|
|
|
@ -1,8 +1,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>
|
||||
<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"/>
|
||||
</dependencies>
|
||||
<objects>
|
||||
|
@ -25,7 +25,7 @@
|
|||
<rect key="frame" x="0.0" y="0.0" width="332" height="221"/>
|
||||
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMinY="YES"/>
|
||||
<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"/>
|
||||
<autoresizingMask key="autoresizingMask" flexibleMinY="YES"/>
|
||||
<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"/>
|
||||
</textFieldCell>
|
||||
</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"/>
|
||||
<autoresizingMask key="autoresizingMask" flexibleMinY="YES"/>
|
||||
<textFieldCell key="cell" lineBreakMode="clipping" alignment="center" title="Author" id="IgT-r1-T38">
|
||||
|
@ -59,7 +59,7 @@
|
|||
<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">
|
||||
<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"/>
|
||||
</popUpButtonCell>
|
||||
<connections>
|
||||
|
@ -67,7 +67,7 @@
|
|||
</connections>
|
||||
</popUpButton>
|
||||
<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"/>
|
||||
<segmentedCell key="cell" borderStyle="border" alignment="left" style="rounded" trackingMode="momentary" id="cmq-I8-cFL">
|
||||
<font key="font" metaFont="system"/>
|
||||
|
@ -94,7 +94,7 @@
|
|||
</customView>
|
||||
</subviews>
|
||||
</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"/>
|
||||
<autoresizingMask key="autoresizingMask" flexibleMinY="YES"/>
|
||||
<textFieldCell key="cell" controlSize="small" lineBreakMode="clipping" alignment="center" title="Copyright" id="nM9-oF-OV9">
|
||||
|
|
|
@ -11,23 +11,23 @@
|
|||
|
||||
@implementation GBTerminalTextFieldCell
|
||||
{
|
||||
GBTerminalTextView *field_editor;
|
||||
GBTerminalTextView *_fieldEditor;
|
||||
}
|
||||
|
||||
- (NSTextView *)fieldEditorForView:(NSTextField *)controlView
|
||||
{
|
||||
if (field_editor) {
|
||||
field_editor.gb = self.gb;
|
||||
return field_editor;
|
||||
if (_fieldEditor) {
|
||||
_fieldEditor.gb = self.gb;
|
||||
return _fieldEditor;
|
||||
}
|
||||
field_editor = [[GBTerminalTextView alloc] init];
|
||||
[field_editor setFieldEditor:true];
|
||||
field_editor.gb = self.gb;
|
||||
field_editor->_field = (NSTextField *)controlView;
|
||||
_fieldEditor = [[GBTerminalTextView alloc] init];
|
||||
[_fieldEditor setFieldEditor:true];
|
||||
_fieldEditor.gb = self.gb;
|
||||
_fieldEditor->_field = (NSTextField *)controlView;
|
||||
((NSTextFieldCell *)controlView.cell).textInset =
|
||||
field_editor.textContainerInset =
|
||||
NSMakeSize(0, 2);
|
||||
return field_editor;
|
||||
_fieldEditor.textContainerInset =
|
||||
NSMakeSize(7, 2);
|
||||
return _fieldEditor;
|
||||
}
|
||||
|
||||
@end
|
||||
|
@ -45,7 +45,7 @@
|
|||
{
|
||||
self = [super init];
|
||||
if (!self) {
|
||||
return NULL;
|
||||
return nil;
|
||||
}
|
||||
lines = [[NSMutableOrderedSet alloc] init];
|
||||
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;
|
||||
NSMutableDictionary<NSNumber *, JOYController *> *_controllerMapping;
|
||||
unsigned _lastPlayerCount;
|
||||
|
||||
bool _rapidA[4], _rapidB[4];
|
||||
uint8_t _rapidACount[4], _rapidBCount[4];
|
||||
}
|
||||
|
||||
+ (instancetype)alloc
|
||||
|
@ -145,6 +148,9 @@ static const uint8_t workboy_vk_to_key[] = {
|
|||
[self observeStandardDefaultsKey:@"GBAspectRatioUnkept" withBlock:^(id newValue) {
|
||||
[weakSelf setFrame:weakSelf.superview.frame];
|
||||
}];
|
||||
[self observeStandardDefaultsKey:@"GBForceIntegerScale" withBlock:^(id newValue) {
|
||||
[weakSelf setFrame:weakSelf.superview.frame];
|
||||
}];
|
||||
[self observeStandardDefaultsKey:@"JoyKitDefaultControllers" withBlock:^(id newValue) {
|
||||
[weakSelf reassignControllers];
|
||||
}];
|
||||
|
@ -279,7 +285,9 @@ static const uint8_t workboy_vk_to_key[] = {
|
|||
|
||||
- (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"]) {
|
||||
double ratio = frame.size.width / frame.size.height;
|
||||
double width = GB_get_screen_width(_gb);
|
||||
|
@ -297,6 +305,19 @@ static const uint8_t workboy_vk_to_key[] = {
|
|||
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];
|
||||
}
|
||||
|
@ -343,6 +364,17 @@ static const uint8_t workboy_vk_to_key[] = {
|
|||
(analogClockMultiplierValid && analogClockMultiplier < 1)) {
|
||||
[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];
|
||||
}
|
||||
|
||||
|
@ -370,7 +402,7 @@ static const uint8_t workboy_vk_to_key[] = {
|
|||
player_count = 2;
|
||||
}
|
||||
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)];
|
||||
if (!key) continue;
|
||||
|
||||
|
@ -401,17 +433,38 @@ static const uint8_t workboy_vk_to_key[] = {
|
|||
analogClockMultiplierValid = false;
|
||||
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:
|
||||
if (self.document.partner) {
|
||||
if (player == 0) {
|
||||
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 {
|
||||
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 {
|
||||
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;
|
||||
}
|
||||
|
@ -444,7 +497,7 @@ static const uint8_t workboy_vk_to_key[] = {
|
|||
player_count = 2;
|
||||
}
|
||||
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)];
|
||||
if (!key) continue;
|
||||
|
||||
|
@ -470,6 +523,16 @@ static const uint8_t workboy_vk_to_key[] = {
|
|||
underclockKeyDown = false;
|
||||
analogClockMultiplierValid = false;
|
||||
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:
|
||||
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
|
||||
{
|
||||
if (!_gb) return;
|
||||
if ([self shouldControllerUseJoystickForMotion:controller]) {
|
||||
if (!self.mouseControlsActive) {
|
||||
GB_set_accelerometer_values(_gb, -axes.value.x, -axes.value.y);
|
||||
/* Always handle only the most dominant 2D input. */
|
||||
for (JOYAxes2D *otherAxes in controller.axes2D) {
|
||||
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);
|
||||
|
||||
|
||||
NSDictionary<NSNumber *, JOYController *> *controllerMapping = [self controllerMapping];
|
||||
NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];
|
||||
bool fauxAnalog = [defaults boolForKey:@"GBFauxAnalogInputs"];
|
||||
|
||||
for (unsigned player = 0; player < playerCount; player++) {
|
||||
JOYController *preferredJoypad = controllerMapping[@(player)];
|
||||
if (preferredJoypad && preferredJoypad != controller) continue; // The player has a different assigned controller
|
||||
if (!preferredJoypad && playerCount != 1) continue; // The player has no assigned controller in multiplayer mode, prevent controller inputs
|
||||
unsigned effectivePlayer;
|
||||
GB_gameboy_t *effectiveGB;
|
||||
if (![self controller:controller applicableForPlayer:player effectivePlayer:&effectivePlayer effectiveGB:&effectiveGB]) continue;
|
||||
|
||||
dispatch_async(dispatch_get_main_queue(), ^{
|
||||
[controller setPlayerLEDs:[controller LEDMaskForPlayer:player]];
|
||||
});
|
||||
NSDictionary *mapping = [[NSUserDefaults standardUserDefaults] dictionaryForKey:@"JoyKitInstanceMapping"][controller.uniqueID];
|
||||
NSDictionary *mapping = [defaults dictionaryForKey:@"JoyKitInstanceMapping"][controller.uniqueID];
|
||||
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;
|
||||
|
@ -633,25 +746,18 @@ static const uint8_t workboy_vk_to_key[] = {
|
|||
usage = GB_inline_const(JOYButtonUsage[], {JOYButtonUsageY, JOYButtonUsageA, JOYButtonUsageB, JOYButtonUsageX})[(usage - JOYButtonUsageGeneric0) & 3];
|
||||
}
|
||||
|
||||
GB_gameboy_t *effectiveGB = _gb;
|
||||
unsigned 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;
|
||||
if (usage >= JOYButtonUsageDPadLeft && usage <= JOYButtonUsageDPadDown) {
|
||||
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
|
||||
continue;
|
||||
}
|
||||
}
|
||||
else {
|
||||
if (controller != lastController) {
|
||||
[self setRumble:0];
|
||||
lastController = controller;
|
||||
else {
|
||||
// User used a digital direction input, revert to non-analog inputs
|
||||
GB_set_use_faux_analog_inputs(effectiveGB, effectivePlayer, false);
|
||||
}
|
||||
}
|
||||
|
||||
switch (usage) {
|
||||
switch ((unsigned)usage) {
|
||||
|
||||
case JOYButtonUsageNone: 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 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;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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>
|
||||
<array>
|
||||
<string>com.github.liji32.sameboy.gb</string>
|
||||
<string>public.gbrom</string>
|
||||
<string>public.gbrom</string>
|
||||
<string>com.retroarch.gb</string>
|
||||
</array>
|
||||
<key>LSTypeIsPackage</key>
|
||||
<integer>0</integer>
|
||||
|
@ -43,6 +44,7 @@
|
|||
<key>LSItemContentTypes</key>
|
||||
<array>
|
||||
<string>com.github.liji32.sameboy.gbc</string>
|
||||
<string>com.retroarch.gbc</string>
|
||||
</array>
|
||||
<key>LSTypeIsPackage</key>
|
||||
<integer>0</integer>
|
||||
|
@ -111,7 +113,9 @@
|
|||
<key>CFBundleExecutable</key>
|
||||
<string>SameBoy</string>
|
||||
<key>CFBundleIconFile</key>
|
||||
<string>AppIcon.icns</string>
|
||||
<string>AppIcon</string>
|
||||
<key>CFBundleIconName</key>
|
||||
<string>AppIcon</string>
|
||||
<key>CFBundleIdentifier</key>
|
||||
<string>com.github.liji32.sameboy</string>
|
||||
<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>
|
||||
|
||||
+ (id)shortcutWithPreferencesEncoding:(NSString *)encoding;
|
||||
+ (id)shortcutWithKeyEquivalent:(NSString *)key_equivalent modifierMask:(unsigned long long)mask;
|
||||
- (id)initWithKeyEquivalent:(NSString *)key_equivalent modifierMask:(unsigned long long)mask;
|
||||
+ (id)shortcutWithKeyEquivalent:(NSString *)key_equivalent modifierMask:(NSUInteger)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 *preferencesEncoding;
|
||||
@property(readonly) NSString *localizedModifierMaskDisplayName;
|
||||
|
|
|
@ -1,8 +1,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>
|
||||
<deployment identifier="macosx"/>
|
||||
<plugIn identifier="com.apple.InterfaceBuilder.CocoaPlugin" version="21507"/>
|
||||
<plugIn identifier="com.apple.InterfaceBuilder.CocoaPlugin" version="24093.9"/>
|
||||
</dependencies>
|
||||
<objects>
|
||||
<customObject id="-2" userLabel="File's Owner" customClass="NSApplication">
|
||||
|
@ -82,7 +82,7 @@
|
|||
<action selector="openDocument:" target="-1" id="bVn-NM-KNZ"/>
|
||||
</connections>
|
||||
</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"/>
|
||||
<connections>
|
||||
<action selector="cartSwap:" target="-1" id="iXS-Ol-IS0"/>
|
||||
|
@ -102,7 +102,7 @@
|
|||
</menu>
|
||||
</menuItem>
|
||||
<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>
|
||||
<action selector="newCartridgeInstance:" target="-1" id="GJc-xU-ZEr"/>
|
||||
</connections>
|
||||
|
@ -158,7 +158,7 @@
|
|||
</connections>
|
||||
</menuItem>
|
||||
<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"/>
|
||||
<menu key="submenu" title="Find" id="4R6-IU-Jq6">
|
||||
<items>
|
||||
|
@ -197,29 +197,73 @@
|
|||
<modifierMask key="keyEquivalentModifierMask"/>
|
||||
<menu key="submenu" title="Emulation" id="HyV-fh-RgO">
|
||||
<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>
|
||||
<action selector="reset:" target="-1" id="DKW-Bd-h3v"/>
|
||||
</connections>
|
||||
</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"/>
|
||||
<connections>
|
||||
<action selector="reset:" target="-1" id="VV1-VP-L7g"/>
|
||||
</connections>
|
||||
</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>
|
||||
<action selector="reloadROM:" target="-1" id="BpN-8V-Csg"/>
|
||||
</connections>
|
||||
</menuItem>
|
||||
<menuItem title="Pause" keyEquivalent="p" id="4K4-hw-R7Q">
|
||||
<menuItem title="Pause" secondaryImage="pause" catalog="system" keyEquivalent="p" id="4K4-hw-R7Q">
|
||||
<connections>
|
||||
<action selector="togglePause:" target="-1" id="osW-wt-QAa"/>
|
||||
</connections>
|
||||
</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 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"/>
|
||||
<menu key="submenu" title="Save State" id="Mxx-u1-M9D">
|
||||
<items>
|
||||
|
@ -276,7 +320,7 @@
|
|||
</items>
|
||||
</menu>
|
||||
</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"/>
|
||||
<menu key="submenu" title="Load State" id="l9D-Ej-sh2">
|
||||
<items>
|
||||
|
@ -344,7 +388,7 @@
|
|||
</menu>
|
||||
</menuItem>
|
||||
<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>
|
||||
<action selector="saveScreenshot:" target="-1" id="gJd-ml-J8p"/>
|
||||
</connections>
|
||||
|
@ -360,44 +404,13 @@
|
|||
<action selector="copyScreenshot:" target="-1" id="XJC-EB-HNl"/>
|
||||
</connections>
|
||||
</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 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>
|
||||
<action selector="toggleAudioRecording:" target="-1" id="YE5-mi-Yzd"/>
|
||||
</connections>
|
||||
</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>
|
||||
<action selector="mute:" target="-1" id="eK3-ea-ExJ"/>
|
||||
</connections>
|
||||
|
@ -414,18 +427,24 @@
|
|||
<action selector="toggleCheats:" target="-1" id="gsw-UY-fhu"/>
|
||||
</connections>
|
||||
</menuItem>
|
||||
<menuItem title="Show Cheats" id="LZV-QK-YXi">
|
||||
<menuItem title="Show Cheats" id="Nf8-F1-YyD">
|
||||
<modifierMask key="keyEquivalentModifierMask"/>
|
||||
<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>
|
||||
</menuItem>
|
||||
</items>
|
||||
</menu>
|
||||
</menuItem>
|
||||
<menuItem title="Connectivity" id="IcW-ZC-4wb">
|
||||
<menuItem title="Connect" id="IcW-ZC-4wb">
|
||||
<modifierMask key="keyEquivalentModifierMask"/>
|
||||
<menu key="submenu" title="Connectivity" id="BDM-Cv-BOm">
|
||||
<menu key="submenu" title="Connect" id="BDM-Cv-BOm">
|
||||
<items>
|
||||
<menuItem title="None" id="SiH-Q4-OBY">
|
||||
<modifierMask key="keyEquivalentModifierMask"/>
|
||||
|
@ -433,7 +452,7 @@
|
|||
<action selector="disconnectAllAccessories:" target="-1" id="5hY-9U-nRn"/>
|
||||
</connections>
|
||||
</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"/>
|
||||
<menu key="submenu" title="Game Link Cable & Infrared" id="6sJ-Wz-QLj">
|
||||
<connections>
|
||||
|
@ -444,13 +463,13 @@
|
|||
<action selector="nop:" target="-3" id="Bpa-0C-lkN"/>
|
||||
</connections>
|
||||
</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"/>
|
||||
<connections>
|
||||
<action selector="connectPrinter:" target="-1" id="tl1-CL-tAw"/>
|
||||
</connections>
|
||||
</menuItem>
|
||||
<menuItem title="Workboy" id="lo9-CX-BJj">
|
||||
<menuItem title="Workboy" secondaryImage="keyboard" catalog="system" id="lo9-CX-BJj">
|
||||
<modifierMask key="keyEquivalentModifierMask"/>
|
||||
<connections>
|
||||
<action selector="connectWorkboy:" target="-1" id="6vS-bq-wAX"/>
|
||||
|
@ -463,14 +482,14 @@
|
|||
<modifierMask key="keyEquivalentModifierMask"/>
|
||||
<menu key="submenu" title="Develop" id="UVb-cc-at0">
|
||||
<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"/>
|
||||
<connections>
|
||||
<action selector="toggleDeveloperMode:" target="-3" id="PIc-o3-bzb"/>
|
||||
</connections>
|
||||
</menuItem>
|
||||
<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"/>
|
||||
<connections>
|
||||
<action selector="showConsoleWindow:" target="-1" id="mFf-4i-jLG"/>
|
||||
|
@ -482,14 +501,14 @@
|
|||
</connections>
|
||||
</menuItem>
|
||||
<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"/>
|
||||
<connections>
|
||||
<action selector="interrupt:" target="-1" id="ZmB-wG-fTs"/>
|
||||
</connections>
|
||||
</menuItem>
|
||||
<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"/>
|
||||
<menu key="submenu" title="Audio Channels" id="l22-4p-yTK">
|
||||
<items>
|
||||
|
@ -521,13 +540,13 @@
|
|||
</menu>
|
||||
</menuItem>
|
||||
<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"/>
|
||||
<connections>
|
||||
<action selector="toggleDisplayBackground:" target="-1" id="p5b-1n-SPR"/>
|
||||
</connections>
|
||||
</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"/>
|
||||
<connections>
|
||||
<action selector="toggleDisplayObjects:" target="-1" id="8ie-ey-739"/>
|
||||
|
@ -601,4 +620,24 @@
|
|||
<point key="canvasLocation" x="140" y="260"/>
|
||||
</menu>
|
||||
</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>
|
||||
|
|
|
@ -3,8 +3,8 @@
|
|||
#import <objc/runtime.h>
|
||||
|
||||
@interface NSTextFieldCell ()
|
||||
- (CGRect)_textLayerDrawingRectForCellFrame:(CGRect)rect;
|
||||
@property NSSize textInset;
|
||||
- (bool)_isEditingInView:(NSView *)view;
|
||||
@end
|
||||
|
||||
@implementation NSTextFieldCell (Inset)
|
||||
|
@ -19,21 +19,59 @@
|
|||
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;
|
||||
ret.origin.x += inset.width;
|
||||
ret.origin.y += inset.height;
|
||||
ret.size.width -= inset.width;
|
||||
ret.size.height -= inset.height;
|
||||
return ret;
|
||||
if (self.drawsBackground) {
|
||||
[self.backgroundColor setFill];
|
||||
if ([self _isEditingInView:controlView]) {
|
||||
NSRectFill(cellFrame);
|
||||
}
|
||||
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
|
||||
{
|
||||
method_exchangeImplementations(class_getInstanceMethod(self, @selector(_textLayerDrawingRectForCellFrame:)),
|
||||
class_getInstanceMethod(self, @selector(_textLayerDrawingRectForCellFrameHook:)));
|
||||
method_exchangeImplementations(class_getInstanceMethod(self, @selector(drawWithFrame:inView:)),
|
||||
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
|
||||
|
|
|
@ -6,7 +6,7 @@ static id nop(id self, SEL _cmd)
|
|||
return nil;
|
||||
}
|
||||
|
||||
static double blah(id self, SEL _cmd)
|
||||
static double minSize(id self, SEL _cmd)
|
||||
{
|
||||
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
|
||||
method_setImplementation(class_getInstanceMethod(self, @selector(menuFormRepresentation)), (IMP)nop);
|
||||
// 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
|
||||
|
|
|
@ -1,8 +1,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>
|
||||
<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"/>
|
||||
</dependencies>
|
||||
<objects>
|
||||
|
@ -13,7 +13,7 @@
|
|||
</customObject>
|
||||
<customObject id="-1" userLabel="First Responder" customClass="FirstResponder"/>
|
||||
<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"/>
|
||||
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
|
||||
<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"/>
|
||||
<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"/>
|
||||
<windowPositionMask key="initialPositionMask" leftStrut="YES" rightStrut="YES" topStrut="YES" bottomStrut="YES"/>
|
||||
<rect key="contentRect" x="196" y="240" width="480" height="360"/>
|
||||
<rect key="screenRect" x="0.0" y="0.0" width="2560" height="1417"/>
|
||||
<view key="contentView" wantsLayer="YES" id="EiT-Mj-1SZ">
|
||||
|
@ -97,7 +96,6 @@ DQ
|
|||
<point key="canvasLocation" x="217" y="267"/>
|
||||
</window>
|
||||
<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="screenRect" x="0.0" y="0.0" width="2560" height="1417"/>
|
||||
<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">
|
||||
<rect key="frame" x="58" y="15" width="359" height="24"/>
|
||||
<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"/>
|
||||
<color key="textColor" name="labelColor" 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 |