From b8a7b454d2e78a326bad22bf9678e2dab9983e9b Mon Sep 17 00:00:00 2001 From: Vas Crabb Date: Sat, 14 Feb 2015 06:02:06 +1100 Subject: Break up the Cocoa debugger by class - it's ugly crammed into a single file --- src/osd/modules/debugger/debugosx.h | 370 ---- src/osd/modules/debugger/debugosx.m | 2309 +------------------- src/osd/modules/debugger/osx/debugosx.h | 55 + src/osd/modules/debugger/osx/debugosxconsoleview.h | 26 + src/osd/modules/debugger/osx/debugosxconsoleview.m | 30 + .../debugger/osx/debugosxdebugcommandhistory.h | 37 + .../debugger/osx/debugosxdebugcommandhistory.m | 111 + .../modules/debugger/osx/debugosxdebugconsole.h | 56 + .../modules/debugger/osx/debugosxdebugconsole.m | 356 +++ src/osd/modules/debugger/osx/debugosxdebugview.h | 64 + src/osd/modules/debugger/osx/debugosxdebugview.m | 466 ++++ .../debugger/osx/debugosxdebugwindowhandler.h | 96 + .../debugger/osx/debugosxdebugwindowhandler.m | 386 ++++ .../modules/debugger/osx/debugosxdisassemblyview.h | 46 + .../modules/debugger/osx/debugosxdisassemblyview.m | 371 ++++ .../debugger/osx/debugosxdisassemblyviewer.h | 31 + .../debugger/osx/debugosxdisassemblyviewer.m | 138 ++ .../modules/debugger/osx/debugosxerrorlogview.h | 26 + .../modules/debugger/osx/debugosxerrorlogview.m | 30 + .../modules/debugger/osx/debugosxerrorlogviewer.h | 29 + .../modules/debugger/osx/debugosxerrorlogviewer.m | 64 + src/osd/modules/debugger/osx/debugosxmemoryview.h | 44 + src/osd/modules/debugger/osx/debugosxmemoryview.m | 207 ++ .../modules/debugger/osx/debugosxmemoryviewer.h | 31 + .../modules/debugger/osx/debugosxmemoryviewer.m | 137 ++ .../modules/debugger/osx/debugosxregistersview.h | 33 + .../modules/debugger/osx/debugosxregistersview.m | 71 + src/osd/sdl/sdl.mak | 19 +- src/osd/sdl/video.c | 4 +- 29 files changed, 2989 insertions(+), 2654 deletions(-) delete mode 100644 src/osd/modules/debugger/debugosx.h create mode 100644 src/osd/modules/debugger/osx/debugosx.h create mode 100644 src/osd/modules/debugger/osx/debugosxconsoleview.h create mode 100644 src/osd/modules/debugger/osx/debugosxconsoleview.m create mode 100644 src/osd/modules/debugger/osx/debugosxdebugcommandhistory.h create mode 100644 src/osd/modules/debugger/osx/debugosxdebugcommandhistory.m create mode 100644 src/osd/modules/debugger/osx/debugosxdebugconsole.h create mode 100644 src/osd/modules/debugger/osx/debugosxdebugconsole.m create mode 100644 src/osd/modules/debugger/osx/debugosxdebugview.h create mode 100644 src/osd/modules/debugger/osx/debugosxdebugview.m create mode 100644 src/osd/modules/debugger/osx/debugosxdebugwindowhandler.h create mode 100644 src/osd/modules/debugger/osx/debugosxdebugwindowhandler.m create mode 100644 src/osd/modules/debugger/osx/debugosxdisassemblyview.h create mode 100644 src/osd/modules/debugger/osx/debugosxdisassemblyview.m create mode 100644 src/osd/modules/debugger/osx/debugosxdisassemblyviewer.h create mode 100644 src/osd/modules/debugger/osx/debugosxdisassemblyviewer.m create mode 100644 src/osd/modules/debugger/osx/debugosxerrorlogview.h create mode 100644 src/osd/modules/debugger/osx/debugosxerrorlogview.m create mode 100644 src/osd/modules/debugger/osx/debugosxerrorlogviewer.h create mode 100644 src/osd/modules/debugger/osx/debugosxerrorlogviewer.m create mode 100644 src/osd/modules/debugger/osx/debugosxmemoryview.h create mode 100644 src/osd/modules/debugger/osx/debugosxmemoryview.m create mode 100644 src/osd/modules/debugger/osx/debugosxmemoryviewer.h create mode 100644 src/osd/modules/debugger/osx/debugosxmemoryviewer.m create mode 100644 src/osd/modules/debugger/osx/debugosxregistersview.h create mode 100644 src/osd/modules/debugger/osx/debugosxregistersview.m diff --git a/src/osd/modules/debugger/debugosx.h b/src/osd/modules/debugger/debugosx.h deleted file mode 100644 index a219f5f8b8a..00000000000 --- a/src/osd/modules/debugger/debugosx.h +++ /dev/null @@ -1,370 +0,0 @@ -// license:BSD-3-Clause -// copyright-holders:Vas Crabb -//============================================================ -// -// debugosx.h - MacOS X Cocoa debug window handling -// -// Copyright (c) 1996-2006, Nicola Salmoria and the MAME Team. -// Visit http://mamedev.org for licensing and usage restrictions. -// -//============================================================ - -#ifndef __SDL_DEBUGOSX__ -#define __SDL_DEBUGOSX__ - -// make sure this comes first -#include - -// MAME headers -#include "emu.h" -#include "debug/debugvw.h" -#include "modules/lib/osdobj_common.h" - - -#ifdef __OBJC__ - -// standard Cocoa headers -#import - -// workarounds for 10.6 warnings -#ifdef MAC_OS_X_VERSION_MAX_ALLOWED - -#if MAC_OS_X_VERSION_MAX_ALLOWED < 1050 - -typedef int NSInteger; -typedef unsigned NSUInteger; -typedef float CGFloat; - -#endif // MAC_OS_X_VERSION_MAX_ALLOWED < 1050 - -#if MAC_OS_X_VERSION_MAX_ALLOWED < 1060 - -@protocol NSWindowDelegate -@end - -@protocol NSSplitViewDelegate -@end - -@protocol NSControlTextEditingDelegate -@end - -@protocol NSTextFieldDelegate -@end - -#endif // MAC_OS_X_VERSION_MAX_ALLOWED < 1060 - -#endif // MAC_OS_X_VERSION_MAX_ALLOWED - - -//============================================================ -// PROTOCOLS -//============================================================ - -@protocol MAMEDebugViewSubviewSupport - -- (NSString *)selectedSubviewName; -- (int)selectedSubviewIndex; -- (void)selectSubviewAtIndex:(int)index; -- (void)selectSubviewForCPU:(device_t *)device; - -@end - - -@protocol MAMEDebugViewExpressionSupport - -- (NSString *)expression; -- (void)setExpression:(NSString *)exp; - -@end - - - -//============================================================ -// CLASSES -//============================================================ - -@interface MAMEDebugCommandHistory : NSObject -{ - NSInteger length, position; - NSString *current; - NSMutableArray *history; -} - -+ (NSInteger)defaultLength; - -- (id)init; - -- (NSInteger)length; -- (void)setLength:(NSInteger)l; - -- (void)add:(NSString *)entry; -- (NSString *)previous:(NSString *)cur; -- (NSString *)next:(NSString *)cur; -- (void)reset; -- (void)clear; - -@end - - -@interface MAMEDebugView : NSView -{ - int type; - running_machine *machine; - debug_view *view; - - debug_view_xy *totalSize, *topLeft; - - NSFont *font; - CGFloat fontWidth, fontHeight, fontAscent; -} - -+ (NSFont *)defaultFont; - -- (id)initWithFrame:(NSRect)f type:(debug_view_type)t machine:(running_machine &)m; - -- (void)update; - -- (NSSize)maximumFrameSize; - -- (NSFont *)font; -- (void)setFont:(NSFont *)f; - -- (void)windowDidBecomeKey:(NSNotification *)notification; -- (void)windowDidResignKey:(NSNotification *)notification; - -@end - - -@interface MAMEMemoryView : MAMEDebugView -{ -} - -- (id)initWithFrame:(NSRect)f machine:(running_machine &)m; - -- (NSSize)maximumFrameSize; - -- (NSString *)selectedSubviewName; -- (int)selectedSubviewIndex; -- (void)selectSubviewAtIndex:(int)index; -- (void)selectSubviewForCPU:(device_t *)device; - -- (NSString *)expression; -- (void)setExpression:(NSString *)exp; - -- (IBAction)showChunkSize:(id)sender; -- (IBAction)showPhysicalAddresses:(id)sender; -- (IBAction)showReverseView:(id)sender; -- (IBAction)showReverseViewToggle:(id)sender; - -- (void)insertActionItemsInMenu:(NSMenu *)menu atIndex:(NSInteger)index; -- (void)insertSubviewItemsInMenu:(NSMenu *)menu atIndex:(NSInteger)index; - -@end - - -@interface MAMEDisassemblyView : MAMEDebugView -{ - BOOL useConsole; -} - -- (id)initWithFrame:(NSRect)f machine:(running_machine &)m useConsole:(BOOL)uc; - -- (NSSize)maximumFrameSize; - -- (NSString *)selectedSubviewName; -- (int)selectedSubviewIndex; -- (void)selectSubviewAtIndex:(int)index; -- (void)selectSubviewForCPU:(device_t *)device; - -- (NSString *)expression; -- (void)setExpression:(NSString *)exp; - -- (IBAction)debugToggleBreakpoint:(id)sender; -- (IBAction)debugToggleBreakpointEnable:(id)sender; -- (IBAction)debugRunToCursor:(id)sender; - -- (IBAction)showRightColumn:(id)sender; - -- (void)insertActionItemsInMenu:(NSMenu *)menu atIndex:(NSInteger)index; -- (void)insertSubviewItemsInMenu:(NSMenu *)menu atIndex:(NSInteger)index; - -@end - - -@interface MAMERegistersView : MAMEDebugView -{ -} - -- (id)initWithFrame:(NSRect)f machine:(running_machine &)m; - -- (NSSize)maximumFrameSize; - -- (NSString *)selectedSubviewName; -- (int)selectedSubviewIndex; -- (void)selectSubviewAtIndex:(int)index; -- (void)selectSubviewForCPU:(device_t *)device; - -@end - - -@interface MAMEConsoleView : MAMEDebugView -{ -} - -- (id)initWithFrame:(NSRect)f machine:(running_machine &)m; - -@end - - -@interface MAMEErrorLogView : MAMEDebugView -{ -} - -- (id)initWithFrame:(NSRect)f machine:(running_machine &)m; - -@end - - -@interface MAMEDebugWindowHandler : NSObject -{ - NSWindow *window; - running_machine *machine; -} - -+ (void)addCommonActionItems:(NSMenu *)menu; -+ (NSPopUpButton *)newActionButtonWithFrame:(NSRect)frame; - -- (id)initWithMachine:(running_machine &)m title:(NSString *)t; - -- (void)activate; - -- (IBAction)debugRun:(id)sender; -- (IBAction)debugRunAndHide:(id)sender; -- (IBAction)debugRunToNextCPU:(id)sender; -- (IBAction)debugRunToNextInterrupt:(id)sender; -- (IBAction)debugRunToNextVBLANK:(id)sender; - -- (IBAction)debugStepInto:(id)sender; -- (IBAction)debugStepOver:(id)sender; -- (IBAction)debugStepOut:(id)sender; - -- (IBAction)debugSoftReset:(id)sender; -- (IBAction)debugHardReset:(id)sender; - -- (IBAction)debugExit:(id)sender; - -- (void)showDebugger:(NSNotification *)notification; -- (void)hideDebugger:(NSNotification *)notification; - -@end - - -@interface MAMEDebugConsole : MAMEDebugWindowHandler -{ - MAMEDebugCommandHistory *history; - NSMutableArray *auxiliaryWindows; - - MAMERegistersView *regView; - MAMEDisassemblyView *dasmView; - MAMEDebugView *consoleView; - NSTextField *commandField; -} - -- (id)initWithMachine:(running_machine &)m; - -- (void)setCPU:(device_t *)device; - -- (IBAction)doCommand:(id)sender; - -- (IBAction)debugNewMemoryWindow:(id)sender; -- (IBAction)debugNewDisassemblyWindow:(id)sender; -- (IBAction)debugNewErrorLogWindow:(id)sender; - -- (void)showDebugger:(NSNotification *)notification; -- (void)auxiliaryWindowWillClose:(NSNotification *)notification; - -- (BOOL)control:(NSControl *)control textView:(NSTextView *)textView doCommandBySelector:(SEL)command; - -- (void)windowWillClose:(NSNotification *)notification; - -- (CGFloat)splitView:(NSSplitView *)sender constrainMinCoordinate:(CGFloat)min ofSubviewAt:(NSInteger)offs; -- (CGFloat)splitView:(NSSplitView *)sender constrainMaxCoordinate:(CGFloat)max ofSubviewAt:(NSInteger)offs; -- (BOOL)splitView:(NSSplitView *)sender canCollapseSubview:(NSView *)subview; -- (void)splitView:(NSSplitView *)sender resizeSubviewsWithOldSize:(NSSize)oldSize; - -@end - - -@interface MAMEAuxiliaryDebugWindowHandler : MAMEDebugWindowHandler -{ - MAMEDebugConsole *console; -} - -+ (void)cascadeWindow:(NSWindow *)window; - -- (id)initWithMachine:(running_machine &)m title:(NSString *)t console:(MAMEDebugConsole *)c; - -- (IBAction)debugNewMemoryWindow:(id)sender; -- (IBAction)debugNewDisassemblyWindow:(id)sender; -- (IBAction)debugNewErrorLogWindow:(id)sender; - -- (void)windowWillClose:(NSNotification *)notification; - -- (void)cascadeWindowWithDesiredSize:(NSSize)desired forView:(NSView *)view; - -@end - - -@interface MAMEExpressionAuxiliaryDebugWindowHandler : MAMEAuxiliaryDebugWindowHandler -{ - MAMEDebugCommandHistory *history; - NSTextField *expressionField; -} - -- (id)initWithMachine:(running_machine &)m title:(NSString *)t console:(MAMEDebugConsole *)c; - -- (id )documentView; - -- (IBAction)doExpression:(id)sender; - -- (BOOL)control:(NSControl *)control textView:(NSTextView *)textView doCommandBySelector:(SEL)command; - -@end - - -@interface MAMEMemoryViewer : MAMEExpressionAuxiliaryDebugWindowHandler -{ - MAMEMemoryView *memoryView; -} - -- (id)initWithMachine:(running_machine &)m console:(MAMEDebugConsole *)c; - -- (IBAction)changeSubview:(id)sender; - -@end - - -@interface MAMEDisassemblyViewer : MAMEExpressionAuxiliaryDebugWindowHandler -{ - MAMEDisassemblyView *dasmView; -} - -- (id)initWithMachine:(running_machine &)m console:(MAMEDebugConsole *)c; - -- (IBAction)changeSubview:(id)sender; - -@end - - -@interface MAMEErrorLogViewer : MAMEAuxiliaryDebugWindowHandler -{ - MAMEErrorLogView *logView; -} - -- (id)initWithMachine:(running_machine &)m console:(MAMEDebugConsole *)c; - -@end - -#endif // __OBJC__ - -#endif // __SDL_DEBUGOSX__ diff --git a/src/osd/modules/debugger/debugosx.m b/src/osd/modules/debugger/debugosx.m index 9d140dbdb69..f8ea683a826 100644 --- a/src/osd/modules/debugger/debugosx.m +++ b/src/osd/modules/debugger/debugosx.m @@ -4,7 +4,7 @@ // // debugosx.m - MacOS X Cocoa debug window handling // -// Copyright (c) 1996-2010, Nicola Salmoria and the MAME Team. +// Copyright (c) 1996-2015, Nicola Salmoria and the MAME Team. // Visit http://mamedev.org for licensing and usage restrictions. // //============================================================ @@ -14,7 +14,6 @@ // * Automatic scrolling for console and log views // * Using alpha for disabled foreground colours doesn't really work // * New windows created from auxiliary windows should inherit focus rather than pointing at current CPU -// * Should have map of machine to console for multiple machine support rather than a single console // * Improve behaviour of expression history in memory and disassembly windows - the double tap is annoying // * Keyboard shortcuts in error log windows // * Don't accept keyboard input while the game is running @@ -22,46 +21,43 @@ // * Scroll views with content narrower than clipping area are flaky under Tiger - nothing I can do about this -// Workaround for Nil being re=defined in luabridge -#include "emu.h" - -// standard Cocoa headers -#include -#import - // MAME headers -//#include "emu.h" -#include "debug/debugvw.h" -#include "debug/debugcon.h" -#include "debug/debugcpu.h" +#include "emu.h" #include "debugger.h" -#include "debug/dvdisasm.h" -#include "debug/dvmemory.h" -#include "debug/dvstate.h" // MAMEOS headers -#include "debugosx.h" +#include "modules/lib/osdobj_common.h" +#include "osx/debugosx.h" #include "osdsdl.h" #include "debug_module.h" +#import "osx/debugosxdebugconsole.h" +#import "osx/debugosxdebugwindowhandler.h" + + //============================================================ // MODULE SUPPORT //============================================================ -static MAMEDebugConsole *main_console = nil; - class debugger_osx : public osd_module, public debug_module { public: debugger_osx() : osd_module(OSD_DEBUG_PROVIDER, "osx"), debug_module(), - m_machine(NULL) + m_machine(NULL), + m_console(nil) + { + } + + virtual ~debugger_osx() { } - virtual ~debugger_osx() { } + virtual int init() + { + return 0; + } - virtual int init() { return 0;} virtual void exit() { } @@ -72,31 +68,11 @@ public: private: running_machine *m_machine; + MAMEDebugConsole *m_console; }; MODULE_DEFINITION(DEBUG_OSX, debugger_osx) -//============================================================ -// LOCAL VARIABLES -//============================================================ - - -static BOOL waiting_for_debugger = NO; - -static NSString *const MAMEHideDebuggerNotification = @"MAMEHideDebuggerNotification"; -static NSString *const MAMEShowDebuggerNotification = @"MAMEShowDebuggerNotification"; -static NSString *const MAMEAuxiliaryDebugWindowWillCloseNotification - = @"MAMEAuxiliaryDebugWindowWillCloseNotification"; - - -//============================================================ -// PROTOTYPES -//============================================================ - -static void debugwin_view_update(debug_view &view, void *osdprivate); - -static void console_create_window(running_machine &machine); - //============================================================ // debugger_osx::init_debugger //============================================================ @@ -113,32 +89,26 @@ void debugger_osx::init_debugger(running_machine &machine) void debugger_osx::wait_for_debugger(device_t &device, bool firststop) { // create a console window - if (main_console == nil) - console_create_window(*m_machine); + if (m_console == nil) + m_console = [[MAMEDebugConsole alloc] initWithMachine:*m_machine]; // make sure the debug windows are visible - waiting_for_debugger = YES; if (firststop) { NSDictionary *info = [NSDictionary dictionaryWithObjectsAndKeys:[NSValue valueWithPointer:&device], @"MAMEDebugDevice", nil]; [[NSNotificationCenter defaultCenter] postNotificationName:MAMEShowDebuggerNotification - object:main_console + object:m_console userInfo:info]; } // get and process messages - { - NSEvent *ev = [NSApp nextEventMatchingMask:NSAnyEventMask - untilDate:[NSDate distantFuture] - inMode:NSDefaultRunLoopMode - dequeue:YES]; - if (ev != nil) - [NSApp sendEvent:ev]; - } - - // mark the debugger as active - waiting_for_debugger = NO; + NSEvent *ev = [NSApp nextEventMatchingMask:NSAnyEventMask + untilDate:[NSDate distantFuture] + inMode:NSDefaultRunLoopMode + dequeue:YES]; + if (ev != nil) + [NSApp sendEvent:ev]; } @@ -149,2226 +119,3 @@ void debugger_osx::wait_for_debugger(device_t &device, bool firststop) void debugger_osx::debugger_update() { } - -//============================================================ -// debugwin_view_update -//============================================================ - -static void debugwin_view_update(debug_view &view, void *osdprivate) -{ - [(MAMEDebugView *)osdprivate update]; -} - - -//============================================================ -// console_create_window -//============================================================ - -void console_create_window(running_machine &machine) -{ - main_console = [[MAMEDebugConsole alloc] initWithMachine:machine]; -} - - -//============================================================ -// MAMEDebugView class -//============================================================ - -@implementation MAMEDebugCommandHistory - -+ (NSInteger)defaultLength { - return 100; -} - - -- (id)init { - if (!(self = [super init])) - return nil; - length = [[self class] defaultLength]; - position = -1; - current = nil; - history = [[NSMutableArray alloc] initWithCapacity:length]; - return self; -} - - -- (void)dealloc { - if (current != nil) - [current release]; - if (history != nil) - [history release]; - [super dealloc]; -} - - -- (NSInteger)length { - return length; -} - - -- (void)setLength:(NSInteger)l { - length = l; - while ([history count] > length) - [history removeLastObject]; -} - - -- (void)add:(NSString *)entry { - if (([history count] == 0) || ![[history objectAtIndex:0] isEqualToString:entry]) { - [history insertObject:entry atIndex:0]; - while ([history count] > length) - [history removeLastObject]; - } - position = -1; -} - - -- (NSString *)previous:(NSString *)cur { - if ((position + 1) < [history count]) { - if (position < 0) { - [current autorelease]; - current = [cur copy]; - } - return [history objectAtIndex:++position]; - } else { - return nil; - } -} - - -- (NSString *)next:(NSString *)cur { - if (position > 0) { - return [history objectAtIndex:--position]; - } else if (position == 0) { - position--; - return [[current retain] autorelease]; - } else { - return nil; - } -} - - -- (void)reset { - position = -1; - if (current != nil) { - [current release]; - current = nil; - } -} - - -- (void)clear { - position = -1; - if (current != nil) { - [current release]; - current = nil; - } - [history removeAllObjects]; -} - -@end - - -//============================================================ -// MAMEDebugView class -//============================================================ - -@implementation MAMEDebugView - -- (NSColor *)foregroundForAttribute:(UINT8)attrib { - const CGFloat alpha = (attrib & DCA_DISABLED) ? 0.5 : 1.0; - if (attrib & DCA_COMMENT) - return [NSColor colorWithCalibratedRed:0.0 green:0.375 blue:0.0 alpha:1.0]; - else if (attrib & DCA_INVALID) - return [NSColor colorWithCalibratedRed:0.0 green:0.0 blue:1.0 alpha:alpha]; - else if (attrib & DCA_CHANGED) - return [NSColor colorWithCalibratedRed:0.875 green:0.0 blue:0.0 alpha:alpha]; - else - return [NSColor colorWithCalibratedWhite:0.0 alpha:alpha]; -} - - -- (NSColor *)backgroundForAttribute:(UINT8)attrib { - if ((attrib & DCA_SELECTED) && (attrib & DCA_CURRENT)) { - if ([[self window] isKeyWindow] && ([[self window] firstResponder] == self)) - return [NSColor colorWithCalibratedRed:0.875 green:0.625 blue:0.875 alpha:1.0]; - else - return [NSColor colorWithCalibratedRed:0.875 green:0.5 blue:0.625 alpha:1.0]; - } else if (attrib & DCA_CURRENT) { - return [NSColor colorWithCalibratedRed:1.0 green:0.625 blue:0.625 alpha:1.0]; - } else if (attrib & DCA_SELECTED) { - if ([[self window] isKeyWindow] && ([[self window] firstResponder] == self)) - return [NSColor colorWithCalibratedRed:0.75 green:0.875 blue:1.0 alpha:1.0]; - else - return [NSColor colorWithCalibratedWhite:0.875 alpha:1.0]; - } else if (attrib & DCA_ANCILLARY) { - return [NSColor colorWithCalibratedWhite:0.75 alpha:1.0]; - } else { - return [NSColor colorWithCalibratedWhite:1.0 alpha:1.0]; - } -} - - -- (debug_view_xy)convertLocation:(NSPoint)location { - debug_view_xy position; - position.x = lround(floor(location.x / fontWidth)); - position.y = lround(floor(location.y / fontHeight)); - if (position.x < 0) - position.x = 0; - else if (position.x >= totalSize->x) - position.x = totalSize->x - 1; - if (position.y < 0) - position.y = 0; - else if (position.y >= totalSize->y) - position.y = totalSize->y - 1; - return position; -} - - -- (void)convertBounds:(NSRect)b toPosition:(debug_view_xy *)origin size:(debug_view_xy *)size { - origin->x = lround(floor(b.origin.x / fontWidth)); - origin->y = lround(floor(b.origin.y / fontHeight)); - size->x = lround(ceil((b.origin.x + b.size.width) / fontWidth)) - origin->x; - size->y = lround(ceil((b.origin.y + b.size.height) / fontHeight)) - origin->y; -} - - -- (void)recomputeVisible { - if ([self window] != nil) { - debug_view_xy origin, size; - - // this gets all the characters that are at least paritally visible - [self convertBounds:[self visibleRect] toPosition:&origin size:&size]; - - // need to render entire lines or we get screwed up characters when widening views - origin.x = 0; - size.x = totalSize->x; - - // tell them what we think - view->set_visible_size(size); - view->set_visible_position(origin); - topLeft->x = origin.x; - topLeft->y = origin.y; - } -} - - -- (void)typeCharacterAndScrollToCursor:(char)ch { - if (view->cursor_supported()) { - debug_view_xy oldPos = view->cursor_position(); - view->process_char(ch); - { - debug_view_xy newPos = view->cursor_position(); - if ((newPos.x != oldPos.x) || (newPos.y != oldPos.y)) { - [self scrollRectToVisible:NSMakeRect(newPos.x * fontWidth, - newPos.y * fontHeight, - fontWidth, - fontHeight)]; - } - } - } else { - view->process_char(ch); - } -} - - -+ (NSFont *)defaultFont { - // maybe we should get the configured system fixed-width font... - return [NSFont fontWithName:@"Monaco" size:10]; -} - - -- (id)initWithFrame:(NSRect)f type:(debug_view_type)t machine:(running_machine &)m { - if (!(self = [super initWithFrame:f])) - return nil; - type = t; - machine = &m; - view = machine->debug_view().alloc_view((debug_view_type)type, debugwin_view_update, self); - if (view == nil) { - [self release]; - return nil; - } - totalSize = global_alloc(debug_view_xy()); - topLeft = global_alloc(debug_view_xy()); - totalSize->x = totalSize->y = 0; - topLeft->x = topLeft->y = 0; - [self setFont:[[self class] defaultFont]]; - return self; -} - - -- (void)dealloc { - [[NSNotificationCenter defaultCenter] removeObserver:self]; - if (font != nil) - [font release]; - global_free(totalSize); - global_free(topLeft); - [super dealloc]; -} - - -- (void)update { - debug_view_xy newSize, newOrigin; - - // resize our frame if the total size has changed - newSize = view->total_size(); - if ((newSize.x != totalSize->x) || (newSize.y != totalSize->y)) { - [self setFrameSize:NSMakeSize(fontWidth * newSize.x, fontHeight * newSize.y)]; - totalSize->x = newSize.x; - totalSize->y = newSize.y; - } - - // scroll the view if we're being told to - newOrigin = view->visible_position(); - if (newOrigin.y != topLeft->y) { - [self scrollPoint:NSMakePoint([self visibleRect].origin.x, newOrigin.y * fontHeight)]; - topLeft->y = newOrigin.y; - } - - // recompute the visible area and mark as dirty - [self recomputeVisible]; - [self setNeedsDisplay:YES]; -} - - -- (NSSize)maximumFrameSize { - debug_view_xy max = view->total_size(); - return NSMakeSize(max.x * fontWidth, max.y * fontHeight); -} - - -- (NSFont *)font { - return [[font retain] autorelease]; -} - - -- (void)setFont:(NSFont *)f { - [font autorelease]; - font = [f retain]; - fontWidth = [font maximumAdvancement].width; - fontHeight = ceil([font ascender] - [font descender]); - fontAscent = [font ascender]; - [[self enclosingScrollView] setLineScroll:fontHeight]; - totalSize->x = totalSize->y = 0; - [self update]; -} - - -- (void)windowDidBecomeKey:(NSNotification *)notification { - NSWindow *win = [notification object]; - if ((win == [self window]) && ([win firstResponder] == self) && view->cursor_supported()) - [self setNeedsDisplay:YES]; -} - - -- (void)windowDidResignKey:(NSNotification *)notification { - NSWindow *win = [notification object]; - if ((win == [self window]) && ([win firstResponder] == self) && view->cursor_supported()) - [self setNeedsDisplay:YES]; -} - - -- (BOOL)acceptsFirstResponder { - return view->cursor_supported(); -} - - -- (BOOL)becomeFirstResponder { - if (view->cursor_supported()) { - debug_view_xy pos; - view->set_cursor_visible(true); - pos = view->cursor_position(); - [self scrollRectToVisible:NSMakeRect(pos.x * fontWidth, pos.y * fontHeight, fontWidth, fontHeight)]; - [self setNeedsDisplay:YES]; - return [super becomeFirstResponder]; - } else { - return NO; - } -} - - -- (BOOL)resignFirstResponder { - if (view->cursor_supported()) - [self setNeedsDisplay:YES]; - return [super resignFirstResponder]; -} - - -- (void)viewDidMoveToSuperview { - [[self enclosingScrollView] setLineScroll:fontHeight]; - [super viewDidMoveToSuperview]; -} - - -- (void)viewDidMoveToWindow { - [[NSNotificationCenter defaultCenter] removeObserver:self name:NSWindowDidBecomeKeyNotification object:nil]; - [[NSNotificationCenter defaultCenter] removeObserver:self name:NSWindowDidResignKeyNotification object:nil]; - if ([self window] != nil) { - [[NSNotificationCenter defaultCenter] addObserver:self - selector:@selector(windowDidBecomeKey:) - name:NSWindowDidBecomeKeyNotification - object:[self window]]; - [[NSNotificationCenter defaultCenter] addObserver:self - selector:@selector(windowDidResignKey:) - name:NSWindowDidResignKeyNotification - object:[self window]]; - [self recomputeVisible]; - } -} - - -- (BOOL)isFlipped { - return YES; -} - - -- (void)drawRect:(NSRect)dirtyRect { - const debug_view_char *base; - debug_view_xy origin, size; - debug_view_xy position, clip; - NSMutableString *text; - NSMutableDictionary *attributes; - UINT32 pass, row, col; - - // work out how much we need to draw - [self recomputeVisible]; - origin = view->visible_position(); - size = view->visible_size(); - [self convertBounds:dirtyRect toPosition:&position size:&clip]; - - // this gets the text for the whole visible area - base = view->viewdata(); - if (!base) - return; - - text = [[NSMutableString alloc] initWithCapacity:clip.x]; - attributes = [[NSMutableDictionary alloc] initWithObjectsAndKeys:font, NSFontAttributeName, nil]; - for (pass = 0; pass < 2; pass++) { - const debug_view_char *data = base + ((position.y - origin.y) * size.x); - for (row = position.y; row < position.y + clip.y; row++, data += size.x) { - int attr = -1; - - if ((row < origin.y) || (row >= origin.y + size.y)) - continue; - - // render entire lines to get character alignment right - for (col = origin.x; col < origin.x + size.x; col++) { - if ((attr != data[col - origin.x].attrib) && ([text length] > 0)) { - if (pass == 0) { - [[self backgroundForAttribute:attr] set]; - [NSBezierPath fillRect:NSMakeRect((col - [text length]) * fontWidth, - row * fontHeight, - [text length] * fontWidth, - fontHeight)]; - } else { - [attributes setObject:[self foregroundForAttribute:attr] - forKey:NSForegroundColorAttributeName]; - [text drawAtPoint:NSMakePoint((col - [text length]) * fontWidth, row * fontHeight) - withAttributes:attributes]; - } - [text setString:@""]; - } - attr = data[col - origin.x].attrib; - [text appendFormat:@"%c", data[col - origin.x].byte]; - } - if ([text length] > 0) { - if (pass == 0) { - [[self backgroundForAttribute:attr] set]; - [NSBezierPath fillRect:NSMakeRect((col - [text length]) * fontWidth, - row * fontHeight, - [text length] * fontWidth, - fontHeight)]; - } else { - [attributes setObject:[self foregroundForAttribute:attr] - forKey:NSForegroundColorAttributeName]; - [text drawAtPoint:NSMakePoint((col - [text length]) * fontWidth, row * fontHeight) - withAttributes:attributes]; - } - [text setString:@""]; - } - } - } - [attributes release]; - [text release]; -} - - -- (void)mouseDown:(NSEvent *)event { - NSPoint location = [self convertPoint:[event locationInWindow] fromView:nil]; - if (view->cursor_supported()) { - view->set_cursor_position([self convertLocation:location]); - view->set_cursor_visible(true); - [self setNeedsDisplay:YES]; - } -} - - -- (void)mouseDragged:(NSEvent *)event { - NSPoint location = [self convertPoint:[event locationInWindow] fromView:nil]; - if (view->cursor_supported()) { - [self autoscroll:event]; - view->set_cursor_position([self convertLocation:location]); - [self setNeedsDisplay:YES]; - } -} - - -- (void)rightMouseDown:(NSEvent *)event { - NSPoint location = [self convertPoint:[event locationInWindow] fromView:nil]; - if (view->cursor_supported()) { - view->set_cursor_position([self convertLocation:location]); - view->set_cursor_visible(true); - [self setNeedsDisplay:YES]; - } - [super rightMouseDown:event]; -} - - -- (void)keyDown:(NSEvent *)event { - NSUInteger modifiers = [event modifierFlags]; - NSString *str = [event charactersIgnoringModifiers]; - - if ([str length] == 1) { - if (modifiers & NSNumericPadKeyMask) { - switch ([str characterAtIndex:0]) { - case NSUpArrowFunctionKey: - if (modifiers & NSCommandKeyMask) - view->process_char(DCH_CTRLHOME); - else - view->process_char(DCH_UP); - return; - case NSDownArrowFunctionKey: - if (modifiers & NSCommandKeyMask) - view->process_char(DCH_CTRLEND); - else - view->process_char(DCH_DOWN); - return; - case NSLeftArrowFunctionKey: - if (modifiers & NSCommandKeyMask) - [self typeCharacterAndScrollToCursor:DCH_HOME]; - else if (modifiers & NSAlternateKeyMask) - [self typeCharacterAndScrollToCursor:DCH_CTRLLEFT]; - else - [self typeCharacterAndScrollToCursor:DCH_LEFT]; - return; - case NSRightArrowFunctionKey: - if (modifiers & NSCommandKeyMask) - [self typeCharacterAndScrollToCursor:DCH_END]; - else if (modifiers & NSAlternateKeyMask) - [self typeCharacterAndScrollToCursor:DCH_CTRLRIGHT]; - else - [self typeCharacterAndScrollToCursor:DCH_RIGHT]; - return; - default: - [self interpretKeyEvents:[NSArray arrayWithObject:event]]; - return; - } - } else if (modifiers & NSFunctionKeyMask) { - switch ([str characterAtIndex:0]) { - case NSPageUpFunctionKey: - if (modifiers & NSAlternateKeyMask) { - view->process_char(DCH_PUP); - return; - } - case NSPageDownFunctionKey: - if (modifiers & NSAlternateKeyMask) { - view->process_char(DCH_PDOWN); - return; - } - default: - ; - } - [super keyDown:event]; - return; - } - } - [self interpretKeyEvents:[NSArray arrayWithObject:event]]; -} - - -- (void)insertTab:(id)sender { - if ([[self window] firstResponder] == self) - [[self window] selectNextKeyView:self]; -} - - -- (void)insertBacktab:(id)sender { - if ([[self window] firstResponder] == self) - [[self window] selectPreviousKeyView:self]; -} - - -- (void)insertNewline:(id)sender { - debug_cpu_get_visible_cpu(*machine)->debug()->single_step(); -} - - -- (void)insertText:(id)string { - NSUInteger len; - NSRange found; - if ([string isKindOfClass:[NSAttributedString class]]) - string = [string string]; - for (len = [string length], found = NSMakeRange(0, 0); - found.location < len; - found.location += found.length) { - found = [string rangeOfComposedCharacterSequenceAtIndex:found.location]; - if (found.length == 1) { - unichar ch = [string characterAtIndex:found.location]; - if ((ch >= 32) && (ch < 127)) - [self typeCharacterAndScrollToCursor:ch]; - } - } -} - -@end - - -//============================================================ -// MAMEMemoryView class -//============================================================ - -@implementation MAMEMemoryView - -- (id)initWithFrame:(NSRect)f machine:(running_machine &)m { - NSMenu *contextMenu; - - if (!(self = [super initWithFrame:f type:DVT_MEMORY machine:m])) - return nil; - - contextMenu = [[NSMenu allocWithZone:[NSMenu menuZone]] initWithTitle:@"Memory"]; - [self insertActionItemsInMenu:contextMenu atIndex:0]; - [self setMenu:contextMenu]; - [contextMenu release]; - - return self; -} - - -- (void)dealloc { - [super dealloc]; -} - - -- (BOOL)validateMenuItem:(NSMenuItem *)item { - SEL action = [item action]; - NSInteger tag = [item tag]; - debug_view_memory *memview = downcast(view); - - if (action == @selector(showChunkSize:)) { - [item setState:((tag == memview->bytes_per_chunk()) ? NSOnState : NSOffState)]; - } else if (action == @selector(showPhysicalAddresses:)) { - [item setState:((tag == memview->physical()) ? NSOnState : NSOffState)]; - } else if (action == @selector(showReverseView:)) { - [item setState:((tag == memview->reverse()) ? NSOnState : NSOffState)]; - } else if (action == @selector(showReverseViewToggle:)) { - [item setState:(memview->reverse() ? NSOnState : NSOffState)]; - } - return YES; -} - - -- (NSSize)maximumFrameSize { - debug_view_xy max; - device_t *curcpu = debug_cpu_get_visible_cpu(*machine); - const debug_view_source *source = view->source_for_device(curcpu); - - max.x = max.y = 0; - for (const debug_view_source *source = view->source_list().first(); source != NULL; source = source->next()) - { - debug_view_xy current; - view->set_source(*source); - current = view->total_size(); - if (current.x > max.x) - max.x = current.x; - if (current.y > max.y) - max.y = current.y; - } - view->set_source(*source); - return NSMakeSize(max.x * fontWidth, max.y * fontHeight); -} - - -- (NSString *)selectedSubviewName { - const debug_view_source *source = view->source(); - if (source != NULL) - return [NSString stringWithUTF8String:source->name()]; - else - return @""; -} - - -- (int)selectedSubviewIndex { - const debug_view_source *source = view->source(); - if (source != NULL) - return view->source_list().indexof(*source); - else - return -1; -} - - -- (void)selectSubviewAtIndex:(int)index { - const int selected = view->source_list().indexof(*view->source()); - if (selected != index) { - view->set_source(*view->source_list().find(index)); - if ([[self window] firstResponder] != self) - view->set_cursor_visible(false); - } -} - - -- (void)selectSubviewForCPU:(device_t *)device { - const debug_view_source *selected = view->source(); - const debug_view_source *source = view->source_for_device(device); - if ( selected != source ) { - view->set_source(*source); - if ([[self window] firstResponder] != self) - view->set_cursor_visible(false); - } -} - - -- (NSString *)expression { - return [NSString stringWithUTF8String:downcast(view)->expression()]; -} - - -- (void)setExpression:(NSString *)exp { - downcast(view)->set_expression([exp UTF8String]); -} - - -- (IBAction)showChunkSize:(id)sender { - downcast(view)->set_bytes_per_chunk([sender tag]); -} - - -- (IBAction)showPhysicalAddresses:(id)sender { - downcast(view)->set_physical([sender tag]); -} - - -- (IBAction)showReverseView:(id)sender { - downcast(view)->set_reverse([sender tag]); -} - - -- (IBAction)showReverseViewToggle:(id)sender { - downcast(view)->set_reverse(!downcast(view)->reverse()); -} - - -- (void)insertActionItemsInMenu:(NSMenu *)menu atIndex:(NSInteger)index { - { - NSInteger tag; - for (tag = 1; tag <= 8; tag <<= 1) { - NSString *title = [NSString stringWithFormat:@"%ld-byte Chunks", (long)tag]; - NSMenuItem *chunkItem = [menu insertItemWithTitle:title - action:@selector(showChunkSize:) - keyEquivalent:[NSString stringWithFormat:@"%ld", (long)tag] - atIndex:index++]; - [chunkItem setTarget:self]; - [chunkItem setTag:tag]; - } - } - [menu insertItem:[NSMenuItem separatorItem] atIndex:index++]; - { - NSMenuItem *logicalItem = [menu insertItemWithTitle:@"Logical Addresses" - action:@selector(showPhysicalAddresses:) - keyEquivalent:@"v" - atIndex:index++]; - [logicalItem setTarget:self]; - [logicalItem setTag:FALSE]; - } - { - NSMenuItem *physicalItem = [menu insertItemWithTitle:@"Physical Addresses" - action:@selector(showPhysicalAddresses:) - keyEquivalent:@"y" - atIndex:index++]; - [physicalItem setTarget:self]; - [physicalItem setTag:TRUE]; - } - [menu insertItem:[NSMenuItem separatorItem] atIndex:index++]; - { - NSMenuItem *reverseItem = [menu insertItemWithTitle:@"Reverse View" - action:@selector(showReverseViewToggle:) - keyEquivalent:@"r" - atIndex:index++]; - [reverseItem setTarget:self]; - } - if (index < [menu numberOfItems]) - [menu insertItem:[NSMenuItem separatorItem] atIndex:index++]; -} - - -- (void)insertSubviewItemsInMenu:(NSMenu *)menu atIndex:(NSInteger)index { - for (const debug_view_source *source = view->source_list().first(); source != NULL; source = source->next()) - { - [[menu insertItemWithTitle:[NSString stringWithUTF8String:source->name()] - action:NULL - keyEquivalent:@"" - atIndex:index++] setTag:view->source_list().indexof(*source)]; - } - if (index < [menu numberOfItems]) - [menu insertItem:[NSMenuItem separatorItem] atIndex:index++]; -} - -@end - - -//============================================================ -// MAMEDisassemblyView class -//============================================================ - -@implementation MAMEDisassemblyView - -- (device_debug::breakpoint *)findBreakpointAtAddress:(offs_t)address inAddressSpace:(address_space &)space { - device_debug *cpuinfo = space.device().debug(); - device_debug::breakpoint *bp; - for (bp = cpuinfo->breakpoint_first(); (bp != NULL) && (address != bp->address()); bp = bp->next()) {} - return bp; -} - -- (void)createContextMenu { - NSMenu *contextMenu = [[NSMenu allocWithZone:[NSMenu menuZone]] initWithTitle:@"Disassembly"]; - NSMenuItem *item; - - item = [contextMenu addItemWithTitle:@"Toggle Breakpoint" - action:@selector(debugToggleBreakpoint:) - keyEquivalent:[NSString stringWithFormat:@"%C", (short)NSF9FunctionKey]]; - [item setKeyEquivalentModifierMask:0]; - [item setTarget:self]; - - item = [contextMenu addItemWithTitle:@"Disable Breakpoint" - action:@selector(debugToggleBreakpointEnable:) - keyEquivalent:[NSString stringWithFormat:@"%C", (short)NSF9FunctionKey]]; - [item setKeyEquivalentModifierMask:NSShiftKeyMask]; - [item setTarget:self]; - - [contextMenu addItem:[NSMenuItem separatorItem]]; - - item = [contextMenu addItemWithTitle:@"Run to Cursor" - action:@selector(debugRunToCursor:) - keyEquivalent:[NSString stringWithFormat:@"%C", (short)NSF4FunctionKey]]; - [item setKeyEquivalentModifierMask:0]; - [item setTarget:self]; - - [contextMenu addItem:[NSMenuItem separatorItem]]; - - item = [contextMenu addItemWithTitle:@"Raw Opcodes" - action:@selector(showRightColumn:) - keyEquivalent:@"r"]; - [item setTarget:self]; - [item setTag:DASM_RIGHTCOL_RAW]; - - item = [contextMenu addItemWithTitle:@"Encrypted Opcodes" - action:@selector(showRightColumn:) - keyEquivalent:@"e"]; - [item setTarget:self]; - [item setTag:DASM_RIGHTCOL_ENCRYPTED]; - - item = [contextMenu addItemWithTitle:@"Comments" - action:@selector(showRightColumn:) - keyEquivalent:@"n"]; - [item setTarget:self]; - [item setTag:DASM_RIGHTCOL_COMMENTS]; - - [self setMenu:contextMenu]; - [contextMenu release]; -} - - -- (id)initWithFrame:(NSRect)f machine:(running_machine &)m useConsole:(BOOL)uc { - if (!(self = [super initWithFrame:f type:DVT_DISASSEMBLY machine:m])) - return nil; - useConsole = uc; - [self createContextMenu]; - return self; -} - - -- (void)dealloc { - [super dealloc]; -} - - -- (BOOL)validateMenuItem:(NSMenuItem *)item { - SEL action = [item action]; - BOOL inContextMenu = ([item menu] == [self menu]); - BOOL haveCursor = NO, isCurrent = NO; - device_debug::breakpoint *breakpoint = NULL; - - if (view->cursor_visible()) { - if (debug_cpu_get_visible_cpu(*machine) == view->source()->device()) { - isCurrent = YES; - if (!useConsole || isCurrent) { - offs_t address = downcast(view)->selected_address(); - haveCursor = YES; - breakpoint = [self findBreakpointAtAddress:address inAddressSpace:downcast(view->source())->space()]; - } - } - } - - if (action == @selector(debugToggleBreakpoint:)) { - if (haveCursor) { - if (breakpoint != NULL) { - if (inContextMenu) - [item setTitle:@"Clear Breakpoint"]; - else - [item setTitle:@"Clear Breakpoint at Cursor"]; - } else { - if (inContextMenu) - [item setTitle:@"Set Breakpoint"]; - else - [item setTitle:@"Set Breakpoint at Cursor"]; - } - } else { - if (inContextMenu) - [item setTitle:@"Toggle Breakpoint"]; - else - [item setTitle:@"Toggle Breakpoint at Cursor"]; - } - return haveCursor; - } else if (action == @selector(debugToggleBreakpointEnable:)) { - if ((breakpoint != NULL) && !breakpoint->enabled()) { - if (inContextMenu) - [item setTitle:@"Enable Breakpoint"]; - else - [item setTitle:@"Enable Breakpoint at Cursor"]; - } else { - if (inContextMenu) - [item setTitle:@"Disable Breakpoint"]; - else - [item setTitle:@"Disable Breakpoint at Cursor"]; - } - return (breakpoint != NULL); - } else if (action == @selector(debugRunToCursor:)) { - return isCurrent; - } else if (action == @selector(showRightColumn:)) { - [item setState:((downcast(view)->right_column() == [item tag]) ? NSOnState : NSOffState)]; - return YES; - } else { - return YES; - } -} - - -- (NSSize)maximumFrameSize { - debug_view_xy max; - device_t *curcpu = debug_cpu_get_visible_cpu(*machine); - const debug_view_source *source = view->source_for_device(curcpu); - - max.x = max.y = 0; - for (const debug_view_source *source = view->source_list().first(); source != NULL; source = source->next()) - { - debug_view_xy current; - view->set_source(*source); - current = view->total_size(); - if (current.x > max.x) - max.x = current.x; - if (current.y > max.y) - max.y = current.y; - } - view->set_source(*source); - return NSMakeSize(max.x * fontWidth, max.y * fontHeight); -} - - -- (NSString *)selectedSubviewName { - const debug_view_source *source = view->source(); - if (source != NULL) - return [NSString stringWithUTF8String:source->name()]; - else - return @""; -} - - -- (int)selectedSubviewIndex { - const debug_view_source *source = view->source(); - if (source != NULL) - return view->source_list().indexof(*source); - else - return -1; -} - - -- (void)selectSubviewAtIndex:(int)index { - const int selected = view->source_list().indexof(*view->source()); - if (selected != index) { - view->set_source(*view->source_list().find(index)); - if ([[self window] firstResponder] != self) - view->set_cursor_visible(false); - } -} - - -- (void)selectSubviewForCPU:(device_t *)device { - const debug_view_source *selected = view->source(); - const debug_view_source *source = view->source_for_device(device); - if ( selected != source ) { - view->set_source(*source); - if ([[self window] firstResponder] != self) - view->set_cursor_visible(false); - } -} - - -- (NSString *)expression { - return [NSString stringWithUTF8String:downcast(view)->expression()]; -} - - -- (void)setExpression:(NSString *)exp { - downcast(view)->set_expression([exp UTF8String]); -} - - -- (IBAction)debugToggleBreakpoint:(id)sender { - if (view->cursor_visible()) { - address_space &space = downcast(view->source())->space(); - if (!useConsole || (debug_cpu_get_visible_cpu(*machine) == &space.device())) { - offs_t address = downcast(view)->selected_address(); - device_debug::breakpoint *bp = [self findBreakpointAtAddress:address inAddressSpace:space]; - - // if it doesn't exist, add a new one - if (useConsole) { - NSString *command; - if (bp == NULL) - command = [NSString stringWithFormat:@"bpset %lX", (unsigned long)address]; - else - command = [NSString stringWithFormat:@"bpclear %X", (unsigned)bp->index()]; - debug_console_execute_command(*machine, [command UTF8String], 1); - } else { - if (bp == NULL) - space.device().debug()->breakpoint_set(address, NULL, NULL); - else - space.device().debug()->breakpoint_clear(bp->index()); - } - } - } -} - - -- (IBAction)debugToggleBreakpointEnable:(id)sender { - if (view->cursor_visible()) { - address_space &space = downcast(view->source())->space(); - if (!useConsole || (debug_cpu_get_visible_cpu(*machine) == &space.device())) { - offs_t address = downcast(view)->selected_address(); - device_debug::breakpoint *bp = [self findBreakpointAtAddress:address inAddressSpace:space]; - - if (bp != NULL) { - NSString *command; - if (useConsole) { - if (bp->enabled()) - command = [NSString stringWithFormat:@"bpdisable %X", (unsigned)bp->index()]; - else - command = [NSString stringWithFormat:@"bpenable %X", (unsigned)bp->index()]; - debug_console_execute_command(*machine, [command UTF8String], 1); - } else { - space.device().debug()->breakpoint_enable(bp->index(), !bp->enabled()); - } - } - } - } -} - - -- (IBAction)debugRunToCursor:(id)sender { - if (view->cursor_visible()) { - address_space &space = downcast(view->source())->space(); - if (debug_cpu_get_visible_cpu(*machine) == &space.device()) { - offs_t address = downcast(view)->selected_address(); - if (useConsole) { - NSString *command = [NSString stringWithFormat:@"go 0x%lX", (unsigned long)address]; - debug_console_execute_command(*machine, [command UTF8String], 1); - } else { - debug_cpu_get_visible_cpu(*machine)->debug()->go(address); - } - } - } -} - - -- (IBAction)showRightColumn:(id)sender { - downcast(view)->set_right_column((disasm_right_column) [sender tag]); -} - - -- (void)insertActionItemsInMenu:(NSMenu *)menu atIndex:(NSInteger)index { - { - NSMenuItem *breakItem = [menu insertItemWithTitle:@"Toggle Breakpoint at Cursor" - action:@selector(debugToggleBreakpoint:) - keyEquivalent:[NSString stringWithFormat:@"%C", (short)NSF9FunctionKey] - atIndex:index++]; - [breakItem setKeyEquivalentModifierMask:0]; - [breakItem setTarget:self]; - } - { - NSMenuItem *disableItem = [menu insertItemWithTitle:@"Disable Breakpoint at Cursor" - action:@selector(debugToggleBreakpointEnable:) - keyEquivalent:[NSString stringWithFormat:@"%C", (short)NSF9FunctionKey] - atIndex:index++]; - [disableItem setKeyEquivalentModifierMask:NSShiftKeyMask]; - [disableItem setAlternate:YES]; - [disableItem setTarget:self]; - } - { - NSMenu *runMenu = [[menu itemWithTitle:@"Run"] submenu]; - NSMenuItem *runItem; - if (runMenu != nil) { - runItem = [runMenu addItemWithTitle:@"to Cursor" - action:@selector(debugRunToCursor:) - keyEquivalent:[NSString stringWithFormat:@"%C", (short)NSF4FunctionKey]]; - } else { - runItem = [menu insertItemWithTitle:@"Run to Cursor" - action:@selector(debugRunToCursor:) - keyEquivalent:[NSString stringWithFormat:@"%C", (short)NSF4FunctionKey] - atIndex:index++]; - } - [runItem setKeyEquivalentModifierMask:0]; - [runItem setTarget:self]; - } - [menu insertItem:[NSMenuItem separatorItem] atIndex:index++]; - { - NSMenuItem *rawItem = [menu insertItemWithTitle:@"Show Raw Opcodes" - action:@selector(showRightColumn:) - keyEquivalent:@"r" - atIndex:index++]; - [rawItem setTarget:self]; - [rawItem setTag:DASM_RIGHTCOL_RAW]; - } - { - NSMenuItem *encItem = [menu insertItemWithTitle:@"Show Encrypted Opcodes" - action:@selector(showRightColumn:) - keyEquivalent:@"e" - atIndex:index++]; - [encItem setTarget:self]; - [encItem setTag:DASM_RIGHTCOL_ENCRYPTED]; - } - { - NSMenuItem *commentsItem = [menu insertItemWithTitle:@"Show Comments" - action:@selector(showRightColumn:) - keyEquivalent:@"n" - atIndex:index++]; - [commentsItem setTarget:self]; - [commentsItem setTag:DASM_RIGHTCOL_COMMENTS]; - } - if (index < [menu numberOfItems]) - [menu insertItem:[NSMenuItem separatorItem] atIndex:index++]; -} - - -- (void)insertSubviewItemsInMenu:(NSMenu *)menu atIndex:(NSInteger)index { - for (const debug_view_source *source = view->source_list().first(); source != NULL; source = source->next()) - { - [[menu insertItemWithTitle:[NSString stringWithUTF8String:source->name()] - action:NULL - keyEquivalent:@"" - atIndex:index++] setTag:view->source_list().indexof(*source)]; - } - if (index < [menu numberOfItems]) - [menu insertItem:[NSMenuItem separatorItem] atIndex:index++]; -} - -@end - - -//============================================================ -// MAMERegistersView class -//============================================================ - -@implementation MAMERegistersView - -- (id)initWithFrame:(NSRect)f machine:(running_machine &)m { - if (!(self = [super initWithFrame:f type:DVT_STATE machine:m])) - return nil; - return self; -} - - -- (void)dealloc { - [super dealloc]; -} - - -- (NSSize)maximumFrameSize { - debug_view_xy max; - device_t *curcpu = debug_cpu_get_visible_cpu(*machine); - const debug_view_source *source = view->source_for_device(curcpu); - - - max.x = max.y = 0; - for (const debug_view_source *source = view->source_list().first(); source != NULL; source = source->next()) - { - debug_view_xy current; - view->set_source(*source); - current = view->total_size(); - if (current.x > max.x) - max.x = current.x; - if (current.y > max.y) - max.y = current.y; - } - view->set_source(*source); - return NSMakeSize(max.x * fontWidth, max.y * fontHeight); -} - - -- (NSString *)selectedSubviewName { - return @""; -} - - -- (int)selectedSubviewIndex { - return -1; -} - - -- (void)selectSubviewAtIndex:(int)index { -} - - -- (void)selectSubviewForCPU:(device_t *)device { - //dv = get_view(dmain, DVT_STATE); - view->set_source(*view->source_for_device(device)); -} - -@end - - -//============================================================ -// MAMEConsoleView class -//============================================================ - -@implementation MAMEConsoleView - -- (id)initWithFrame:(NSRect)f machine:(running_machine &)m { - if (!(self = [super initWithFrame:f type:DVT_CONSOLE machine:m])) - return nil; - return self; -} - - -- (void)dealloc { - [super dealloc]; -} - -@end - - -//============================================================ -// MAMEErrorLogView class -//============================================================ - -@implementation MAMEErrorLogView - -- (id)initWithFrame:(NSRect)f machine:(running_machine &)m { - if (!(self = [super initWithFrame:f type:DVT_LOG machine:m])) - return nil; - return self; -} - - -- (void)dealloc { - [super dealloc]; -} - -@end - - -//============================================================ -// MAMEDebugWindowHandler class -//============================================================ - -@implementation MAMEDebugWindowHandler - -+ (void)addCommonActionItems:(NSMenu *)menu { - { - NSMenuItem *runParentItem = [menu addItemWithTitle:@"Run" - action:@selector(debugRun:) - keyEquivalent:[NSString stringWithFormat:@"%C", (short)NSF5FunctionKey]]; - NSMenu *runMenu = [[NSMenu allocWithZone:[NSMenu menuZone]] initWithTitle:@"Run"]; - [runParentItem setSubmenu:runMenu]; - [runMenu release]; - [runParentItem setKeyEquivalentModifierMask:0]; - [[runMenu addItemWithTitle:@"and Hide Debugger" - action:@selector(debugRunAndHide:) - keyEquivalent:[NSString stringWithFormat:@"%C", (short)NSF12FunctionKey]] - setKeyEquivalentModifierMask:0]; - [[runMenu addItemWithTitle:@"to Next CPU" - action:@selector(debugRunToNextCPU:) - keyEquivalent:[NSString stringWithFormat:@"%C", (short)NSF6FunctionKey]] - setKeyEquivalentModifierMask:0]; - [[runMenu addItemWithTitle:@"until Next Interrupt on Current CPU" - action:@selector(debugRunToNextInterrupt:) - keyEquivalent:[NSString stringWithFormat:@"%C", (short)NSF7FunctionKey]] - setKeyEquivalentModifierMask:0]; - [[runMenu addItemWithTitle:@"until Next VBLANK" - action:@selector(debugRunToNextVBLANK:) - keyEquivalent:[NSString stringWithFormat:@"%C", (short)NSF8FunctionKey]] - setKeyEquivalentModifierMask:0]; - } - { - NSMenuItem *stepParentItem = [menu addItemWithTitle:@"Step" action:NULL keyEquivalent:@""]; - NSMenu *stepMenu = [[NSMenu allocWithZone:[NSMenu menuZone]] initWithTitle:@"Step"]; - [stepParentItem setSubmenu:stepMenu]; - [stepMenu release]; - [[stepMenu addItemWithTitle:@"Into" - action:@selector(debugStepInto:) - keyEquivalent:[NSString stringWithFormat:@"%C", (short)NSF11FunctionKey]] - setKeyEquivalentModifierMask:0]; - [[stepMenu addItemWithTitle:@"Over" - action:@selector(debugStepOver:) - keyEquivalent:[NSString stringWithFormat:@"%C", (short)NSF10FunctionKey]] - setKeyEquivalentModifierMask:0]; - [[stepMenu addItemWithTitle:@"Out" - action:@selector(debugStepOut:) - keyEquivalent:[NSString stringWithFormat:@"%C", (short)NSF10FunctionKey]] - setKeyEquivalentModifierMask:NSShiftKeyMask]; - } - { - NSMenuItem *resetParentItem = [menu addItemWithTitle:@"Reset" action:NULL keyEquivalent:@""]; - NSMenu *resetMenu = [[NSMenu allocWithZone:[NSMenu menuZone]] initWithTitle:@"Reset"]; - [resetParentItem setSubmenu:resetMenu]; - [resetMenu release]; - [[resetMenu addItemWithTitle:@"Soft" - action:@selector(debugSoftReset:) - keyEquivalent:[NSString stringWithFormat:@"%C", (short)NSF3FunctionKey]] - setKeyEquivalentModifierMask:0]; - [[resetMenu addItemWithTitle:@"Hard" - action:@selector(debugHardReset:) - keyEquivalent:[NSString stringWithFormat:@"%C", (short)NSF3FunctionKey]] - setKeyEquivalentModifierMask:NSShiftKeyMask]; - } - [menu addItem:[NSMenuItem separatorItem]]; - { - NSMenuItem *newParentItem = [menu addItemWithTitle:@"New" action:NULL keyEquivalent:@""]; - NSMenu *newMenu = [[NSMenu allocWithZone:[NSMenu menuZone]] initWithTitle:@"New"]; - [newParentItem setSubmenu:newMenu]; - [newMenu release]; - [newMenu addItemWithTitle:@"Memory Window" - action:@selector(debugNewMemoryWindow:) - keyEquivalent:@"d"]; - [newMenu addItemWithTitle:@"Disassembly Window" - action:@selector(debugNewDisassemblyWindow:) - keyEquivalent:@"a"]; - [newMenu addItemWithTitle:@"Error Log Window" - action:@selector(debugNewErrorLogWindow:) - keyEquivalent:@"l"]; - } - [menu addItem:[NSMenuItem separatorItem]]; - [menu addItemWithTitle:@"Close Window" action:@selector(performClose:) keyEquivalent:@"w"]; - [menu addItemWithTitle:@"Exit" action:@selector(debugExit:) keyEquivalent:@""]; -} - - -+ (NSPopUpButton *)newActionButtonWithFrame:(NSRect)frame { - NSPopUpButton *actionButton = [[NSPopUpButton alloc] initWithFrame:frame pullsDown:YES]; - [actionButton setTitle:@""]; - [actionButton addItemWithTitle:@""]; - [actionButton setBezelStyle:NSShadowlessSquareBezelStyle]; - [actionButton setFocusRingType:NSFocusRingTypeNone]; - [[actionButton cell] setArrowPosition:NSPopUpArrowAtCenter]; - [[self class] addCommonActionItems:[actionButton menu]]; - return actionButton; -} - - -- (id)initWithMachine:(running_machine &)m title:(NSString *)t { - if (!(self = [super init])) - return nil; - - window = [[NSWindow alloc] initWithContentRect:NSMakeRect(0, 0, 320, 240) - styleMask:(NSTitledWindowMask | - NSClosableWindowMask | - NSMiniaturizableWindowMask | - NSResizableWindowMask) - backing:NSBackingStoreBuffered - defer:YES]; - [window setReleasedWhenClosed:NO]; - [window setDelegate:self]; - [window setTitle:t]; - [window setContentMinSize:NSMakeSize(320, 240)]; - - [[NSNotificationCenter defaultCenter] addObserver:self - selector:@selector(showDebugger:) - name:MAMEShowDebuggerNotification - object:nil]; - [[NSNotificationCenter defaultCenter] addObserver:self - selector:@selector(hideDebugger:) - name:MAMEHideDebuggerNotification - object:nil]; - - machine = &m; - - return self; -} - - -- (void)dealloc { - [[NSNotificationCenter defaultCenter] removeObserver:self]; - - if (window != nil) - [window release]; - - [super dealloc]; -} - - -- (void)activate { - [window makeKeyAndOrderFront:self]; -} - - -- (IBAction)debugRun:(id)sender { - debug_cpu_get_visible_cpu(*machine)->debug()->go(); -} - - -- (IBAction)debugRunAndHide:(id)sender { - [[NSNotificationCenter defaultCenter] postNotificationName:MAMEHideDebuggerNotification object:self]; - debug_cpu_get_visible_cpu(*machine)->debug()->go(); -} - - -- (IBAction)debugRunToNextCPU:(id)sender { - debug_cpu_get_visible_cpu(*machine)->debug()->go_next_device(); -} - - -- (IBAction)debugRunToNextInterrupt:(id)sender { - debug_cpu_get_visible_cpu(*machine)->debug()->go_interrupt(); -} - - -- (IBAction)debugRunToNextVBLANK:(id)sender { - debug_cpu_get_visible_cpu(*machine)->debug()->go_vblank(); -} - - -- (IBAction)debugStepInto:(id)sender { - debug_cpu_get_visible_cpu(*machine)->debug()->single_step(); -} - - -- (IBAction)debugStepOver:(id)sender { - debug_cpu_get_visible_cpu(*machine)->debug()->single_step_over(); -} - - -- (IBAction)debugStepOut:(id)sender { - debug_cpu_get_visible_cpu(*machine)->debug()->single_step_out(); -} - - -- (IBAction)debugSoftReset:(id)sender { - machine->schedule_soft_reset(); - debug_cpu_get_visible_cpu(*machine)->debug()->go(); -} - - -- (IBAction)debugHardReset:(id)sender { - machine->schedule_hard_reset(); -} - - -- (IBAction)debugExit:(id)sender { - machine->schedule_exit(); -} - - -- (void)showDebugger:(NSNotification *)notification { - device_t *device = (device_t *) [[[notification userInfo] objectForKey:@"MAMEDebugDevice"] pointerValue]; - if (&device->machine() == machine) { - if (![window isVisible] && ![window isMiniaturized]) - [window orderFront:self]; - } -} - - -- (void)hideDebugger:(NSNotification *)notification { - [window orderOut:self]; -} - -@end - - - -//============================================================ -// MAMEDebugConsole class -//============================================================ - -@implementation MAMEDebugConsole - -- (id)initWithMachine:(running_machine &)m { - NSSplitView *regSplit, *dasmSplit; - NSScrollView *regScroll, *dasmScroll, *consoleScroll; - NSView *consoleContainer; - NSPopUpButton *actionButton; - NSRect rct; - - // initialise superclass - if (!(self = [super initWithMachine:m title:@"Debug"])) - return nil; - history = [[MAMEDebugCommandHistory alloc] init]; - auxiliaryWindows = [[NSMutableArray alloc] init]; - - // create the register view - regView = [[MAMERegistersView alloc] initWithFrame:NSMakeRect(0, 0, 100, 100) machine:*machine]; - regScroll = [[NSScrollView alloc] initWithFrame:NSMakeRect(0, 0, 100, 100)]; - [regScroll setDrawsBackground:YES]; - [regScroll setHasHorizontalScroller:YES]; - [regScroll setHasVerticalScroller:YES]; - [regScroll setAutohidesScrollers:YES]; - [regScroll setBorderType:NSBezelBorder]; - [regScroll setDocumentView:regView]; - [regView release]; - - // create the disassembly view - dasmView = [[MAMEDisassemblyView alloc] initWithFrame:NSMakeRect(0, 0, 100, 100) - machine:*machine - useConsole:YES]; - [dasmView setExpression:@"curpc"]; - dasmScroll = [[NSScrollView alloc] initWithFrame:NSMakeRect(0, 0, 100, 100)]; - [dasmScroll setDrawsBackground:YES]; - [dasmScroll setHasHorizontalScroller:YES]; - [dasmScroll setHasVerticalScroller:YES]; - [dasmScroll setAutohidesScrollers:YES]; - [dasmScroll setBorderType:NSBezelBorder]; - [dasmScroll setDocumentView:dasmView]; - [dasmView release]; - - // create the console view - consoleView = [[MAMEConsoleView alloc] initWithFrame:NSMakeRect(0, 0, 100, 100) machine:*machine]; - consoleScroll = [[NSScrollView alloc] initWithFrame:NSMakeRect(0, 0, 100, 100)]; - [consoleScroll setDrawsBackground:YES]; - [consoleScroll setAutoresizingMask:(NSViewWidthSizable | NSViewHeightSizable)]; - [consoleScroll setHasHorizontalScroller:YES]; - [consoleScroll setHasVerticalScroller:YES]; - [consoleScroll setAutohidesScrollers:YES]; - [consoleScroll setBorderType:NSBezelBorder]; - [consoleScroll setDocumentView:consoleView]; - [consoleView release]; - - // create the command field - commandField = [[NSTextField alloc] initWithFrame:NSMakeRect(0, 0, 100, 19)]; - [commandField setAutoresizingMask:(NSViewWidthSizable | NSViewMaxYMargin)]; - [commandField setFont:[[MAMEDebugView class] defaultFont]]; - [commandField setFocusRingType:NSFocusRingTypeNone]; - [commandField setTarget:self]; - [commandField setAction:@selector(doCommand:)]; - [commandField setDelegate:self]; - rct = [commandField frame]; - [commandField setFrame:NSMakeRect(rct.size.height, 0, rct.size.width - rct.size.height, rct.size.height)]; - - // create the action pull-down button - actionButton = [[self class] newActionButtonWithFrame:NSMakeRect(0, 0, rct.size.height, rct.size.height)]; - [actionButton setAutoresizingMask:(NSViewMaxXMargin | NSViewMaxYMargin)]; - [dasmView insertActionItemsInMenu:[actionButton menu] atIndex:1]; - - // create the container for the console and command input field - consoleContainer = [[NSView alloc] initWithFrame:NSMakeRect(0, 0, 100, 100)]; - [consoleScroll setFrame:NSMakeRect(0, - rct.size.height, - 100, - [consoleContainer bounds].size.height - rct.size.height)]; - [consoleContainer addSubview:consoleScroll]; - [consoleContainer addSubview:commandField]; - [consoleContainer addSubview:actionButton]; - [consoleScroll release]; - [commandField release]; - [actionButton release]; - - // create the split between the disassembly and the console - dasmSplit = [[NSSplitView alloc] initWithFrame:NSMakeRect(0, 0, 100, 100)]; - [dasmSplit setDelegate:self]; - [dasmSplit setVertical:NO]; - [dasmSplit addSubview:dasmScroll]; - [dasmSplit addSubview:consoleContainer]; - [dasmScroll release]; - [consoleContainer release]; - - // create the split between the registers and the console - regSplit = [[NSSplitView alloc] initWithFrame:NSMakeRect(0, 0, 100, 100)]; - [regSplit setDelegate:self]; - [regSplit setAutoresizingMask:(NSViewWidthSizable | NSViewHeightSizable)]; - [regSplit setVertical:YES]; - [regSplit addSubview:regScroll]; - [regSplit addSubview:dasmSplit]; - [regScroll release]; - [dasmSplit release]; - - // put the split views in the window and get them into a half-reasonable state - [window setContentView:regSplit]; - [regSplit release]; - [regSplit adjustSubviews]; - [dasmSplit adjustSubviews]; - - // keyboard focus should start on the command field - [window makeFirstResponder:commandField]; - - // calculate the optimal size for everything - { - NSRect available = [[NSScreen mainScreen] visibleFrame]; - NSRect windowFrame = [window frame]; - NSSize regCurrent = [regScroll frame].size; - NSSize regSize = [NSScrollView frameSizeForContentSize:[regView maximumFrameSize] - hasHorizontalScroller:YES - hasVerticalScroller:YES - borderType:[regScroll borderType]]; - NSSize dasmCurrent = [dasmScroll frame].size; - NSSize dasmSize = [NSScrollView frameSizeForContentSize:[dasmView maximumFrameSize] - hasHorizontalScroller:YES - hasVerticalScroller:YES - borderType:[dasmScroll borderType]]; - NSSize consoleCurrent = [consoleContainer frame].size; - NSSize consoleSize = [NSScrollView frameSizeForContentSize:[consoleView maximumFrameSize] - hasHorizontalScroller:YES - hasVerticalScroller:YES - borderType:[consoleScroll borderType]]; - NSSize adjustment; - NSRect lhsFrame, rhsFrame; - - consoleSize.width += consoleCurrent.width - [consoleScroll frame].size.width; - consoleSize.height += consoleCurrent.height - [consoleScroll frame].size.height; - adjustment.width = regSize.width - regCurrent.width; - adjustment.height = regSize.height - regCurrent.height; - adjustment.width += MAX(dasmSize.width - dasmCurrent.width, consoleSize.width - consoleCurrent.width); - - windowFrame.size.width += adjustment.width; - windowFrame.size.height += adjustment.height; // not used - better to go for fixed height - windowFrame.size.height = MIN(512.0, available.size.height); - windowFrame.size.width = MIN(windowFrame.size.width, available.size.width); - windowFrame.origin.x = available.origin.x + available.size.width - windowFrame.size.width; - windowFrame.origin.y = available.origin.y; - [window setFrame:windowFrame display:YES]; - - lhsFrame = [regScroll frame]; - rhsFrame = [dasmSplit frame]; - adjustment.width = MIN(regSize.width, ([regSplit frame].size.width - [regSplit dividerThickness]) / 2); - rhsFrame.origin.x -= lhsFrame.size.width - adjustment.width; - rhsFrame.size.width += lhsFrame.size.width - adjustment.width; - lhsFrame.size.width = adjustment.width; - [regScroll setFrame:lhsFrame]; - [dasmSplit setFrame:rhsFrame]; - } - - // select the current processor - [self setCPU:machine->firstcpu]; - - [[NSNotificationCenter defaultCenter] addObserver:self - selector:@selector(auxiliaryWindowWillClose:) - name:MAMEAuxiliaryDebugWindowWillCloseNotification - object:nil]; - - // don't forget the return value - return self; -} - - -- (void)dealloc { - [[NSNotificationCenter defaultCenter] removeObserver:self]; - - if (history != nil) - [history release]; - if (auxiliaryWindows != nil) - [auxiliaryWindows release]; - - [super dealloc]; -} - - -- (void)setCPU:(device_t *)device { - [regView selectSubviewForCPU:device]; - [dasmView selectSubviewForCPU:device]; - [window setTitle:[NSString stringWithFormat:@"Debug: %s - %s '%s'", - device->machine().system().name, - device->name(), - device->tag()]]; -} - - -- (IBAction)doCommand:(id)sender { - NSString *command = [sender stringValue]; - if ([command length] == 0) { - debug_cpu_get_visible_cpu(*machine)->debug()->single_step(); - } else { - debug_console_execute_command(*machine, [command UTF8String], 1); - [history add:command]; - } - [sender setStringValue:@""]; -} - - -- (IBAction)debugNewMemoryWindow:(id)sender { - MAMEMemoryViewer *win = [[MAMEMemoryViewer alloc] initWithMachine:*machine console:self]; - [auxiliaryWindows addObject:win]; - [win release]; - [win activate]; -} - - -- (IBAction)debugNewDisassemblyWindow:(id)sender { - MAMEDisassemblyViewer *win = [[MAMEDisassemblyViewer alloc] initWithMachine:*machine console:self]; - [auxiliaryWindows addObject:win]; - [win release]; - [win activate]; -} - - -- (IBAction)debugNewErrorLogWindow:(id)sender { - MAMEErrorLogViewer *win = [[MAMEErrorLogViewer alloc] initWithMachine:*machine console:self]; - [auxiliaryWindows addObject:win]; - [win release]; - [win activate]; -} - - -- (void)showDebugger:(NSNotification *)notification { - device_t *device = (device_t * )[[[notification userInfo] objectForKey:@"MAMEDebugDevice"] pointerValue]; - if (&device->machine() == machine) { - [self setCPU:device]; - [window makeKeyAndOrderFront:self]; - } -} - - -- (void)auxiliaryWindowWillClose:(NSNotification *)notification { - [auxiliaryWindows removeObjectIdenticalTo:[notification object]]; -} - - -- (BOOL)control:(NSControl *)control textView:(NSTextView *)textView doCommandBySelector:(SEL)command { - if (control == commandField) { - if (command == @selector(cancelOperation:)) { - [commandField setStringValue:@""]; - [history reset]; - return YES; - } else if (command == @selector(moveUp:)) { - NSString *hist = [history previous:[commandField stringValue]]; - if (hist != nil) { - [commandField setStringValue:hist]; - [commandField selectText:self]; - [(NSText *)[window firstResponder] setSelectedRange:NSMakeRange([hist length], 0)]; - } - return YES; - } else if (command == @selector(moveDown:)) { - NSString *hist = [history next:[commandField stringValue]]; - if (hist != nil) { - [commandField setStringValue:hist]; - [commandField selectText:self]; - [(NSText *)[window firstResponder] setSelectedRange:NSMakeRange([hist length], 0)]; - } - return YES; - } - } - return NO; -} - - -- (void)windowWillClose:(NSNotification *)notification { - if ([notification object] != window) - return; - [[NSNotificationCenter defaultCenter] postNotificationName:MAMEHideDebuggerNotification object:self]; - debug_cpu_get_visible_cpu(*machine)->debug()->go(); -} - - -- (CGFloat)splitView:(NSSplitView *)sender constrainMinCoordinate:(CGFloat)min ofSubviewAt:(NSInteger)offs { - return (min < 100) ? 100 : min; -} - - -- (CGFloat)splitView:(NSSplitView *)sender constrainMaxCoordinate:(CGFloat)max ofSubviewAt:(NSInteger)offs { - NSSize sz = [sender bounds].size; - CGFloat allowed = ([sender isVertical] ? sz.width : sz.height) - 100 - [sender dividerThickness]; - return (max > allowed) ? allowed : max; -} - - -- (BOOL)splitView:(NSSplitView *)sender canCollapseSubview:(NSView *)subview { - // allow registers or disassembly to be collapsed, but not console - return [[sender subviews] indexOfObjectIdenticalTo:subview] == 0; -} - - -- (void)splitView:(NSSplitView *)sender resizeSubviewsWithOldSize:(NSSize)oldSize { - // This can only deal with a single split, but that's all we use, anyway - NSRect first, second; - [sender adjustSubviews]; - first = [[[sender subviews] objectAtIndex:0] frame]; - second = [[[sender subviews] objectAtIndex:1] frame]; - if ([sender isVertical]) { - if (first.size.width < 100) { - CGFloat diff = 100 - first.size.width; - first.size.width = 100; - second.origin.x += diff; - second.size.width -= diff; - } else if (second.size.width < 100) { - CGFloat diff = 100 - second.size.width; - second.size.width = 100; - second.origin.x -= diff; - first.size.width -= diff; - } - } else { - if (first.size.height < 100) { - CGFloat diff = 100 - first.size.height; - first.size.height = 100; - second.origin.y += diff; - second.size.height -= diff; - } else if (second.size.height < 100) { - CGFloat diff = 100 - second.size.height; - second.size.height = 100; - second.origin.y -= diff; - first.size.height -= diff; - } - } - [[[sender subviews] objectAtIndex:0] setFrame:first]; - [[[sender subviews] objectAtIndex:1] setFrame:second]; -} - -@end - - -//============================================================ -// MAMEAuxiliaryDebugWindowHandler class -//============================================================ - -@implementation MAMEAuxiliaryDebugWindowHandler - -+ (void)cascadeWindow:(NSWindow *)window { - static NSPoint lastPosition = { 0, 0 }; - if (NSEqualPoints(lastPosition, NSZeroPoint)) { - NSRect available = [[NSScreen mainScreen] visibleFrame]; - lastPosition = NSMakePoint(available.origin.x + 12, available.origin.y + available.size.height - 8); - } - lastPosition = [window cascadeTopLeftFromPoint:lastPosition]; -} - - -- (id)initWithMachine:(running_machine &)m title:(NSString *)t console:(MAMEDebugConsole *)c { - if (!(self = [super initWithMachine:m title:t])) - return nil; - console = c; - return self; -} - - -- (void)dealloc { - [super dealloc]; -} - - -- (IBAction)debugNewMemoryWindow:(id)sender { - [console debugNewMemoryWindow:sender]; -} - - -- (IBAction)debugNewDisassemblyWindow:(id)sender { - [console debugNewDisassemblyWindow:sender]; -} - - -- (IBAction)debugNewErrorLogWindow:(id)sender { - [console debugNewErrorLogWindow:sender]; -} - - -- (void)windowWillClose:(NSNotification *)notification { - [[NSNotificationCenter defaultCenter] postNotificationName:MAMEAuxiliaryDebugWindowWillCloseNotification - object:self]; -} - -- (void)cascadeWindowWithDesiredSize:(NSSize)desired forView:(NSView *)view { - NSRect available = [[NSScreen mainScreen] visibleFrame]; - NSRect windowFrame = [window frame]; - NSSize current = [view frame].size; - - desired.width -= current.width; - desired.height -= current.height; - - windowFrame.size.width += desired.width; - windowFrame.size.height += desired.height; - windowFrame.size.height = MIN(MIN(windowFrame.size.height, 240), available.size.height); - windowFrame.size.width = MIN(windowFrame.size.width, available.size.width); - windowFrame.origin.x = available.origin.x + available.size.width - windowFrame.size.width; - windowFrame.origin.y = available.origin.y; - [window setFrame:windowFrame display:YES]; - [[self class] cascadeWindow:window]; - - windowFrame = [[window contentView] frame]; - desired = [window contentMinSize]; - [window setContentMinSize:NSMakeSize(MIN(windowFrame.size.width, desired.width), - MIN(windowFrame.size.height, desired.height))]; -} - -@end - - -//============================================================ -// MAMEExpreesionAuxiliaryDebugWindowHandler class -//============================================================ - -@implementation MAMEExpressionAuxiliaryDebugWindowHandler - -- (id)initWithMachine:(running_machine &)m title:(NSString *)t console:(MAMEDebugConsole *)c { - if (!(self = [super initWithMachine:m title:t console:c])) - return nil; - history = [[MAMEDebugCommandHistory alloc] init]; - return self; -} - - -- (void)dealloc { - if (history != nil) - [history release]; - [super dealloc]; -} - - -- (id )documentView { - return nil; -} - - -- (IBAction)doExpression:(id)sender { - NSString *expr = [sender stringValue]; - if ([expr length] > 0) { - [history add:expr]; - [[self documentView] setExpression:expr]; - } else { - [sender setStringValue:[[self documentView] expression]]; - [history reset]; - } - [sender selectText:self]; -} - - -- (BOOL)control:(NSControl *)control textView:(NSTextView *)textView doCommandBySelector:(SEL)command { - if (control == expressionField) { - if (command == @selector(cancelOperation:)) { - [history reset]; - [expressionField setStringValue:[[self documentView] expression]]; - [expressionField selectText:self]; - return YES; - } else if (command == @selector(moveUp:)) { - NSString *hist = [history previous:[expressionField stringValue]]; - if (hist != nil) { - [expressionField setStringValue:hist]; - [expressionField selectText:self]; - } - return YES; - } else if (command == @selector(moveDown:)) { - NSString *hist = [history next:[expressionField stringValue]]; - if (hist != nil) { - [expressionField setStringValue:hist]; - [expressionField selectText:self]; - } - return YES; - } - } - return NO; -} - -@end - - -//============================================================ -// MAMEMemoryViewer class -//============================================================ - -@implementation MAMEMemoryViewer - -- (id)initWithMachine:(running_machine &)m console:(MAMEDebugConsole *)c { - NSScrollView *memoryScroll; - NSView *expressionContainer; - NSPopUpButton *actionButton, *subviewButton; - NSRect contentBounds, expressionFrame; - - if (!(self = [super initWithMachine:m title:@"Memory" console:c])) - return nil; - contentBounds = [[window contentView] bounds]; - - // create the expression field - expressionField = [[NSTextField alloc] initWithFrame:NSMakeRect(0, 0, 100, 19)]; - [expressionField setAutoresizingMask:(NSViewWidthSizable | NSViewMaxXMargin | NSViewMinYMargin)]; - [expressionField setFont:[[MAMEDebugView class] defaultFont]]; - [expressionField setFocusRingType:NSFocusRingTypeNone]; - [expressionField setTarget:self]; - [expressionField setAction:@selector(doExpression:)]; - [expressionField setDelegate:self]; - expressionFrame = [expressionField frame]; - expressionFrame.size.width = (contentBounds.size.width - expressionFrame.size.height) / 2; - [expressionField setFrameSize:expressionFrame.size]; - - // create the subview popup - subviewButton = [[NSPopUpButton alloc] initWithFrame:NSOffsetRect(expressionFrame, - expressionFrame.size.width, - 0)]; - [subviewButton setAutoresizingMask:(NSViewWidthSizable | NSViewMinXMargin | NSViewMinYMargin)]; - [subviewButton setBezelStyle:NSShadowlessSquareBezelStyle]; - [subviewButton setFocusRingType:NSFocusRingTypeNone]; - [subviewButton setFont:[[MAMEDebugView class] defaultFont]]; - [subviewButton setTarget:self]; - [subviewButton setAction:@selector(changeSubview:)]; - [[subviewButton cell] setArrowPosition:NSPopUpArrowAtBottom]; - - // create a container for the expression field and subview popup - expressionFrame = NSMakeRect(expressionFrame.size.height, - contentBounds.size.height - expressionFrame.size.height, - contentBounds.size.width - expressionFrame.size.height, - expressionFrame.size.height); - expressionContainer = [[NSView alloc] initWithFrame:expressionFrame]; - [expressionContainer setAutoresizingMask:(NSViewWidthSizable | NSViewMinYMargin)]; - [expressionContainer addSubview:expressionField]; - [expressionField release]; - [expressionContainer addSubview:subviewButton]; - [subviewButton release]; - [[window contentView] addSubview:expressionContainer]; - [expressionContainer release]; - - // create the memory view - memoryView = [[MAMEMemoryView alloc] initWithFrame:NSMakeRect(0, 0, 100, 100) - machine:*machine]; - [memoryView insertSubviewItemsInMenu:[subviewButton menu] atIndex:0]; - memoryScroll = [[NSScrollView alloc] initWithFrame:NSMakeRect(0, - 0, - contentBounds.size.width, - expressionFrame.origin.y)]; - [memoryScroll setDrawsBackground:YES]; - [memoryScroll setAutoresizingMask:(NSViewWidthSizable | NSViewHeightSizable)]; - [memoryScroll setHasHorizontalScroller:YES]; - [memoryScroll setHasVerticalScroller:YES]; - [memoryScroll setAutohidesScrollers:YES]; - [memoryScroll setBorderType:NSNoBorder]; - [memoryScroll setDocumentView:memoryView]; - [memoryView release]; - [[window contentView] addSubview:memoryScroll]; - [memoryScroll release]; - - // create the action popup - actionButton = [[self class] newActionButtonWithFrame:NSMakeRect(0, - expressionFrame.origin.y, - expressionFrame.size.height, - expressionFrame.size.height)]; - [actionButton setAutoresizingMask:(NSViewMaxXMargin | NSViewMinYMargin)]; - [memoryView insertActionItemsInMenu:[actionButton menu] atIndex:1]; - [[window contentView] addSubview:actionButton]; - [actionButton release]; - - // set default state - [memoryView selectSubviewForCPU:debug_cpu_get_visible_cpu(*machine)]; - [memoryView setExpression:@"0"]; - [expressionField setStringValue:@"0"]; - [expressionField selectText:self]; - [subviewButton selectItemAtIndex:[subviewButton indexOfItemWithTag:[memoryView selectedSubviewIndex]]]; - [window makeFirstResponder:expressionField]; - [window setTitle:[NSString stringWithFormat:@"Memory: %@", [memoryView selectedSubviewName]]]; - - // calculate the optimal size for everything - { - NSSize desired = [NSScrollView frameSizeForContentSize:[memoryView maximumFrameSize] - hasHorizontalScroller:YES - hasVerticalScroller:YES - borderType:[memoryScroll borderType]]; - [self cascadeWindowWithDesiredSize:desired forView:memoryScroll]; - } - - // don't forget the result - return self; -} - - -- (void)dealloc { - [super dealloc]; -} - - -- (id )documentView { - return memoryView; -} - - -- (IBAction)changeSubview:(id)sender { - [memoryView selectSubviewAtIndex:[[sender selectedItem] tag]]; - [window setTitle:[NSString stringWithFormat:@"Memory: %@", [memoryView selectedSubviewName]]]; -} - -@end - - -//============================================================ -// MAMEDisassemblyViewer class -//============================================================ - -@implementation MAMEDisassemblyViewer - -- (id)initWithMachine:(running_machine &)m console:(MAMEDebugConsole *)c { - NSScrollView *dasmScroll; - NSView *expressionContainer; - NSPopUpButton *actionButton, *subviewButton; - NSRect contentBounds, expressionFrame; - - if (!(self = [super initWithMachine:m title:@"Disassembly" console:c])) - return nil; - contentBounds = [[window contentView] bounds]; - - // create the expression field - expressionField = [[NSTextField alloc] initWithFrame:NSMakeRect(0, 0, 100, 19)]; - [expressionField setAutoresizingMask:(NSViewWidthSizable | NSViewMaxXMargin | NSViewMinYMargin)]; - [expressionField setFont:[[MAMEDebugView class] defaultFont]]; - [expressionField setFocusRingType:NSFocusRingTypeNone]; - [expressionField setTarget:self]; - [expressionField setAction:@selector(doExpression:)]; - [expressionField setDelegate:self]; - expressionFrame = [expressionField frame]; - expressionFrame.size.width = (contentBounds.size.width - expressionFrame.size.height) / 2; - [expressionField setFrameSize:expressionFrame.size]; - - // create the subview popup - subviewButton = [[NSPopUpButton alloc] initWithFrame:NSOffsetRect(expressionFrame, - expressionFrame.size.width, - 0)]; - [subviewButton setAutoresizingMask:(NSViewWidthSizable | NSViewMinXMargin | NSViewMinYMargin)]; - [subviewButton setBezelStyle:NSShadowlessSquareBezelStyle]; - [subviewButton setFocusRingType:NSFocusRingTypeNone]; - [subviewButton setFont:[[MAMEDebugView class] defaultFont]]; - [subviewButton setTarget:self]; - [subviewButton setAction:@selector(changeSubview:)]; - [[subviewButton cell] setArrowPosition:NSPopUpArrowAtBottom]; - - // create a container for the expression field and subview popup - expressionFrame = NSMakeRect(expressionFrame.size.height, - contentBounds.size.height - expressionFrame.size.height, - contentBounds.size.width - expressionFrame.size.height, - expressionFrame.size.height); - expressionContainer = [[NSView alloc] initWithFrame:expressionFrame]; - [expressionContainer setAutoresizingMask:(NSViewWidthSizable | NSViewMinYMargin)]; - [expressionContainer addSubview:expressionField]; - [expressionField release]; - [expressionContainer addSubview:subviewButton]; - [subviewButton release]; - [[window contentView] addSubview:expressionContainer]; - [expressionContainer release]; - - // create the disassembly view - dasmView = [[MAMEDisassemblyView alloc] initWithFrame:NSMakeRect(0, 0, 100, 100) - machine:*machine - useConsole:NO]; - [dasmView insertSubviewItemsInMenu:[subviewButton menu] atIndex:0]; - dasmScroll = [[NSScrollView alloc] initWithFrame:NSMakeRect(0, - 0, - contentBounds.size.width, - expressionFrame.origin.y)]; - [dasmScroll setDrawsBackground:YES]; - [dasmScroll setAutoresizingMask:(NSViewWidthSizable | NSViewHeightSizable)]; - [dasmScroll setHasHorizontalScroller:YES]; - [dasmScroll setHasVerticalScroller:YES]; - [dasmScroll setAutohidesScrollers:YES]; - [dasmScroll setBorderType:NSNoBorder]; - [dasmScroll setDocumentView:dasmView]; - [dasmView release]; - [[window contentView] addSubview:dasmScroll]; - [dasmScroll release]; - - // create the action popup - actionButton = [[self class] newActionButtonWithFrame:NSMakeRect(0, - expressionFrame.origin.y, - expressionFrame.size.height, - expressionFrame.size.height)]; - [actionButton setAutoresizingMask:(NSViewMaxXMargin | NSViewMinYMargin)]; - [dasmView insertActionItemsInMenu:[actionButton menu] atIndex:1]; - [[window contentView] addSubview:actionButton]; - [actionButton release]; - - // set default state - [dasmView selectSubviewForCPU:debug_cpu_get_visible_cpu(*machine)]; - [dasmView setExpression:@"curpc"]; - [expressionField setStringValue:@"curpc"]; - [expressionField selectText:self]; - [subviewButton selectItemAtIndex:[subviewButton indexOfItemWithTag:[dasmView selectedSubviewIndex]]]; - [window makeFirstResponder:expressionField]; - [window setTitle:[NSString stringWithFormat:@"Disassembly: %@", [dasmView selectedSubviewName]]]; - - // calculate the optimal size for everything - { - NSSize desired = [NSScrollView frameSizeForContentSize:[dasmView maximumFrameSize] - hasHorizontalScroller:YES - hasVerticalScroller:YES - borderType:[dasmScroll borderType]]; - [self cascadeWindowWithDesiredSize:desired forView:dasmScroll]; - } - - // don't forget the result - return self; -} - - -- (void)dealloc { - [super dealloc]; -} - - -- (id )documentView { - return dasmView; -} - - -- (IBAction)changeSubview:(id)sender { - [dasmView selectSubviewAtIndex:[[sender selectedItem] tag]]; - [window setTitle:[NSString stringWithFormat:@"Disassembly: %@", [dasmView selectedSubviewName]]]; -} - -@end - - -//============================================================ -// MAMEErrorLogViewer class -//============================================================ - -@implementation MAMEErrorLogViewer - -- (id)initWithMachine:(running_machine &)m console:(MAMEDebugConsole *)c { - NSScrollView *logScroll; - NSString *title; - - title = [NSString stringWithFormat:@"Error Log: %@ [%@]", - [NSString stringWithUTF8String:m.system().description], - [NSString stringWithUTF8String:m.system().name]]; - if (!(self = [super initWithMachine:m title:title console:c])) - return nil; - - // create the error log view - logView = [[MAMEErrorLogView alloc] initWithFrame:NSMakeRect(0, 0, 100, 100) machine:*machine]; - logScroll = [[NSScrollView alloc] initWithFrame:NSMakeRect(0, 0, 100, 100)]; - [logScroll setDrawsBackground:YES]; - [logScroll setAutoresizingMask:(NSViewWidthSizable | NSViewHeightSizable)]; - [logScroll setHasHorizontalScroller:YES]; - [logScroll setHasVerticalScroller:YES]; - [logScroll setAutohidesScrollers:YES]; - [logScroll setBorderType:NSNoBorder]; - [logScroll setDocumentView:logView]; - [logView release]; - [window setContentView:logScroll]; - [logScroll release]; - - // calculate the optimal size for everything - { - NSSize desired = [NSScrollView frameSizeForContentSize:[logView maximumFrameSize] - hasHorizontalScroller:YES - hasVerticalScroller:YES - borderType:[logScroll borderType]]; - - // this thing starts with no content, so its prefered height may be very small - desired.height = MAX(desired.height, 240); - [self cascadeWindowWithDesiredSize:desired forView:logScroll]; - } - - // don't forget the result - return self; -} - - -- (void)dealloc { - [super dealloc]; -} - -@end diff --git a/src/osd/modules/debugger/osx/debugosx.h b/src/osd/modules/debugger/osx/debugosx.h new file mode 100644 index 00000000000..8971955dacb --- /dev/null +++ b/src/osd/modules/debugger/osx/debugosx.h @@ -0,0 +1,55 @@ +// license:BSD-3-Clause +// copyright-holders:Vas Crabb +//============================================================ +// +// debugosx.h - MacOS X Cocoa debug window handling +// +// Copyright (c) 1996-2015, Nicola Salmoria and the MAME Team. +// Visit http://mamedev.org for licensing and usage restrictions. +// +//============================================================ + +#ifndef __SDL_DEBUGOSX__ +#define __SDL_DEBUGOSX__ + +// make sure this comes first +#include + + +#ifdef __OBJC__ + +// standard Cocoa headers +#import + +// workarounds for 10.6 warnings +#ifdef MAC_OS_X_VERSION_MAX_ALLOWED + +#if MAC_OS_X_VERSION_MAX_ALLOWED < 1050 + +typedef int NSInteger; +typedef unsigned NSUInteger; +typedef float CGFloat; + +#endif // MAC_OS_X_VERSION_MAX_ALLOWED < 1050 + +#if MAC_OS_X_VERSION_MAX_ALLOWED < 1060 + +@protocol NSWindowDelegate +@end + +@protocol NSSplitViewDelegate +@end + +@protocol NSControlTextEditingDelegate +@end + +@protocol NSTextFieldDelegate +@end + +#endif // MAC_OS_X_VERSION_MAX_ALLOWED < 1060 + +#endif // MAC_OS_X_VERSION_MAX_ALLOWED + +#endif // __OBJC__ + +#endif // __SDL_DEBUGOSX__ diff --git a/src/osd/modules/debugger/osx/debugosxconsoleview.h b/src/osd/modules/debugger/osx/debugosxconsoleview.h new file mode 100644 index 00000000000..0c9740f02db --- /dev/null +++ b/src/osd/modules/debugger/osx/debugosxconsoleview.h @@ -0,0 +1,26 @@ +// license:BSD-3-Clause +// copyright-holders:Vas Crabb +//============================================================ +// +// debugosxconsoleview.h - MacOS X Cocoa debug window handling +// +// Copyright (c) 1996-2015, Nicola Salmoria and the MAME Team. +// Visit http://mamedev.org for licensing and usage restrictions. +// +//============================================================ + +#import "debugosx.h" +#import "debugosxdebugview.h" + +#include "emu.h" + +#import + + +@interface MAMEConsoleView : MAMEDebugView +{ +} + +- (id)initWithFrame:(NSRect)f machine:(running_machine &)m; + +@end diff --git a/src/osd/modules/debugger/osx/debugosxconsoleview.m b/src/osd/modules/debugger/osx/debugosxconsoleview.m new file mode 100644 index 00000000000..746fa26cf93 --- /dev/null +++ b/src/osd/modules/debugger/osx/debugosxconsoleview.m @@ -0,0 +1,30 @@ +// license:BSD-3-Clause +// copyright-holders:Vas Crabb +//============================================================ +// +// debugosxconsoleview.m - MacOS X Cocoa debug window handling +// +// Copyright (c) 1996-2015, Nicola Salmoria and the MAME Team. +// Visit http://mamedev.org for licensing and usage restrictions. +// +//============================================================ + +#import "debugosxconsoleview.h" + +#include "debug/debugvw.h" + + +@implementation MAMEConsoleView + +- (id)initWithFrame:(NSRect)f machine:(running_machine &)m { + if (!(self = [super initWithFrame:f type:DVT_CONSOLE machine:m])) + return nil; + return self; +} + + +- (void)dealloc { + [super dealloc]; +} + +@end diff --git a/src/osd/modules/debugger/osx/debugosxdebugcommandhistory.h b/src/osd/modules/debugger/osx/debugosxdebugcommandhistory.h new file mode 100644 index 00000000000..78f8fbe42c7 --- /dev/null +++ b/src/osd/modules/debugger/osx/debugosxdebugcommandhistory.h @@ -0,0 +1,37 @@ +// license:BSD-3-Clause +// copyright-holders:Vas Crabb +//============================================================ +// +// debugosxdebugcommandhistory.h - MacOS X Cocoa debug window handling +// +// Copyright (c) 1996-2015, Nicola Salmoria and the MAME Team. +// Visit http://mamedev.org for licensing and usage restrictions. +// +//============================================================ + +#import "debugosx.h" + +#import + + +@interface MAMEDebugCommandHistory : NSObject +{ + NSInteger length, position; + NSString *current; + NSMutableArray *history; +} + ++ (NSInteger)defaultLength; + +- (id)init; + +- (NSInteger)length; +- (void)setLength:(NSInteger)l; + +- (void)add:(NSString *)entry; +- (NSString *)previous:(NSString *)cur; +- (NSString *)next:(NSString *)cur; +- (void)reset; +- (void)clear; + +@end diff --git a/src/osd/modules/debugger/osx/debugosxdebugcommandhistory.m b/src/osd/modules/debugger/osx/debugosxdebugcommandhistory.m new file mode 100644 index 00000000000..9c1cd5093a0 --- /dev/null +++ b/src/osd/modules/debugger/osx/debugosxdebugcommandhistory.m @@ -0,0 +1,111 @@ +// license:BSD-3-Clause +// copyright-holders:Vas Crabb +//============================================================ +// +// debugosxdebugcommandhistory.m - MacOS X Cocoa debug window handling +// +// Copyright (c) 1996-2015, Nicola Salmoria and the MAME Team. +// Visit http://mamedev.org for licensing and usage restrictions. +// +//============================================================ + +//============================================================ +// MAMEDebugView class +//============================================================ + +#import "debugosxdebugcommandhistory.h" + + +@implementation MAMEDebugCommandHistory + ++ (NSInteger)defaultLength { + return 100; +} + + +- (id)init { + if (!(self = [super init])) + return nil; + length = [[self class] defaultLength]; + position = -1; + current = nil; + history = [[NSMutableArray alloc] initWithCapacity:length]; + return self; +} + + +- (void)dealloc { + if (current != nil) + [current release]; + if (history != nil) + [history release]; + [super dealloc]; +} + + +- (NSInteger)length { + return length; +} + + +- (void)setLength:(NSInteger)l { + length = l; + while ([history count] > length) + [history removeLastObject]; +} + + +- (void)add:(NSString *)entry { + if (([history count] == 0) || ![[history objectAtIndex:0] isEqualToString:entry]) { + [history insertObject:entry atIndex:0]; + while ([history count] > length) + [history removeLastObject]; + } + position = -1; +} + + +- (NSString *)previous:(NSString *)cur { + if ((position + 1) < [history count]) { + if (position < 0) { + [current autorelease]; + current = [cur copy]; + } + return [history objectAtIndex:++position]; + } else { + return nil; + } +} + + +- (NSString *)next:(NSString *)cur { + if (position > 0) { + return [history objectAtIndex:--position]; + } else if (position == 0) { + position--; + return [[current retain] autorelease]; + } else { + return nil; + } +} + + +- (void)reset { + position = -1; + if (current != nil) { + [current release]; + current = nil; + } +} + + +- (void)clear { + position = -1; + if (current != nil) { + [current release]; + current = nil; + } + [history removeAllObjects]; +} + +@end diff --git a/src/osd/modules/debugger/osx/debugosxdebugconsole.h b/src/osd/modules/debugger/osx/debugosxdebugconsole.h new file mode 100644 index 00000000000..85639929c04 --- /dev/null +++ b/src/osd/modules/debugger/osx/debugosxdebugconsole.h @@ -0,0 +1,56 @@ +// license:BSD-3-Clause +// copyright-holders:Vas Crabb +//============================================================ +// +// debugosxdebugconsole.h - MacOS X Cocoa debug window handling +// +// Copyright (c) 1996-2015, Nicola Salmoria and the MAME Team. +// Visit http://mamedev.org for licensing and usage restrictions. +// +//============================================================ + +#import "debugosx.h" +#import "debugosxdebugwindowhandler.h" + +#include "device.h" +#include "emu.h" + +#import + + +@class MAMEDebugCommandHistory, MAMEDebugView, MAMEDisassemblyView, MAMERegistersView; + +@interface MAMEDebugConsole : MAMEDebugWindowHandler +{ + MAMEDebugCommandHistory *history; + NSMutableArray *auxiliaryWindows; + + MAMERegistersView *regView; + MAMEDisassemblyView *dasmView; + MAMEDebugView *consoleView; + NSTextField *commandField; +} + +- (id)initWithMachine:(running_machine &)m; + +- (void)setCPU:(device_t *)device; + +- (IBAction)doCommand:(id)sender; + +- (IBAction)debugNewMemoryWindow:(id)sender; +- (IBAction)debugNewDisassemblyWindow:(id)sender; +- (IBAction)debugNewErrorLogWindow:(id)sender; + +- (void)showDebugger:(NSNotification *)notification; +- (void)auxiliaryWindowWillClose:(NSNotification *)notification; + +- (BOOL)control:(NSControl *)control textView:(NSTextView *)textView doCommandBySelector:(SEL)command; + +- (void)windowWillClose:(NSNotification *)notification; + +- (CGFloat)splitView:(NSSplitView *)sender constrainMinCoordinate:(CGFloat)min ofSubviewAt:(NSInteger)offs; +- (CGFloat)splitView:(NSSplitView *)sender constrainMaxCoordinate:(CGFloat)max ofSubviewAt:(NSInteger)offs; +- (BOOL)splitView:(NSSplitView *)sender canCollapseSubview:(NSView *)subview; +- (void)splitView:(NSSplitView *)sender resizeSubviewsWithOldSize:(NSSize)oldSize; + +@end diff --git a/src/osd/modules/debugger/osx/debugosxdebugconsole.m b/src/osd/modules/debugger/osx/debugosxdebugconsole.m new file mode 100644 index 00000000000..4952e2ccdf6 --- /dev/null +++ b/src/osd/modules/debugger/osx/debugosxdebugconsole.m @@ -0,0 +1,356 @@ +// license:BSD-3-Clause +// copyright-holders:Vas Crabb +//============================================================ +// +// debugosxdebugconsole.m - MacOS X Cocoa debug window handling +// +// Copyright (c) 1996-2015, Nicola Salmoria and the MAME Team. +// Visit http://mamedev.org for licensing and usage restrictions. +// +//============================================================ + +#import "debugosxdebugconsole.h" + +#import "debugosxdebugcommandhistory.h" +#import "debugosxconsoleview.h" +#import "debugosxdebugview.h" +#import "debugosxdisassemblyview.h" +#import "debugosxdisassemblyviewer.h" +#import "debugosxerrorlogviewer.h" +#import "debugosxmemoryviewer.h" +#import "debugosxregistersview.h" + +#include "debug/debugcon.h" +#include "debug/debugcpu.h" + + +@implementation MAMEDebugConsole + +- (id)initWithMachine:(running_machine &)m { + NSSplitView *regSplit, *dasmSplit; + NSScrollView *regScroll, *dasmScroll, *consoleScroll; + NSView *consoleContainer; + NSPopUpButton *actionButton; + NSRect rct; + + // initialise superclass + if (!(self = [super initWithMachine:m title:@"Debug"])) + return nil; + history = [[MAMEDebugCommandHistory alloc] init]; + auxiliaryWindows = [[NSMutableArray alloc] init]; + + // create the register view + regView = [[MAMERegistersView alloc] initWithFrame:NSMakeRect(0, 0, 100, 100) machine:*machine]; + regScroll = [[NSScrollView alloc] initWithFrame:NSMakeRect(0, 0, 100, 100)]; + [regScroll setDrawsBackground:YES]; + [regScroll setHasHorizontalScroller:YES]; + [regScroll setHasVerticalScroller:YES]; + [regScroll setAutohidesScrollers:YES]; + [regScroll setBorderType:NSBezelBorder]; + [regScroll setDocumentView:regView]; + [regView release]; + + // create the disassembly view + dasmView = [[MAMEDisassemblyView alloc] initWithFrame:NSMakeRect(0, 0, 100, 100) + machine:*machine + useConsole:YES]; + [dasmView setExpression:@"curpc"]; + dasmScroll = [[NSScrollView alloc] initWithFrame:NSMakeRect(0, 0, 100, 100)]; + [dasmScroll setDrawsBackground:YES]; + [dasmScroll setHasHorizontalScroller:YES]; + [dasmScroll setHasVerticalScroller:YES]; + [dasmScroll setAutohidesScrollers:YES]; + [dasmScroll setBorderType:NSBezelBorder]; + [dasmScroll setDocumentView:dasmView]; + [dasmView release]; + + // create the console view + consoleView = [[MAMEConsoleView alloc] initWithFrame:NSMakeRect(0, 0, 100, 100) machine:*machine]; + consoleScroll = [[NSScrollView alloc] initWithFrame:NSMakeRect(0, 0, 100, 100)]; + [consoleScroll setDrawsBackground:YES]; + [consoleScroll setAutoresizingMask:(NSViewWidthSizable | NSViewHeightSizable)]; + [consoleScroll setHasHorizontalScroller:YES]; + [consoleScroll setHasVerticalScroller:YES]; + [consoleScroll setAutohidesScrollers:YES]; + [consoleScroll setBorderType:NSBezelBorder]; + [consoleScroll setDocumentView:consoleView]; + [consoleView release]; + + // create the command field + commandField = [[NSTextField alloc] initWithFrame:NSMakeRect(0, 0, 100, 19)]; + [commandField setAutoresizingMask:(NSViewWidthSizable | NSViewMaxYMargin)]; + [commandField setFont:[[MAMEDebugView class] defaultFont]]; + [commandField setFocusRingType:NSFocusRingTypeNone]; + [commandField setTarget:self]; + [commandField setAction:@selector(doCommand:)]; + [commandField setDelegate:self]; + rct = [commandField frame]; + [commandField setFrame:NSMakeRect(rct.size.height, 0, rct.size.width - rct.size.height, rct.size.height)]; + + // create the action pull-down button + actionButton = [[self class] newActionButtonWithFrame:NSMakeRect(0, 0, rct.size.height, rct.size.height)]; + [actionButton setAutoresizingMask:(NSViewMaxXMargin | NSViewMaxYMargin)]; + [dasmView insertActionItemsInMenu:[actionButton menu] atIndex:1]; + + // create the container for the console and command input field + consoleContainer = [[NSView alloc] initWithFrame:NSMakeRect(0, 0, 100, 100)]; + [consoleScroll setFrame:NSMakeRect(0, + rct.size.height, + 100, + [consoleContainer bounds].size.height - rct.size.height)]; + [consoleContainer addSubview:consoleScroll]; + [consoleContainer addSubview:commandField]; + [consoleContainer addSubview:actionButton]; + [consoleScroll release]; + [commandField release]; + [actionButton release]; + + // create the split between the disassembly and the console + dasmSplit = [[NSSplitView alloc] initWithFrame:NSMakeRect(0, 0, 100, 100)]; + [dasmSplit setDelegate:self]; + [dasmSplit setVertical:NO]; + [dasmSplit addSubview:dasmScroll]; + [dasmSplit addSubview:consoleContainer]; + [dasmScroll release]; + [consoleContainer release]; + + // create the split between the registers and the console + regSplit = [[NSSplitView alloc] initWithFrame:NSMakeRect(0, 0, 100, 100)]; + [regSplit setDelegate:self]; + [regSplit setAutoresizingMask:(NSViewWidthSizable | NSViewHeightSizable)]; + [regSplit setVertical:YES]; + [regSplit addSubview:regScroll]; + [regSplit addSubview:dasmSplit]; + [regScroll release]; + [dasmSplit release]; + + // put the split views in the window and get them into a half-reasonable state + [window setContentView:regSplit]; + [regSplit release]; + [regSplit adjustSubviews]; + [dasmSplit adjustSubviews]; + + // keyboard focus should start on the command field + [window makeFirstResponder:commandField]; + + // calculate the optimal size for everything + { + NSRect available = [[NSScreen mainScreen] visibleFrame]; + NSRect windowFrame = [window frame]; + NSSize regCurrent = [regScroll frame].size; + NSSize regSize = [NSScrollView frameSizeForContentSize:[regView maximumFrameSize] + hasHorizontalScroller:YES + hasVerticalScroller:YES + borderType:[regScroll borderType]]; + NSSize dasmCurrent = [dasmScroll frame].size; + NSSize dasmSize = [NSScrollView frameSizeForContentSize:[dasmView maximumFrameSize] + hasHorizontalScroller:YES + hasVerticalScroller:YES + borderType:[dasmScroll borderType]]; + NSSize consoleCurrent = [consoleContainer frame].size; + NSSize consoleSize = [NSScrollView frameSizeForContentSize:[consoleView maximumFrameSize] + hasHorizontalScroller:YES + hasVerticalScroller:YES + borderType:[consoleScroll borderType]]; + NSSize adjustment; + NSRect lhsFrame, rhsFrame; + + consoleSize.width += consoleCurrent.width - [consoleScroll frame].size.width; + consoleSize.height += consoleCurrent.height - [consoleScroll frame].size.height; + adjustment.width = regSize.width - regCurrent.width; + adjustment.height = regSize.height - regCurrent.height; + adjustment.width += MAX(dasmSize.width - dasmCurrent.width, consoleSize.width - consoleCurrent.width); + + windowFrame.size.width += adjustment.width; + windowFrame.size.height += adjustment.height; // not used - better to go for fixed height + windowFrame.size.height = MIN(512.0, available.size.height); + windowFrame.size.width = MIN(windowFrame.size.width, available.size.width); + windowFrame.origin.x = available.origin.x + available.size.width - windowFrame.size.width; + windowFrame.origin.y = available.origin.y; + [window setFrame:windowFrame display:YES]; + + lhsFrame = [regScroll frame]; + rhsFrame = [dasmSplit frame]; + adjustment.width = MIN(regSize.width, ([regSplit frame].size.width - [regSplit dividerThickness]) / 2); + rhsFrame.origin.x -= lhsFrame.size.width - adjustment.width; + rhsFrame.size.width += lhsFrame.size.width - adjustment.width; + lhsFrame.size.width = adjustment.width; + [regScroll setFrame:lhsFrame]; + [dasmSplit setFrame:rhsFrame]; + } + + // select the current processor + [self setCPU:machine->firstcpu]; + + [[NSNotificationCenter defaultCenter] addObserver:self + selector:@selector(auxiliaryWindowWillClose:) + name:MAMEAuxiliaryDebugWindowWillCloseNotification + object:nil]; + + // don't forget the return value + return self; +} + + +- (void)dealloc { + [[NSNotificationCenter defaultCenter] removeObserver:self]; + + if (history != nil) + [history release]; + if (auxiliaryWindows != nil) + [auxiliaryWindows release]; + + [super dealloc]; +} + + +- (void)setCPU:(device_t *)device { + [regView selectSubviewForCPU:device]; + [dasmView selectSubviewForCPU:device]; + [window setTitle:[NSString stringWithFormat:@"Debug: %s - %s '%s'", + device->machine().system().name, + device->name(), + device->tag()]]; +} + + +- (IBAction)doCommand:(id)sender { + NSString *command = [sender stringValue]; + if ([command length] == 0) { + debug_cpu_get_visible_cpu(*machine)->debug()->single_step(); + } else { + debug_console_execute_command(*machine, [command UTF8String], 1); + [history add:command]; + } + [sender setStringValue:@""]; +} + + +- (IBAction)debugNewMemoryWindow:(id)sender { + MAMEMemoryViewer *win = [[MAMEMemoryViewer alloc] initWithMachine:*machine console:self]; + [auxiliaryWindows addObject:win]; + [win release]; + [win activate]; +} + + +- (IBAction)debugNewDisassemblyWindow:(id)sender { + MAMEDisassemblyViewer *win = [[MAMEDisassemblyViewer alloc] initWithMachine:*machine console:self]; + [auxiliaryWindows addObject:win]; + [win release]; + [win activate]; +} + + +- (IBAction)debugNewErrorLogWindow:(id)sender { + MAMEErrorLogViewer *win = [[MAMEErrorLogViewer alloc] initWithMachine:*machine console:self]; + [auxiliaryWindows addObject:win]; + [win release]; + [win activate]; +} + + +- (void)showDebugger:(NSNotification *)notification { + device_t *device = (device_t * )[[[notification userInfo] objectForKey:@"MAMEDebugDevice"] pointerValue]; + if (&device->machine() == machine) { + [self setCPU:device]; + [window makeKeyAndOrderFront:self]; + } +} + + +- (void)auxiliaryWindowWillClose:(NSNotification *)notification { + [auxiliaryWindows removeObjectIdenticalTo:[notification object]]; +} + + +- (BOOL)control:(NSControl *)control textView:(NSTextView *)textView doCommandBySelector:(SEL)command { + if (control == commandField) { + if (command == @selector(cancelOperation:)) { + [commandField setStringValue:@""]; + [history reset]; + return YES; + } else if (command == @selector(moveUp:)) { + NSString *hist = [history previous:[commandField stringValue]]; + if (hist != nil) { + [commandField setStringValue:hist]; + [commandField selectText:self]; + [(NSText *)[window firstResponder] setSelectedRange:NSMakeRange([hist length], 0)]; + } + return YES; + } else if (command == @selector(moveDown:)) { + NSString *hist = [history next:[commandField stringValue]]; + if (hist != nil) { + [commandField setStringValue:hist]; + [commandField selectText:self]; + [(NSText *)[window firstResponder] setSelectedRange:NSMakeRange([hist length], 0)]; + } + return YES; + } + } + return NO; +} + + +- (void)windowWillClose:(NSNotification *)notification { + if ([notification object] != window) + return; + [[NSNotificationCenter defaultCenter] postNotificationName:MAMEHideDebuggerNotification object:self]; + debug_cpu_get_visible_cpu(*machine)->debug()->go(); +} + + +- (CGFloat)splitView:(NSSplitView *)sender constrainMinCoordinate:(CGFloat)min ofSubviewAt:(NSInteger)offs { + return (min < 100) ? 100 : min; +} + + +- (CGFloat)splitView:(NSSplitView *)sender constrainMaxCoordinate:(CGFloat)max ofSubviewAt:(NSInteger)offs { + NSSize sz = [sender bounds].size; + CGFloat allowed = ([sender isVertical] ? sz.width : sz.height) - 100 - [sender dividerThickness]; + return (max > allowed) ? allowed : max; +} + + +- (BOOL)splitView:(NSSplitView *)sender canCollapseSubview:(NSView *)subview { + // allow registers or disassembly to be collapsed, but not console + return [[sender subviews] indexOfObjectIdenticalTo:subview] == 0; +} + + +- (void)splitView:(NSSplitView *)sender resizeSubviewsWithOldSize:(NSSize)oldSize { + // This can only deal with a single split, but that's all we use, anyway + NSRect first, second; + [sender adjustSubviews]; + first = [[[sender subviews] objectAtIndex:0] frame]; + second = [[[sender subviews] objectAtIndex:1] frame]; + if ([sender isVertical]) { + if (first.size.width < 100) { + CGFloat diff = 100 - first.size.width; + first.size.width = 100; + second.origin.x += diff; + second.size.width -= diff; + } else if (second.size.width < 100) { + CGFloat diff = 100 - second.size.width; + second.size.width = 100; + second.origin.x -= diff; + first.size.width -= diff; + } + } else { + if (first.size.height < 100) { + CGFloat diff = 100 - first.size.height; + first.size.height = 100; + second.origin.y += diff; + second.size.height -= diff; + } else if (second.size.height < 100) { + CGFloat diff = 100 - second.size.height; + second.size.height = 100; + second.origin.y -= diff; + first.size.height -= diff; + } + } + [[[sender subviews] objectAtIndex:0] setFrame:first]; + [[[sender subviews] objectAtIndex:1] setFrame:second]; +} + +@end diff --git a/src/osd/modules/debugger/osx/debugosxdebugview.h b/src/osd/modules/debugger/osx/debugosxdebugview.h new file mode 100644 index 00000000000..d87ecdb3015 --- /dev/null +++ b/src/osd/modules/debugger/osx/debugosxdebugview.h @@ -0,0 +1,64 @@ +// license:BSD-3-Clause +// copyright-holders:Vas Crabb +//============================================================ +// +// debugosxdebugview.h - MacOS X Cocoa debug window handling +// +// Copyright (c) 1996-2015, Nicola Salmoria and the MAME Team. +// Visit http://mamedev.org for licensing and usage restrictions. +// +//============================================================ + +#import "debugosx.h" + +#include "emu.h" +#include "debug/debugvw.h" + +#import + + +@protocol MAMEDebugViewSubviewSupport + +- (NSString *)selectedSubviewName; +- (int)selectedSubviewIndex; +- (void)selectSubviewAtIndex:(int)index; +- (void)selectSubviewForCPU:(device_t *)device; + +@end + + +@protocol MAMEDebugViewExpressionSupport + +- (NSString *)expression; +- (void)setExpression:(NSString *)exp; + +@end + + +@interface MAMEDebugView : NSView +{ + int type; + running_machine *machine; + debug_view *view; + + INT32 totalWidth, totalHeight, originLeft, originTop; + + NSFont *font; + CGFloat fontWidth, fontHeight, fontAscent; +} + ++ (NSFont *)defaultFont; + +- (id)initWithFrame:(NSRect)f type:(debug_view_type)t machine:(running_machine &)m; + +- (void)update; + +- (NSSize)maximumFrameSize; + +- (NSFont *)font; +- (void)setFont:(NSFont *)f; + +- (void)windowDidBecomeKey:(NSNotification *)notification; +- (void)windowDidResignKey:(NSNotification *)notification; + +@end diff --git a/src/osd/modules/debugger/osx/debugosxdebugview.m b/src/osd/modules/debugger/osx/debugosxdebugview.m new file mode 100644 index 00000000000..d893bb0ad2f --- /dev/null +++ b/src/osd/modules/debugger/osx/debugosxdebugview.m @@ -0,0 +1,466 @@ +// license:BSD-3-Clause +// copyright-holders:Vas Crabb +//============================================================ +// +// debugosxdebugview.h - MacOS X Cocoa debug window handling +// +// Copyright (c) 1996-2015, Nicola Salmoria and the MAME Team. +// Visit http://mamedev.org for licensing and usage restrictions. +// +//============================================================ + +#import "debugosxdebugview.h" + +#include "debug/debugcpu.h" + + +static void debugwin_view_update(debug_view &view, void *osdprivate) +{ + [(MAMEDebugView *)osdprivate update]; +} + + +@implementation MAMEDebugView + +- (NSColor *)foregroundForAttribute:(UINT8)attrib { + const CGFloat alpha = (attrib & DCA_DISABLED) ? 0.5 : 1.0; + if (attrib & DCA_COMMENT) + return [NSColor colorWithCalibratedRed:0.0 green:0.375 blue:0.0 alpha:1.0]; + else if (attrib & DCA_INVALID) + return [NSColor colorWithCalibratedRed:0.0 green:0.0 blue:1.0 alpha:alpha]; + else if (attrib & DCA_CHANGED) + return [NSColor colorWithCalibratedRed:0.875 green:0.0 blue:0.0 alpha:alpha]; + else + return [NSColor colorWithCalibratedWhite:0.0 alpha:alpha]; +} + + +- (NSColor *)backgroundForAttribute:(UINT8)attrib { + if ((attrib & DCA_SELECTED) && (attrib & DCA_CURRENT)) { + if ([[self window] isKeyWindow] && ([[self window] firstResponder] == self)) + return [NSColor colorWithCalibratedRed:0.875 green:0.625 blue:0.875 alpha:1.0]; + else + return [NSColor colorWithCalibratedRed:0.875 green:0.5 blue:0.625 alpha:1.0]; + } else if (attrib & DCA_CURRENT) { + return [NSColor colorWithCalibratedRed:1.0 green:0.625 blue:0.625 alpha:1.0]; + } else if (attrib & DCA_SELECTED) { + if ([[self window] isKeyWindow] && ([[self window] firstResponder] == self)) + return [NSColor colorWithCalibratedRed:0.75 green:0.875 blue:1.0 alpha:1.0]; + else + return [NSColor colorWithCalibratedWhite:0.875 alpha:1.0]; + } else if (attrib & DCA_ANCILLARY) { + return [NSColor colorWithCalibratedWhite:0.75 alpha:1.0]; + } else { + return [NSColor colorWithCalibratedWhite:1.0 alpha:1.0]; + } +} + + +- (debug_view_xy)convertLocation:(NSPoint)location { + debug_view_xy position; + position.x = lround(floor(location.x / fontWidth)); + position.y = lround(floor(location.y / fontHeight)); + if (position.x < 0) + position.x = 0; + else if (position.x >= totalWidth) + position.x = totalWidth - 1; + if (position.y < 0) + position.y = 0; + else if (position.y >= totalHeight) + position.y = totalHeight - 1; + return position; +} + + +- (void)convertBounds:(NSRect)b toPosition:(debug_view_xy *)origin size:(debug_view_xy *)size { + origin->x = lround(floor(b.origin.x / fontWidth)); + origin->y = lround(floor(b.origin.y / fontHeight)); + size->x = lround(ceil((b.origin.x + b.size.width) / fontWidth)) - origin->x; + size->y = lround(ceil((b.origin.y + b.size.height) / fontHeight)) - origin->y; +} + + +- (void)recomputeVisible { + if ([self window] != nil) { + debug_view_xy origin, size; + + // this gets all the characters that are at least paritally visible + [self convertBounds:[self visibleRect] toPosition:&origin size:&size]; + + // need to render entire lines or we get screwed up characters when widening views + origin.x = 0; + size.x = totalWidth; + + // tell them what we think + view->set_visible_size(size); + view->set_visible_position(origin); + originLeft = origin.x; + originTop = origin.y; + } +} + + +- (void)typeCharacterAndScrollToCursor:(char)ch { + if (view->cursor_supported()) { + debug_view_xy oldPos = view->cursor_position(); + view->process_char(ch); + { + debug_view_xy newPos = view->cursor_position(); + if ((newPos.x != oldPos.x) || (newPos.y != oldPos.y)) { + [self scrollRectToVisible:NSMakeRect(newPos.x * fontWidth, + newPos.y * fontHeight, + fontWidth, + fontHeight)]; + } + } + } else { + view->process_char(ch); + } +} + + ++ (NSFont *)defaultFont { + // maybe we should get the configured system fixed-width font... + return [NSFont fontWithName:@"Monaco" size:10]; +} + + +- (id)initWithFrame:(NSRect)f type:(debug_view_type)t machine:(running_machine &)m { + if (!(self = [super initWithFrame:f])) + return nil; + type = t; + machine = &m; + view = machine->debug_view().alloc_view((debug_view_type)type, debugwin_view_update, self); + if (view == nil) { + [self release]; + return nil; + } + totalWidth = totalHeight = 0; + originLeft = originTop = 0; + [self setFont:[[self class] defaultFont]]; + return self; +} + + +- (void)dealloc { + [[NSNotificationCenter defaultCenter] removeObserver:self]; + if (font != nil) + [font release]; + [super dealloc]; +} + + +- (void)update { + debug_view_xy newSize, newOrigin; + + // resize our frame if the total size has changed + newSize = view->total_size(); + if ((newSize.x != totalWidth) || (newSize.y != totalHeight)) { + [self setFrameSize:NSMakeSize(fontWidth * newSize.x, fontHeight * newSize.y)]; + totalWidth = newSize.x; + totalHeight = newSize.y; + } + + // scroll the view if we're being told to + newOrigin = view->visible_position(); + if (newOrigin.y != originTop) { + [self scrollPoint:NSMakePoint([self visibleRect].origin.x, newOrigin.y * fontHeight)]; + originTop = newOrigin.y; + } + + // recompute the visible area and mark as dirty + [self recomputeVisible]; + [self setNeedsDisplay:YES]; +} + + +- (NSSize)maximumFrameSize { + debug_view_xy max = view->total_size(); + return NSMakeSize(max.x * fontWidth, max.y * fontHeight); +} + + +- (NSFont *)font { + return [[font retain] autorelease]; +} + + +- (void)setFont:(NSFont *)f { + [font autorelease]; + font = [f retain]; + fontWidth = [font maximumAdvancement].width; + fontHeight = ceil([font ascender] - [font descender]); + fontAscent = [font ascender]; + [[self enclosingScrollView] setLineScroll:fontHeight]; + totalWidth = totalHeight = 0; + [self update]; +} + + +- (void)windowDidBecomeKey:(NSNotification *)notification { + NSWindow *win = [notification object]; + if ((win == [self window]) && ([win firstResponder] == self) && view->cursor_supported()) + [self setNeedsDisplay:YES]; +} + + +- (void)windowDidResignKey:(NSNotification *)notification { + NSWindow *win = [notification object]; + if ((win == [self window]) && ([win firstResponder] == self) && view->cursor_supported()) + [self setNeedsDisplay:YES]; +} + + +- (BOOL)acceptsFirstResponder { + return view->cursor_supported(); +} + + +- (BOOL)becomeFirstResponder { + if (view->cursor_supported()) { + debug_view_xy pos; + view->set_cursor_visible(true); + pos = view->cursor_position(); + [self scrollRectToVisible:NSMakeRect(pos.x * fontWidth, pos.y * fontHeight, fontWidth, fontHeight)]; + [self setNeedsDisplay:YES]; + return [super becomeFirstResponder]; + } else { + return NO; + } +} + + +- (BOOL)resignFirstResponder { + if (view->cursor_supported()) + [self setNeedsDisplay:YES]; + return [super resignFirstResponder]; +} + + +- (void)viewDidMoveToSuperview { + [[self enclosingScrollView] setLineScroll:fontHeight]; + [super viewDidMoveToSuperview]; +} + + +- (void)viewDidMoveToWindow { + [[NSNotificationCenter defaultCenter] removeObserver:self name:NSWindowDidBecomeKeyNotification object:nil]; + [[NSNotificationCenter defaultCenter] removeObserver:self name:NSWindowDidResignKeyNotification object:nil]; + if ([self window] != nil) { + [[NSNotificationCenter defaultCenter] addObserver:self + selector:@selector(windowDidBecomeKey:) + name:NSWindowDidBecomeKeyNotification + object:[self window]]; + [[NSNotificationCenter defaultCenter] addObserver:self + selector:@selector(windowDidResignKey:) + name:NSWindowDidResignKeyNotification + object:[self window]]; + [self recomputeVisible]; + } +} + + +- (BOOL)isFlipped { + return YES; +} + + +- (void)drawRect:(NSRect)dirtyRect { + const debug_view_char *base; + debug_view_xy origin, size; + debug_view_xy position, clip; + NSMutableString *text; + NSMutableDictionary *attributes; + UINT32 pass, row, col; + + // work out how much we need to draw + [self recomputeVisible]; + origin = view->visible_position(); + size = view->visible_size(); + [self convertBounds:dirtyRect toPosition:&position size:&clip]; + + // this gets the text for the whole visible area + base = view->viewdata(); + if (!base) + return; + + text = [[NSMutableString alloc] initWithCapacity:clip.x]; + attributes = [[NSMutableDictionary alloc] initWithObjectsAndKeys:font, NSFontAttributeName, nil]; + for (pass = 0; pass < 2; pass++) { + const debug_view_char *data = base + ((position.y - origin.y) * size.x); + for (row = position.y; row < position.y + clip.y; row++, data += size.x) { + int attr = -1; + + if ((row < origin.y) || (row >= origin.y + size.y)) + continue; + + // render entire lines to get character alignment right + for (col = origin.x; col < origin.x + size.x; col++) { + if ((attr != data[col - origin.x].attrib) && ([text length] > 0)) { + if (pass == 0) { + [[self backgroundForAttribute:attr] set]; + [NSBezierPath fillRect:NSMakeRect((col - [text length]) * fontWidth, + row * fontHeight, + [text length] * fontWidth, + fontHeight)]; + } else { + [attributes setObject:[self foregroundForAttribute:attr] + forKey:NSForegroundColorAttributeName]; + [text drawAtPoint:NSMakePoint((col - [text length]) * fontWidth, row * fontHeight) + withAttributes:attributes]; + } + [text setString:@""]; + } + attr = data[col - origin.x].attrib; + [text appendFormat:@"%c", data[col - origin.x].byte]; + } + if ([text length] > 0) { + if (pass == 0) { + [[self backgroundForAttribute:attr] set]; + [NSBezierPath fillRect:NSMakeRect((col - [text length]) * fontWidth, + row * fontHeight, + [text length] * fontWidth, + fontHeight)]; + } else { + [attributes setObject:[self foregroundForAttribute:attr] + forKey:NSForegroundColorAttributeName]; + [text drawAtPoint:NSMakePoint((col - [text length]) * fontWidth, row * fontHeight) + withAttributes:attributes]; + } + [text setString:@""]; + } + } + } + [attributes release]; + [text release]; +} + + +- (void)mouseDown:(NSEvent *)event { + NSPoint location = [self convertPoint:[event locationInWindow] fromView:nil]; + if (view->cursor_supported()) { + view->set_cursor_position([self convertLocation:location]); + view->set_cursor_visible(true); + [self setNeedsDisplay:YES]; + } +} + + +- (void)mouseDragged:(NSEvent *)event { + NSPoint location = [self convertPoint:[event locationInWindow] fromView:nil]; + if (view->cursor_supported()) { + [self autoscroll:event]; + view->set_cursor_position([self convertLocation:location]); + [self setNeedsDisplay:YES]; + } +} + + +- (void)rightMouseDown:(NSEvent *)event { + NSPoint location = [self convertPoint:[event locationInWindow] fromView:nil]; + if (view->cursor_supported()) { + view->set_cursor_position([self convertLocation:location]); + view->set_cursor_visible(true); + [self setNeedsDisplay:YES]; + } + [super rightMouseDown:event]; +} + + +- (void)keyDown:(NSEvent *)event { + NSUInteger modifiers = [event modifierFlags]; + NSString *str = [event charactersIgnoringModifiers]; + + if ([str length] == 1) { + if (modifiers & NSNumericPadKeyMask) { + switch ([str characterAtIndex:0]) { + case NSUpArrowFunctionKey: + if (modifiers & NSCommandKeyMask) + view->process_char(DCH_CTRLHOME); + else + view->process_char(DCH_UP); + return; + case NSDownArrowFunctionKey: + if (modifiers & NSCommandKeyMask) + view->process_char(DCH_CTRLEND); + else + view->process_char(DCH_DOWN); + return; + case NSLeftArrowFunctionKey: + if (modifiers & NSCommandKeyMask) + [self typeCharacterAndScrollToCursor:DCH_HOME]; + else if (modifiers & NSAlternateKeyMask) + [self typeCharacterAndScrollToCursor:DCH_CTRLLEFT]; + else + [self typeCharacterAndScrollToCursor:DCH_LEFT]; + return; + case NSRightArrowFunctionKey: + if (modifiers & NSCommandKeyMask) + [self typeCharacterAndScrollToCursor:DCH_END]; + else if (modifiers & NSAlternateKeyMask) + [self typeCharacterAndScrollToCursor:DCH_CTRLRIGHT]; + else + [self typeCharacterAndScrollToCursor:DCH_RIGHT]; + return; + default: + [self interpretKeyEvents:[NSArray arrayWithObject:event]]; + return; + } + } else if (modifiers & NSFunctionKeyMask) { + switch ([str characterAtIndex:0]) { + case NSPageUpFunctionKey: + if (modifiers & NSAlternateKeyMask) { + view->process_char(DCH_PUP); + return; + } + case NSPageDownFunctionKey: + if (modifiers & NSAlternateKeyMask) { + view->process_char(DCH_PDOWN); + return; + } + default: + ; + } + [super keyDown:event]; + return; + } + } + [self interpretKeyEvents:[NSArray arrayWithObject:event]]; +} + + +- (void)insertTab:(id)sender { + if ([[self window] firstResponder] == self) + [[self window] selectNextKeyView:self]; +} + + +- (void)insertBacktab:(id)sender { + if ([[self window] firstResponder] == self) + [[self window] selectPreviousKeyView:self]; +} + + +- (void)insertNewline:(id)sender { + debug_cpu_get_visible_cpu(*machine)->debug()->single_step(); +} + + +- (void)insertText:(id)string { + NSUInteger len; + NSRange found; + if ([string isKindOfClass:[NSAttributedString class]]) + string = [string string]; + for (len = [string length], found = NSMakeRange(0, 0); + found.location < len; + found.location += found.length) { + found = [string rangeOfComposedCharacterSequenceAtIndex:found.location]; + if (found.length == 1) { + unichar ch = [string characterAtIndex:found.location]; + if ((ch >= 32) && (ch < 127)) + [self typeCharacterAndScrollToCursor:ch]; + } + } +} + +@end diff --git a/src/osd/modules/debugger/osx/debugosxdebugwindowhandler.h b/src/osd/modules/debugger/osx/debugosxdebugwindowhandler.h new file mode 100644 index 00000000000..35f8be2b67b --- /dev/null +++ b/src/osd/modules/debugger/osx/debugosxdebugwindowhandler.h @@ -0,0 +1,96 @@ +// license:BSD-3-Clause +// copyright-holders:Vas Crabb +//============================================================ +// +// debugosxdebugwindowhandler.h - MacOS X Cocoa debug window handling +// +// Copyright (c) 1996-2015, Nicola Salmoria and the MAME Team. +// Visit http://mamedev.org for licensing and usage restrictions. +// +//============================================================ + +#import "debugosx.h" + +#include "emu.h" + +#import + + +@protocol MAMEDebugViewExpressionSupport; +@class MAMEDebugCommandHistory, MAMEDebugConsole; + + +extern NSString *const MAMEHideDebuggerNotification; +extern NSString *const MAMEShowDebuggerNotification; +extern NSString *const MAMEAuxiliaryDebugWindowWillCloseNotification; + + +@interface MAMEDebugWindowHandler : NSObject +{ + NSWindow *window; + running_machine *machine; +} + ++ (void)addCommonActionItems:(NSMenu *)menu; ++ (NSPopUpButton *)newActionButtonWithFrame:(NSRect)frame; + +- (id)initWithMachine:(running_machine &)m title:(NSString *)t; + +- (void)activate; + +- (IBAction)debugRun:(id)sender; +- (IBAction)debugRunAndHide:(id)sender; +- (IBAction)debugRunToNextCPU:(id)sender; +- (IBAction)debugRunToNextInterrupt:(id)sender; +- (IBAction)debugRunToNextVBLANK:(id)sender; + +- (IBAction)debugStepInto:(id)sender; +- (IBAction)debugStepOver:(id)sender; +- (IBAction)debugStepOut:(id)sender; + +- (IBAction)debugSoftReset:(id)sender; +- (IBAction)debugHardReset:(id)sender; + +- (IBAction)debugExit:(id)sender; + +- (void)showDebugger:(NSNotification *)notification; +- (void)hideDebugger:(NSNotification *)notification; + +@end + + +@interface MAMEAuxiliaryDebugWindowHandler : MAMEDebugWindowHandler +{ + MAMEDebugConsole *console; +} + ++ (void)cascadeWindow:(NSWindow *)window; + +- (id)initWithMachine:(running_machine &)m title:(NSString *)t console:(MAMEDebugConsole *)c; + +- (IBAction)debugNewMemoryWindow:(id)sender; +- (IBAction)debugNewDisassemblyWindow:(id)sender; +- (IBAction)debugNewErrorLogWindow:(id)sender; + +- (void)windowWillClose:(NSNotification *)notification; + +- (void)cascadeWindowWithDesiredSize:(NSSize)desired forView:(NSView *)view; + +@end + + +@interface MAMEExpressionAuxiliaryDebugWindowHandler : MAMEAuxiliaryDebugWindowHandler +{ + MAMEDebugCommandHistory *history; + NSTextField *expressionField; +} + +- (id)initWithMachine:(running_machine &)m title:(NSString *)t console:(MAMEDebugConsole *)c; + +- (id )documentView; + +- (IBAction)doExpression:(id)sender; + +- (BOOL)control:(NSControl *)control textView:(NSTextView *)textView doCommandBySelector:(SEL)command; + +@end diff --git a/src/osd/modules/debugger/osx/debugosxdebugwindowhandler.m b/src/osd/modules/debugger/osx/debugosxdebugwindowhandler.m new file mode 100644 index 00000000000..d5382c19454 --- /dev/null +++ b/src/osd/modules/debugger/osx/debugosxdebugwindowhandler.m @@ -0,0 +1,386 @@ +// license:BSD-3-Clause +// copyright-holders:Vas Crabb +//============================================================ +// +// debugosxdebugwindowhandler.m - MacOS X Cocoa debug window handling +// +// Copyright (c) 1996-2015, Nicola Salmoria and the MAME Team. +// Visit http://mamedev.org for licensing and usage restrictions. +// +//============================================================ + +#import "debugosxdebugwindowhandler.h" + +#import "debugosxdebugcommandhistory.h" +#import "debugosxdebugview.h" + +#include "debug/debugcpu.h" + + +//============================================================ +// NOTIFICATIONS +//============================================================ + +NSString *const MAMEHideDebuggerNotification = @"MAMEHideDebuggerNotification"; +NSString *const MAMEShowDebuggerNotification = @"MAMEShowDebuggerNotification"; +NSString *const MAMEAuxiliaryDebugWindowWillCloseNotification = @"MAMEAuxiliaryDebugWindowWillCloseNotification"; + + +//============================================================ +// MAMEDebugWindowHandler class +//============================================================ + +@implementation MAMEDebugWindowHandler + ++ (void)addCommonActionItems:(NSMenu *)menu { + { + NSMenuItem *runParentItem = [menu addItemWithTitle:@"Run" + action:@selector(debugRun:) + keyEquivalent:[NSString stringWithFormat:@"%C", (short)NSF5FunctionKey]]; + NSMenu *runMenu = [[NSMenu allocWithZone:[NSMenu menuZone]] initWithTitle:@"Run"]; + [runParentItem setSubmenu:runMenu]; + [runMenu release]; + [runParentItem setKeyEquivalentModifierMask:0]; + [[runMenu addItemWithTitle:@"and Hide Debugger" + action:@selector(debugRunAndHide:) + keyEquivalent:[NSString stringWithFormat:@"%C", (short)NSF12FunctionKey]] + setKeyEquivalentModifierMask:0]; + [[runMenu addItemWithTitle:@"to Next CPU" + action:@selector(debugRunToNextCPU:) + keyEquivalent:[NSString stringWithFormat:@"%C", (short)NSF6FunctionKey]] + setKeyEquivalentModifierMask:0]; + [[runMenu addItemWithTitle:@"until Next Interrupt on Current CPU" + action:@selector(debugRunToNextInterrupt:) + keyEquivalent:[NSString stringWithFormat:@"%C", (short)NSF7FunctionKey]] + setKeyEquivalentModifierMask:0]; + [[runMenu addItemWithTitle:@"until Next VBLANK" + action:@selector(debugRunToNextVBLANK:) + keyEquivalent:[NSString stringWithFormat:@"%C", (short)NSF8FunctionKey]] + setKeyEquivalentModifierMask:0]; + } + { + NSMenuItem *stepParentItem = [menu addItemWithTitle:@"Step" action:NULL keyEquivalent:@""]; + NSMenu *stepMenu = [[NSMenu allocWithZone:[NSMenu menuZone]] initWithTitle:@"Step"]; + [stepParentItem setSubmenu:stepMenu]; + [stepMenu release]; + [[stepMenu addItemWithTitle:@"Into" + action:@selector(debugStepInto:) + keyEquivalent:[NSString stringWithFormat:@"%C", (short)NSF11FunctionKey]] + setKeyEquivalentModifierMask:0]; + [[stepMenu addItemWithTitle:@"Over" + action:@selector(debugStepOver:) + keyEquivalent:[NSString stringWithFormat:@"%C", (short)NSF10FunctionKey]] + setKeyEquivalentModifierMask:0]; + [[stepMenu addItemWithTitle:@"Out" + action:@selector(debugStepOut:) + keyEquivalent:[NSString stringWithFormat:@"%C", (short)NSF10FunctionKey]] + setKeyEquivalentModifierMask:NSShiftKeyMask]; + } + { + NSMenuItem *resetParentItem = [menu addItemWithTitle:@"Reset" action:NULL keyEquivalent:@""]; + NSMenu *resetMenu = [[NSMenu allocWithZone:[NSMenu menuZone]] initWithTitle:@"Reset"]; + [resetParentItem setSubmenu:resetMenu]; + [resetMenu release]; + [[resetMenu addItemWithTitle:@"Soft" + action:@selector(debugSoftReset:) + keyEquivalent:[NSString stringWithFormat:@"%C", (short)NSF3FunctionKey]] + setKeyEquivalentModifierMask:0]; + [[resetMenu addItemWithTitle:@"Hard" + action:@selector(debugHardReset:) + keyEquivalent:[NSString stringWithFormat:@"%C", (short)NSF3FunctionKey]] + setKeyEquivalentModifierMask:NSShiftKeyMask]; + } + [menu addItem:[NSMenuItem separatorItem]]; + { + NSMenuItem *newParentItem = [menu addItemWithTitle:@"New" action:NULL keyEquivalent:@""]; + NSMenu *newMenu = [[NSMenu allocWithZone:[NSMenu menuZone]] initWithTitle:@"New"]; + [newParentItem setSubmenu:newMenu]; + [newMenu release]; + [newMenu addItemWithTitle:@"Memory Window" + action:@selector(debugNewMemoryWindow:) + keyEquivalent:@"d"]; + [newMenu addItemWithTitle:@"Disassembly Window" + action:@selector(debugNewDisassemblyWindow:) + keyEquivalent:@"a"]; + [newMenu addItemWithTitle:@"Error Log Window" + action:@selector(debugNewErrorLogWindow:) + keyEquivalent:@"l"]; + } + [menu addItem:[NSMenuItem separatorItem]]; + [menu addItemWithTitle:@"Close Window" action:@selector(performClose:) keyEquivalent:@"w"]; + [menu addItemWithTitle:@"Exit" action:@selector(debugExit:) keyEquivalent:@""]; +} + + ++ (NSPopUpButton *)newActionButtonWithFrame:(NSRect)frame { + NSPopUpButton *actionButton = [[NSPopUpButton alloc] initWithFrame:frame pullsDown:YES]; + [actionButton setTitle:@""]; + [actionButton addItemWithTitle:@""]; + [actionButton setBezelStyle:NSShadowlessSquareBezelStyle]; + [actionButton setFocusRingType:NSFocusRingTypeNone]; + [[actionButton cell] setArrowPosition:NSPopUpArrowAtCenter]; + [[self class] addCommonActionItems:[actionButton menu]]; + return actionButton; +} + + +- (id)initWithMachine:(running_machine &)m title:(NSString *)t { + if (!(self = [super init])) + return nil; + + window = [[NSWindow alloc] initWithContentRect:NSMakeRect(0, 0, 320, 240) + styleMask:(NSTitledWindowMask | + NSClosableWindowMask | + NSMiniaturizableWindowMask | + NSResizableWindowMask) + backing:NSBackingStoreBuffered + defer:YES]; + [window setReleasedWhenClosed:NO]; + [window setDelegate:self]; + [window setTitle:t]; + [window setContentMinSize:NSMakeSize(320, 240)]; + + [[NSNotificationCenter defaultCenter] addObserver:self + selector:@selector(showDebugger:) + name:MAMEShowDebuggerNotification + object:nil]; + [[NSNotificationCenter defaultCenter] addObserver:self + selector:@selector(hideDebugger:) + name:MAMEHideDebuggerNotification + object:nil]; + + machine = &m; + + return self; +} + + +- (void)dealloc { + [[NSNotificationCenter defaultCenter] removeObserver:self]; + + if (window != nil) + [window release]; + + [super dealloc]; +} + + +- (void)activate { + [window makeKeyAndOrderFront:self]; +} + + +- (IBAction)debugRun:(id)sender { + debug_cpu_get_visible_cpu(*machine)->debug()->go(); +} + + +- (IBAction)debugRunAndHide:(id)sender { + [[NSNotificationCenter defaultCenter] postNotificationName:MAMEHideDebuggerNotification object:self]; + debug_cpu_get_visible_cpu(*machine)->debug()->go(); +} + + +- (IBAction)debugRunToNextCPU:(id)sender { + debug_cpu_get_visible_cpu(*machine)->debug()->go_next_device(); +} + + +- (IBAction)debugRunToNextInterrupt:(id)sender { + debug_cpu_get_visible_cpu(*machine)->debug()->go_interrupt(); +} + + +- (IBAction)debugRunToNextVBLANK:(id)sender { + debug_cpu_get_visible_cpu(*machine)->debug()->go_vblank(); +} + + +- (IBAction)debugStepInto:(id)sender { + debug_cpu_get_visible_cpu(*machine)->debug()->single_step(); +} + + +- (IBAction)debugStepOver:(id)sender { + debug_cpu_get_visible_cpu(*machine)->debug()->single_step_over(); +} + + +- (IBAction)debugStepOut:(id)sender { + debug_cpu_get_visible_cpu(*machine)->debug()->single_step_out(); +} + + +- (IBAction)debugSoftReset:(id)sender { + machine->schedule_soft_reset(); + debug_cpu_get_visible_cpu(*machine)->debug()->go(); +} + + +- (IBAction)debugHardReset:(id)sender { + machine->schedule_hard_reset(); +} + + +- (IBAction)debugExit:(id)sender { + machine->schedule_exit(); +} + + +- (void)showDebugger:(NSNotification *)notification { + device_t *device = (device_t *) [[[notification userInfo] objectForKey:@"MAMEDebugDevice"] pointerValue]; + if (&device->machine() == machine) { + if (![window isVisible] && ![window isMiniaturized]) + [window orderFront:self]; + } +} + + +- (void)hideDebugger:(NSNotification *)notification { + [window orderOut:self]; +} + +@end + + +//============================================================ +// MAMEAuxiliaryDebugWindowHandler class +//============================================================ + +@implementation MAMEAuxiliaryDebugWindowHandler + ++ (void)cascadeWindow:(NSWindow *)window { + static NSPoint lastPosition = { 0, 0 }; + if (NSEqualPoints(lastPosition, NSZeroPoint)) { + NSRect available = [[NSScreen mainScreen] visibleFrame]; + lastPosition = NSMakePoint(available.origin.x + 12, available.origin.y + available.size.height - 8); + } + lastPosition = [window cascadeTopLeftFromPoint:lastPosition]; +} + + +- (id)initWithMachine:(running_machine &)m title:(NSString *)t console:(MAMEDebugConsole *)c { + if (!(self = [super initWithMachine:m title:t])) + return nil; + console = c; + return self; +} + + +- (void)dealloc { + [super dealloc]; +} + + +- (IBAction)debugNewMemoryWindow:(id)sender { + [console debugNewMemoryWindow:sender]; +} + + +- (IBAction)debugNewDisassemblyWindow:(id)sender { + [console debugNewDisassemblyWindow:sender]; +} + + +- (IBAction)debugNewErrorLogWindow:(id)sender { + [console debugNewErrorLogWindow:sender]; +} + + +- (void)windowWillClose:(NSNotification *)notification { + [[NSNotificationCenter defaultCenter] postNotificationName:MAMEAuxiliaryDebugWindowWillCloseNotification + object:self]; +} + +- (void)cascadeWindowWithDesiredSize:(NSSize)desired forView:(NSView *)view { + NSRect available = [[NSScreen mainScreen] visibleFrame]; + NSRect windowFrame = [window frame]; + NSSize current = [view frame].size; + + desired.width -= current.width; + desired.height -= current.height; + + windowFrame.size.width += desired.width; + windowFrame.size.height += desired.height; + windowFrame.size.height = MIN(MIN(windowFrame.size.height, 240), available.size.height); + windowFrame.size.width = MIN(windowFrame.size.width, available.size.width); + windowFrame.origin.x = available.origin.x + available.size.width - windowFrame.size.width; + windowFrame.origin.y = available.origin.y; + [window setFrame:windowFrame display:YES]; + [[self class] cascadeWindow:window]; + + windowFrame = [[window contentView] frame]; + desired = [window contentMinSize]; + [window setContentMinSize:NSMakeSize(MIN(windowFrame.size.width, desired.width), + MIN(windowFrame.size.height, desired.height))]; +} + +@end + + +//============================================================ +// MAMEExpreesionAuxiliaryDebugWindowHandler class +//============================================================ + +@implementation MAMEExpressionAuxiliaryDebugWindowHandler + +- (id)initWithMachine:(running_machine &)m title:(NSString *)t console:(MAMEDebugConsole *)c { + if (!(self = [super initWithMachine:m title:t console:c])) + return nil; + history = [[MAMEDebugCommandHistory alloc] init]; + return self; +} + + +- (void)dealloc { + if (history != nil) + [history release]; + [super dealloc]; +} + + +- (id )documentView { + return nil; +} + + +- (IBAction)doExpression:(id)sender { + NSString *expr = [sender stringValue]; + if ([expr length] > 0) { + [history add:expr]; + [[self documentView] setExpression:expr]; + } else { + [sender setStringValue:[[self documentView] expression]]; + [history reset]; + } + [sender selectText:self]; +} + + +- (BOOL)control:(NSControl *)control textView:(NSTextView *)textView doCommandBySelector:(SEL)command { + if (control == expressionField) { + if (command == @selector(cancelOperation:)) { + [history reset]; + [expressionField setStringValue:[[self documentView] expression]]; + [expressionField selectText:self]; + return YES; + } else if (command == @selector(moveUp:)) { + NSString *hist = [history previous:[expressionField stringValue]]; + if (hist != nil) { + [expressionField setStringValue:hist]; + [expressionField selectText:self]; + } + return YES; + } else if (command == @selector(moveDown:)) { + NSString *hist = [history next:[expressionField stringValue]]; + if (hist != nil) { + [expressionField setStringValue:hist]; + [expressionField selectText:self]; + } + return YES; + } + } + return NO; +} + +@end \ No newline at end of file diff --git a/src/osd/modules/debugger/osx/debugosxdisassemblyview.h b/src/osd/modules/debugger/osx/debugosxdisassemblyview.h new file mode 100644 index 00000000000..32e61a967e6 --- /dev/null +++ b/src/osd/modules/debugger/osx/debugosxdisassemblyview.h @@ -0,0 +1,46 @@ +// license:BSD-3-Clause +// copyright-holders:Vas Crabb +//============================================================ +// +// debugosxdisassemblyview.h - MacOS X Cocoa debug window handling +// +// Copyright (c) 1996-2015, Nicola Salmoria and the MAME Team. +// Visit http://mamedev.org for licensing and usage restrictions. +// +//============================================================ + +#import "debugosx.h" +#import "debugosxdebugview.h" + +#include "emu.h" + +#import + + +@interface MAMEDisassemblyView : MAMEDebugView +{ + BOOL useConsole; +} + +- (id)initWithFrame:(NSRect)f machine:(running_machine &)m useConsole:(BOOL)uc; + +- (NSSize)maximumFrameSize; + +- (NSString *)selectedSubviewName; +- (int)selectedSubviewIndex; +- (void)selectSubviewAtIndex:(int)index; +- (void)selectSubviewForCPU:(device_t *)device; + +- (NSString *)expression; +- (void)setExpression:(NSString *)exp; + +- (IBAction)debugToggleBreakpoint:(id)sender; +- (IBAction)debugToggleBreakpointEnable:(id)sender; +- (IBAction)debugRunToCursor:(id)sender; + +- (IBAction)showRightColumn:(id)sender; + +- (void)insertActionItemsInMenu:(NSMenu *)menu atIndex:(NSInteger)index; +- (void)insertSubviewItemsInMenu:(NSMenu *)menu atIndex:(NSInteger)index; + +@end diff --git a/src/osd/modules/debugger/osx/debugosxdisassemblyview.m b/src/osd/modules/debugger/osx/debugosxdisassemblyview.m new file mode 100644 index 00000000000..af0242b20b4 --- /dev/null +++ b/src/osd/modules/debugger/osx/debugosxdisassemblyview.m @@ -0,0 +1,371 @@ +// license:BSD-3-Clause +// copyright-holders:Vas Crabb +//============================================================ +// +// debugosxdisassemblyview.m - MacOS X Cocoa debug window handling +// +// Copyright (c) 1996-2015, Nicola Salmoria and the MAME Team. +// Visit http://mamedev.org for licensing and usage restrictions. +// +//============================================================ + +#import "debugosxdisassemblyview.h" + +#include "emucore.h" +#include "debug/debugcon.h" +#include "debug/debugcpu.h" +#include "debug/debugvw.h" +#include "debug/dvdisasm.h" + + +@implementation MAMEDisassemblyView + +- (device_debug::breakpoint *)findBreakpointAtAddress:(offs_t)address inAddressSpace:(address_space &)space { + device_debug *cpuinfo = space.device().debug(); + device_debug::breakpoint *bp; + for (bp = cpuinfo->breakpoint_first(); (bp != NULL) && (address != bp->address()); bp = bp->next()) {} + return bp; +} + +- (void)createContextMenu { + NSMenu *contextMenu = [[NSMenu allocWithZone:[NSMenu menuZone]] initWithTitle:@"Disassembly"]; + NSMenuItem *item; + + item = [contextMenu addItemWithTitle:@"Toggle Breakpoint" + action:@selector(debugToggleBreakpoint:) + keyEquivalent:[NSString stringWithFormat:@"%C", (short)NSF9FunctionKey]]; + [item setKeyEquivalentModifierMask:0]; + [item setTarget:self]; + + item = [contextMenu addItemWithTitle:@"Disable Breakpoint" + action:@selector(debugToggleBreakpointEnable:) + keyEquivalent:[NSString stringWithFormat:@"%C", (short)NSF9FunctionKey]]; + [item setKeyEquivalentModifierMask:NSShiftKeyMask]; + [item setTarget:self]; + + [contextMenu addItem:[NSMenuItem separatorItem]]; + + item = [contextMenu addItemWithTitle:@"Run to Cursor" + action:@selector(debugRunToCursor:) + keyEquivalent:[NSString stringWithFormat:@"%C", (short)NSF4FunctionKey]]; + [item setKeyEquivalentModifierMask:0]; + [item setTarget:self]; + + [contextMenu addItem:[NSMenuItem separatorItem]]; + + item = [contextMenu addItemWithTitle:@"Raw Opcodes" + action:@selector(showRightColumn:) + keyEquivalent:@"r"]; + [item setTarget:self]; + [item setTag:DASM_RIGHTCOL_RAW]; + + item = [contextMenu addItemWithTitle:@"Encrypted Opcodes" + action:@selector(showRightColumn:) + keyEquivalent:@"e"]; + [item setTarget:self]; + [item setTag:DASM_RIGHTCOL_ENCRYPTED]; + + item = [contextMenu addItemWithTitle:@"Comments" + action:@selector(showRightColumn:) + keyEquivalent:@"n"]; + [item setTarget:self]; + [item setTag:DASM_RIGHTCOL_COMMENTS]; + + [self setMenu:contextMenu]; + [contextMenu release]; +} + + +- (id)initWithFrame:(NSRect)f machine:(running_machine &)m useConsole:(BOOL)uc { + if (!(self = [super initWithFrame:f type:DVT_DISASSEMBLY machine:m])) + return nil; + useConsole = uc; + [self createContextMenu]; + return self; +} + + +- (void)dealloc { + [super dealloc]; +} + + +- (BOOL)validateMenuItem:(NSMenuItem *)item { + SEL action = [item action]; + BOOL inContextMenu = ([item menu] == [self menu]); + BOOL haveCursor = NO, isCurrent = NO; + device_debug::breakpoint *breakpoint = NULL; + + if (view->cursor_visible()) { + if (debug_cpu_get_visible_cpu(*machine) == view->source()->device()) { + isCurrent = YES; + if (!useConsole || isCurrent) { + offs_t address = downcast(view)->selected_address(); + haveCursor = YES; + breakpoint = [self findBreakpointAtAddress:address inAddressSpace:downcast(view->source())->space()]; + } + } + } + + if (action == @selector(debugToggleBreakpoint:)) { + if (haveCursor) { + if (breakpoint != NULL) { + if (inContextMenu) + [item setTitle:@"Clear Breakpoint"]; + else + [item setTitle:@"Clear Breakpoint at Cursor"]; + } else { + if (inContextMenu) + [item setTitle:@"Set Breakpoint"]; + else + [item setTitle:@"Set Breakpoint at Cursor"]; + } + } else { + if (inContextMenu) + [item setTitle:@"Toggle Breakpoint"]; + else + [item setTitle:@"Toggle Breakpoint at Cursor"]; + } + return haveCursor; + } else if (action == @selector(debugToggleBreakpointEnable:)) { + if ((breakpoint != NULL) && !breakpoint->enabled()) { + if (inContextMenu) + [item setTitle:@"Enable Breakpoint"]; + else + [item setTitle:@"Enable Breakpoint at Cursor"]; + } else { + if (inContextMenu) + [item setTitle:@"Disable Breakpoint"]; + else + [item setTitle:@"Disable Breakpoint at Cursor"]; + } + return (breakpoint != NULL); + } else if (action == @selector(debugRunToCursor:)) { + return isCurrent; + } else if (action == @selector(showRightColumn:)) { + [item setState:((downcast(view)->right_column() == [item tag]) ? NSOnState : NSOffState)]; + return YES; + } else { + return YES; + } +} + + +- (NSSize)maximumFrameSize { + debug_view_xy max; + device_t *curcpu = debug_cpu_get_visible_cpu(*machine); + const debug_view_source *source = view->source_for_device(curcpu); + + max.x = max.y = 0; + for (const debug_view_source *source = view->source_list().first(); source != NULL; source = source->next()) + { + debug_view_xy current; + view->set_source(*source); + current = view->total_size(); + if (current.x > max.x) + max.x = current.x; + if (current.y > max.y) + max.y = current.y; + } + view->set_source(*source); + return NSMakeSize(max.x * fontWidth, max.y * fontHeight); +} + + +- (NSString *)selectedSubviewName { + const debug_view_source *source = view->source(); + if (source != NULL) + return [NSString stringWithUTF8String:source->name()]; + else + return @""; +} + + +- (int)selectedSubviewIndex { + const debug_view_source *source = view->source(); + if (source != NULL) + return view->source_list().indexof(*source); + else + return -1; +} + + +- (void)selectSubviewAtIndex:(int)index { + const int selected = view->source_list().indexof(*view->source()); + if (selected != index) { + view->set_source(*view->source_list().find(index)); + if ([[self window] firstResponder] != self) + view->set_cursor_visible(false); + } +} + + +- (void)selectSubviewForCPU:(device_t *)device { + const debug_view_source *selected = view->source(); + const debug_view_source *source = view->source_for_device(device); + if ( selected != source ) { + view->set_source(*source); + if ([[self window] firstResponder] != self) + view->set_cursor_visible(false); + } +} + + +- (NSString *)expression { + return [NSString stringWithUTF8String:downcast(view)->expression()]; +} + + +- (void)setExpression:(NSString *)exp { + downcast(view)->set_expression([exp UTF8String]); +} + + +- (IBAction)debugToggleBreakpoint:(id)sender { + if (view->cursor_visible()) { + address_space &space = downcast(view->source())->space(); + if (!useConsole || (debug_cpu_get_visible_cpu(*machine) == &space.device())) { + offs_t address = downcast(view)->selected_address(); + device_debug::breakpoint *bp = [self findBreakpointAtAddress:address inAddressSpace:space]; + + // if it doesn't exist, add a new one + if (useConsole) { + NSString *command; + if (bp == NULL) + command = [NSString stringWithFormat:@"bpset %lX", (unsigned long)address]; + else + command = [NSString stringWithFormat:@"bpclear %X", (unsigned)bp->index()]; + debug_console_execute_command(*machine, [command UTF8String], 1); + } else { + if (bp == NULL) + space.device().debug()->breakpoint_set(address, NULL, NULL); + else + space.device().debug()->breakpoint_clear(bp->index()); + } + } + } +} + + +- (IBAction)debugToggleBreakpointEnable:(id)sender { + if (view->cursor_visible()) { + address_space &space = downcast(view->source())->space(); + if (!useConsole || (debug_cpu_get_visible_cpu(*machine) == &space.device())) { + offs_t address = downcast(view)->selected_address(); + device_debug::breakpoint *bp = [self findBreakpointAtAddress:address inAddressSpace:space]; + + if (bp != NULL) { + NSString *command; + if (useConsole) { + if (bp->enabled()) + command = [NSString stringWithFormat:@"bpdisable %X", (unsigned)bp->index()]; + else + command = [NSString stringWithFormat:@"bpenable %X", (unsigned)bp->index()]; + debug_console_execute_command(*machine, [command UTF8String], 1); + } else { + space.device().debug()->breakpoint_enable(bp->index(), !bp->enabled()); + } + } + } + } +} + + +- (IBAction)debugRunToCursor:(id)sender { + if (view->cursor_visible()) { + address_space &space = downcast(view->source())->space(); + if (debug_cpu_get_visible_cpu(*machine) == &space.device()) { + offs_t address = downcast(view)->selected_address(); + if (useConsole) { + NSString *command = [NSString stringWithFormat:@"go 0x%lX", (unsigned long)address]; + debug_console_execute_command(*machine, [command UTF8String], 1); + } else { + debug_cpu_get_visible_cpu(*machine)->debug()->go(address); + } + } + } +} + + +- (IBAction)showRightColumn:(id)sender { + downcast(view)->set_right_column((disasm_right_column) [sender tag]); +} + + +- (void)insertActionItemsInMenu:(NSMenu *)menu atIndex:(NSInteger)index { + { + NSMenuItem *breakItem = [menu insertItemWithTitle:@"Toggle Breakpoint at Cursor" + action:@selector(debugToggleBreakpoint:) + keyEquivalent:[NSString stringWithFormat:@"%C", (short)NSF9FunctionKey] + atIndex:index++]; + [breakItem setKeyEquivalentModifierMask:0]; + [breakItem setTarget:self]; + } + { + NSMenuItem *disableItem = [menu insertItemWithTitle:@"Disable Breakpoint at Cursor" + action:@selector(debugToggleBreakpointEnable:) + keyEquivalent:[NSString stringWithFormat:@"%C", (short)NSF9FunctionKey] + atIndex:index++]; + [disableItem setKeyEquivalentModifierMask:NSShiftKeyMask]; + [disableItem setAlternate:YES]; + [disableItem setTarget:self]; + } + { + NSMenu *runMenu = [[menu itemWithTitle:@"Run"] submenu]; + NSMenuItem *runItem; + if (runMenu != nil) { + runItem = [runMenu addItemWithTitle:@"to Cursor" + action:@selector(debugRunToCursor:) + keyEquivalent:[NSString stringWithFormat:@"%C", (short)NSF4FunctionKey]]; + } else { + runItem = [menu insertItemWithTitle:@"Run to Cursor" + action:@selector(debugRunToCursor:) + keyEquivalent:[NSString stringWithFormat:@"%C", (short)NSF4FunctionKey] + atIndex:index++]; + } + [runItem setKeyEquivalentModifierMask:0]; + [runItem setTarget:self]; + } + [menu insertItem:[NSMenuItem separatorItem] atIndex:index++]; + { + NSMenuItem *rawItem = [menu insertItemWithTitle:@"Show Raw Opcodes" + action:@selector(showRightColumn:) + keyEquivalent:@"r" + atIndex:index++]; + [rawItem setTarget:self]; + [rawItem setTag:DASM_RIGHTCOL_RAW]; + } + { + NSMenuItem *encItem = [menu insertItemWithTitle:@"Show Encrypted Opcodes" + action:@selector(showRightColumn:) + keyEquivalent:@"e" + atIndex:index++]; + [encItem setTarget:self]; + [encItem setTag:DASM_RIGHTCOL_ENCRYPTED]; + } + { + NSMenuItem *commentsItem = [menu insertItemWithTitle:@"Show Comments" + action:@selector(showRightColumn:) + keyEquivalent:@"n" + atIndex:index++]; + [commentsItem setTarget:self]; + [commentsItem setTag:DASM_RIGHTCOL_COMMENTS]; + } + if (index < [menu numberOfItems]) + [menu insertItem:[NSMenuItem separatorItem] atIndex:index++]; +} + + +- (void)insertSubviewItemsInMenu:(NSMenu *)menu atIndex:(NSInteger)index { + for (const debug_view_source *source = view->source_list().first(); source != NULL; source = source->next()) + { + [[menu insertItemWithTitle:[NSString stringWithUTF8String:source->name()] + action:NULL + keyEquivalent:@"" + atIndex:index++] setTag:view->source_list().indexof(*source)]; + } + if (index < [menu numberOfItems]) + [menu insertItem:[NSMenuItem separatorItem] atIndex:index++]; +} + +@end diff --git a/src/osd/modules/debugger/osx/debugosxdisassemblyviewer.h b/src/osd/modules/debugger/osx/debugosxdisassemblyviewer.h new file mode 100644 index 00000000000..fa4f76bd813 --- /dev/null +++ b/src/osd/modules/debugger/osx/debugosxdisassemblyviewer.h @@ -0,0 +1,31 @@ +// license:BSD-3-Clause +// copyright-holders:Vas Crabb +//============================================================ +// +// debugosxdisassemblyviewer.h - MacOS X Cocoa debug window handling +// +// Copyright (c) 1996-2015, Nicola Salmoria and the MAME Team. +// Visit http://mamedev.org for licensing and usage restrictions. +// +//============================================================ + +#import "debugosx.h" +#import "debugosxdebugwindowhandler.h" + +#include "emu.h" + +#import + + +@class MAMEDebugConsole, MAMEDisassemblyView; + +@interface MAMEDisassemblyViewer : MAMEExpressionAuxiliaryDebugWindowHandler +{ + MAMEDisassemblyView *dasmView; +} + +- (id)initWithMachine:(running_machine &)m console:(MAMEDebugConsole *)c; + +- (IBAction)changeSubview:(id)sender; + +@end diff --git a/src/osd/modules/debugger/osx/debugosxdisassemblyviewer.m b/src/osd/modules/debugger/osx/debugosxdisassemblyviewer.m new file mode 100644 index 00000000000..3a965fe1404 --- /dev/null +++ b/src/osd/modules/debugger/osx/debugosxdisassemblyviewer.m @@ -0,0 +1,138 @@ +// license:BSD-3-Clause +// copyright-holders:Vas Crabb +//============================================================ +// +// debugosxdisassemblyviewer.m - MacOS X Cocoa debug window handling +// +// Copyright (c) 1996-2015, Nicola Salmoria and the MAME Team. +// Visit http://mamedev.org for licensing and usage restrictions. +// +//============================================================ + +#import "debugosxdisassemblyviewer.h" + +#import "debugosxdebugview.h" +#import "debugosxdisassemblyview.h" + +#include "debug/debugcpu.h" + + +@implementation MAMEDisassemblyViewer + +- (id)initWithMachine:(running_machine &)m console:(MAMEDebugConsole *)c { + NSScrollView *dasmScroll; + NSView *expressionContainer; + NSPopUpButton *actionButton, *subviewButton; + NSRect contentBounds, expressionFrame; + + if (!(self = [super initWithMachine:m title:@"Disassembly" console:c])) + return nil; + contentBounds = [[window contentView] bounds]; + + // create the expression field + expressionField = [[NSTextField alloc] initWithFrame:NSMakeRect(0, 0, 100, 19)]; + [expressionField setAutoresizingMask:(NSViewWidthSizable | NSViewMaxXMargin | NSViewMinYMargin)]; + [expressionField setFont:[[MAMEDebugView class] defaultFont]]; + [expressionField setFocusRingType:NSFocusRingTypeNone]; + [expressionField setTarget:self]; + [expressionField setAction:@selector(doExpression:)]; + [expressionField setDelegate:self]; + expressionFrame = [expressionField frame]; + expressionFrame.size.width = (contentBounds.size.width - expressionFrame.size.height) / 2; + [expressionField setFrameSize:expressionFrame.size]; + + // create the subview popup + subviewButton = [[NSPopUpButton alloc] initWithFrame:NSOffsetRect(expressionFrame, + expressionFrame.size.width, + 0)]; + [subviewButton setAutoresizingMask:(NSViewWidthSizable | NSViewMinXMargin | NSViewMinYMargin)]; + [subviewButton setBezelStyle:NSShadowlessSquareBezelStyle]; + [subviewButton setFocusRingType:NSFocusRingTypeNone]; + [subviewButton setFont:[[MAMEDebugView class] defaultFont]]; + [subviewButton setTarget:self]; + [subviewButton setAction:@selector(changeSubview:)]; + [[subviewButton cell] setArrowPosition:NSPopUpArrowAtBottom]; + + // create a container for the expression field and subview popup + expressionFrame = NSMakeRect(expressionFrame.size.height, + contentBounds.size.height - expressionFrame.size.height, + contentBounds.size.width - expressionFrame.size.height, + expressionFrame.size.height); + expressionContainer = [[NSView alloc] initWithFrame:expressionFrame]; + [expressionContainer setAutoresizingMask:(NSViewWidthSizable | NSViewMinYMargin)]; + [expressionContainer addSubview:expressionField]; + [expressionField release]; + [expressionContainer addSubview:subviewButton]; + [subviewButton release]; + [[window contentView] addSubview:expressionContainer]; + [expressionContainer release]; + + // create the disassembly view + dasmView = [[MAMEDisassemblyView alloc] initWithFrame:NSMakeRect(0, 0, 100, 100) + machine:*machine + useConsole:NO]; + [dasmView insertSubviewItemsInMenu:[subviewButton menu] atIndex:0]; + dasmScroll = [[NSScrollView alloc] initWithFrame:NSMakeRect(0, + 0, + contentBounds.size.width, + expressionFrame.origin.y)]; + [dasmScroll setDrawsBackground:YES]; + [dasmScroll setAutoresizingMask:(NSViewWidthSizable | NSViewHeightSizable)]; + [dasmScroll setHasHorizontalScroller:YES]; + [dasmScroll setHasVerticalScroller:YES]; + [dasmScroll setAutohidesScrollers:YES]; + [dasmScroll setBorderType:NSNoBorder]; + [dasmScroll setDocumentView:dasmView]; + [dasmView release]; + [[window contentView] addSubview:dasmScroll]; + [dasmScroll release]; + + // create the action popup + actionButton = [[self class] newActionButtonWithFrame:NSMakeRect(0, + expressionFrame.origin.y, + expressionFrame.size.height, + expressionFrame.size.height)]; + [actionButton setAutoresizingMask:(NSViewMaxXMargin | NSViewMinYMargin)]; + [dasmView insertActionItemsInMenu:[actionButton menu] atIndex:1]; + [[window contentView] addSubview:actionButton]; + [actionButton release]; + + // set default state + [dasmView selectSubviewForCPU:debug_cpu_get_visible_cpu(*machine)]; + [dasmView setExpression:@"curpc"]; + [expressionField setStringValue:@"curpc"]; + [expressionField selectText:self]; + [subviewButton selectItemAtIndex:[subviewButton indexOfItemWithTag:[dasmView selectedSubviewIndex]]]; + [window makeFirstResponder:expressionField]; + [window setTitle:[NSString stringWithFormat:@"Disassembly: %@", [dasmView selectedSubviewName]]]; + + // calculate the optimal size for everything + { + NSSize desired = [NSScrollView frameSizeForContentSize:[dasmView maximumFrameSize] + hasHorizontalScroller:YES + hasVerticalScroller:YES + borderType:[dasmScroll borderType]]; + [self cascadeWindowWithDesiredSize:desired forView:dasmScroll]; + } + + // don't forget the result + return self; +} + + +- (void)dealloc { + [super dealloc]; +} + + +- (id )documentView { + return dasmView; +} + + +- (IBAction)changeSubview:(id)sender { + [dasmView selectSubviewAtIndex:[[sender selectedItem] tag]]; + [window setTitle:[NSString stringWithFormat:@"Disassembly: %@", [dasmView selectedSubviewName]]]; +} + +@end diff --git a/src/osd/modules/debugger/osx/debugosxerrorlogview.h b/src/osd/modules/debugger/osx/debugosxerrorlogview.h new file mode 100644 index 00000000000..7f85a06147f --- /dev/null +++ b/src/osd/modules/debugger/osx/debugosxerrorlogview.h @@ -0,0 +1,26 @@ +// license:BSD-3-Clause +// copyright-holders:Vas Crabb +//============================================================ +// +// debugosxerrorlogview.h - MacOS X Cocoa debug window handling +// +// Copyright (c) 1996-2015, Nicola Salmoria and the MAME Team. +// Visit http://mamedev.org for licensing and usage restrictions. +// +//============================================================ + +#import "debugosx.h" +#import "debugosxdebugview.h" + +#include "emu.h" + +#import + + +@interface MAMEErrorLogView : MAMEDebugView +{ +} + +- (id)initWithFrame:(NSRect)f machine:(running_machine &)m; + +@end diff --git a/src/osd/modules/debugger/osx/debugosxerrorlogview.m b/src/osd/modules/debugger/osx/debugosxerrorlogview.m new file mode 100644 index 00000000000..49ffac807b0 --- /dev/null +++ b/src/osd/modules/debugger/osx/debugosxerrorlogview.m @@ -0,0 +1,30 @@ +// license:BSD-3-Clause +// copyright-holders:Vas Crabb +//============================================================ +// +// debugosxerrorlogview.m - MacOS X Cocoa debug window handling +// +// Copyright (c) 1996-2015, Nicola Salmoria and the MAME Team. +// Visit http://mamedev.org for licensing and usage restrictions. +// +//============================================================ + +#import "debugosxerrorlogview.h" + +#include "debug/debugvw.h" + + +@implementation MAMEErrorLogView + +- (id)initWithFrame:(NSRect)f machine:(running_machine &)m { + if (!(self = [super initWithFrame:f type:DVT_LOG machine:m])) + return nil; + return self; +} + + +- (void)dealloc { + [super dealloc]; +} + +@end diff --git a/src/osd/modules/debugger/osx/debugosxerrorlogviewer.h b/src/osd/modules/debugger/osx/debugosxerrorlogviewer.h new file mode 100644 index 00000000000..caab178d854 --- /dev/null +++ b/src/osd/modules/debugger/osx/debugosxerrorlogviewer.h @@ -0,0 +1,29 @@ +// license:BSD-3-Clause +// copyright-holders:Vas Crabb +//============================================================ +// +// debugosxerrorlogviewer.h - MacOS X Cocoa debug window handling +// +// Copyright (c) 1996-2015, Nicola Salmoria and the MAME Team. +// Visit http://mamedev.org for licensing and usage restrictions. +// +//============================================================ + +#import "debugosx.h" +#import "debugosxdebugwindowhandler.h" + +#include "emu.h" + +#import + + +@class MAMEDebugConsole, MAMEErrorLogView; + +@interface MAMEErrorLogViewer : MAMEAuxiliaryDebugWindowHandler +{ + MAMEErrorLogView *logView; +} + +- (id)initWithMachine:(running_machine &)m console:(MAMEDebugConsole *)c; + +@end diff --git a/src/osd/modules/debugger/osx/debugosxerrorlogviewer.m b/src/osd/modules/debugger/osx/debugosxerrorlogviewer.m new file mode 100644 index 00000000000..b0abaeaeca6 --- /dev/null +++ b/src/osd/modules/debugger/osx/debugosxerrorlogviewer.m @@ -0,0 +1,64 @@ +// license:BSD-3-Clause +// copyright-holders:Vas Crabb +//============================================================ +// +// debugosxerrorlogviewer.m - MacOS X Cocoa debug window handling +// +// Copyright (c) 1996-2015, Nicola Salmoria and the MAME Team. +// Visit http://mamedev.org for licensing and usage restrictions. +// +//============================================================ + +#import "debugosxerrorlogviewer.h" + +#import "debugosxerrorlogview.h" + + +@implementation MAMEErrorLogViewer + +- (id)initWithMachine:(running_machine &)m console:(MAMEDebugConsole *)c { + NSScrollView *logScroll; + NSString *title; + + title = [NSString stringWithFormat:@"Error Log: %@ [%@]", + [NSString stringWithUTF8String:m.system().description], + [NSString stringWithUTF8String:m.system().name]]; + if (!(self = [super initWithMachine:m title:title console:c])) + return nil; + + // create the error log view + logView = [[MAMEErrorLogView alloc] initWithFrame:NSMakeRect(0, 0, 100, 100) machine:*machine]; + logScroll = [[NSScrollView alloc] initWithFrame:NSMakeRect(0, 0, 100, 100)]; + [logScroll setDrawsBackground:YES]; + [logScroll setAutoresizingMask:(NSViewWidthSizable | NSViewHeightSizable)]; + [logScroll setHasHorizontalScroller:YES]; + [logScroll setHasVerticalScroller:YES]; + [logScroll setAutohidesScrollers:YES]; + [logScroll setBorderType:NSNoBorder]; + [logScroll setDocumentView:logView]; + [logView release]; + [window setContentView:logScroll]; + [logScroll release]; + + // calculate the optimal size for everything + { + NSSize desired = [NSScrollView frameSizeForContentSize:[logView maximumFrameSize] + hasHorizontalScroller:YES + hasVerticalScroller:YES + borderType:[logScroll borderType]]; + + // this thing starts with no content, so its prefered height may be very small + desired.height = MAX(desired.height, 240); + [self cascadeWindowWithDesiredSize:desired forView:logScroll]; + } + + // don't forget the result + return self; +} + + +- (void)dealloc { + [super dealloc]; +} + +@end diff --git a/src/osd/modules/debugger/osx/debugosxmemoryview.h b/src/osd/modules/debugger/osx/debugosxmemoryview.h new file mode 100644 index 00000000000..24f4544955a --- /dev/null +++ b/src/osd/modules/debugger/osx/debugosxmemoryview.h @@ -0,0 +1,44 @@ +// license:BSD-3-Clause +// copyright-holders:Vas Crabb +//============================================================ +// +// debugosxmemoryview.h - MacOS X Cocoa debug window handling +// +// Copyright (c) 1996-2015, Nicola Salmoria and the MAME Team. +// Visit http://mamedev.org for licensing and usage restrictions. +// +//============================================================ + +#import "debugosx.h" +#import "debugosxdebugview.h" + +#include "emu.h" + +#import + + +@interface MAMEMemoryView : MAMEDebugView +{ +} + +- (id)initWithFrame:(NSRect)f machine:(running_machine &)m; + +- (NSSize)maximumFrameSize; + +- (NSString *)selectedSubviewName; +- (int)selectedSubviewIndex; +- (void)selectSubviewAtIndex:(int)index; +- (void)selectSubviewForCPU:(device_t *)device; + +- (NSString *)expression; +- (void)setExpression:(NSString *)exp; + +- (IBAction)showChunkSize:(id)sender; +- (IBAction)showPhysicalAddresses:(id)sender; +- (IBAction)showReverseView:(id)sender; +- (IBAction)showReverseViewToggle:(id)sender; + +- (void)insertActionItemsInMenu:(NSMenu *)menu atIndex:(NSInteger)index; +- (void)insertSubviewItemsInMenu:(NSMenu *)menu atIndex:(NSInteger)index; + +@end diff --git a/src/osd/modules/debugger/osx/debugosxmemoryview.m b/src/osd/modules/debugger/osx/debugosxmemoryview.m new file mode 100644 index 00000000000..8477a8cb6fa --- /dev/null +++ b/src/osd/modules/debugger/osx/debugosxmemoryview.m @@ -0,0 +1,207 @@ +// license:BSD-3-Clause +// copyright-holders:Vas Crabb +//============================================================ +// +// debugosxmemoryview.m - MacOS X Cocoa debug window handling +// +// Copyright (c) 1996-2015, Nicola Salmoria and the MAME Team. +// Visit http://mamedev.org for licensing and usage restrictions. +// +//============================================================ + +#import "debugosxmemoryview.h" + +#include "emucore.h" +#include "debug/debugcpu.h" +#include "debug/debugvw.h" +#include "debug/dvmemory.h" + + +@implementation MAMEMemoryView + +- (id)initWithFrame:(NSRect)f machine:(running_machine &)m { + NSMenu *contextMenu; + + if (!(self = [super initWithFrame:f type:DVT_MEMORY machine:m])) + return nil; + + contextMenu = [[NSMenu allocWithZone:[NSMenu menuZone]] initWithTitle:@"Memory"]; + [self insertActionItemsInMenu:contextMenu atIndex:0]; + [self setMenu:contextMenu]; + [contextMenu release]; + + return self; +} + + +- (void)dealloc { + [super dealloc]; +} + + +- (BOOL)validateMenuItem:(NSMenuItem *)item { + SEL action = [item action]; + NSInteger tag = [item tag]; + debug_view_memory *memview = downcast(view); + + if (action == @selector(showChunkSize:)) { + [item setState:((tag == memview->bytes_per_chunk()) ? NSOnState : NSOffState)]; + } else if (action == @selector(showPhysicalAddresses:)) { + [item setState:((tag == memview->physical()) ? NSOnState : NSOffState)]; + } else if (action == @selector(showReverseView:)) { + [item setState:((tag == memview->reverse()) ? NSOnState : NSOffState)]; + } else if (action == @selector(showReverseViewToggle:)) { + [item setState:(memview->reverse() ? NSOnState : NSOffState)]; + } + return YES; +} + + +- (NSSize)maximumFrameSize { + debug_view_xy max; + device_t *curcpu = debug_cpu_get_visible_cpu(*machine); + debug_view_source const *source = view->source_for_device(curcpu); + + max.x = max.y = 0; + for (const debug_view_source *source = view->source_list().first(); + source != NULL; + source = source->next()) + { + debug_view_xy current; + view->set_source(*source); + current = view->total_size(); + if (current.x > max.x) + max.x = current.x; + if (current.y > max.y) + max.y = current.y; + } + view->set_source(*source); + return NSMakeSize(max.x * fontWidth, max.y * fontHeight); +} + + +- (NSString *)selectedSubviewName { + debug_view_source const *source = view->source(); + if (source != NULL) + return [NSString stringWithUTF8String:source->name()]; + else + return @""; +} + + +- (int)selectedSubviewIndex { + debug_view_source const *source = view->source(); + if (source != NULL) + return view->source_list().indexof(*source); + else + return -1; +} + + +- (void)selectSubviewAtIndex:(int)index { + int const selected = view->source_list().indexof(*view->source()); + if (selected != index) { + view->set_source(*view->source_list().find(index)); + if ([[self window] firstResponder] != self) + view->set_cursor_visible(false); + } +} + + +- (void)selectSubviewForCPU:(device_t *)device { + debug_view_source const *selected = view->source(); + debug_view_source const *source = view->source_for_device(device); + if ( selected != source ) { + view->set_source(*source); + if ([[self window] firstResponder] != self) + view->set_cursor_visible(false); + } +} + + +- (NSString *)expression { + return [NSString stringWithUTF8String:downcast(view)->expression()]; +} + + +- (void)setExpression:(NSString *)exp { + downcast(view)->set_expression([exp UTF8String]); +} + + +- (IBAction)showChunkSize:(id)sender { + downcast(view)->set_bytes_per_chunk([sender tag]); +} + + +- (IBAction)showPhysicalAddresses:(id)sender { + downcast(view)->set_physical([sender tag]); +} + + +- (IBAction)showReverseView:(id)sender { + downcast(view)->set_reverse([sender tag]); +} + + +- (IBAction)showReverseViewToggle:(id)sender { + downcast(view)->set_reverse(!downcast(view)->reverse()); +} + + +- (void)insertActionItemsInMenu:(NSMenu *)menu atIndex:(NSInteger)index { + { + NSInteger tag; + for (tag = 1; tag <= 8; tag <<= 1) { + NSString *title = [NSString stringWithFormat:@"%ld-byte Chunks", (long)tag]; + NSMenuItem *chunkItem = [menu insertItemWithTitle:title + action:@selector(showChunkSize:) + keyEquivalent:[NSString stringWithFormat:@"%ld", (long)tag] + atIndex:index++]; + [chunkItem setTarget:self]; + [chunkItem setTag:tag]; + } + } + [menu insertItem:[NSMenuItem separatorItem] atIndex:index++]; + { + NSMenuItem *logicalItem = [menu insertItemWithTitle:@"Logical Addresses" + action:@selector(showPhysicalAddresses:) + keyEquivalent:@"v" + atIndex:index++]; + [logicalItem setTarget:self]; + [logicalItem setTag:FALSE]; + } + { + NSMenuItem *physicalItem = [menu insertItemWithTitle:@"Physical Addresses" + action:@selector(showPhysicalAddresses:) + keyEquivalent:@"y" + atIndex:index++]; + [physicalItem setTarget:self]; + [physicalItem setTag:TRUE]; + } + [menu insertItem:[NSMenuItem separatorItem] atIndex:index++]; + { + NSMenuItem *reverseItem = [menu insertItemWithTitle:@"Reverse View" + action:@selector(showReverseViewToggle:) + keyEquivalent:@"r" + atIndex:index++]; + [reverseItem setTarget:self]; + } + if (index < [menu numberOfItems]) + [menu insertItem:[NSMenuItem separatorItem] atIndex:index++]; +} + + +- (void)insertSubviewItemsInMenu:(NSMenu *)menu atIndex:(NSInteger)index { + for (const debug_view_source *source = view->source_list().first(); source != NULL; source = source->next()) + { + [[menu insertItemWithTitle:[NSString stringWithUTF8String:source->name()] + action:NULL + keyEquivalent:@"" + atIndex:index++] setTag:view->source_list().indexof(*source)]; + } + if (index < [menu numberOfItems]) + [menu insertItem:[NSMenuItem separatorItem] atIndex:index++]; +} + +@end diff --git a/src/osd/modules/debugger/osx/debugosxmemoryviewer.h b/src/osd/modules/debugger/osx/debugosxmemoryviewer.h new file mode 100644 index 00000000000..4ea37140fdc --- /dev/null +++ b/src/osd/modules/debugger/osx/debugosxmemoryviewer.h @@ -0,0 +1,31 @@ +// license:BSD-3-Clause +// copyright-holders:Vas Crabb +//============================================================ +// +// debugosxmemoryviewer.h - MacOS X Cocoa debug window handling +// +// Copyright (c) 1996-2015, Nicola Salmoria and the MAME Team. +// Visit http://mamedev.org for licensing and usage restrictions. +// +//============================================================ + +#import "debugosx.h" +#import "debugosxdebugwindowhandler.h" + +#include "emu.h" + +#import + + +@class MAMEDebugConsole, MAMEMemoryView; + +@interface MAMEMemoryViewer : MAMEExpressionAuxiliaryDebugWindowHandler +{ + MAMEMemoryView *memoryView; +} + +- (id)initWithMachine:(running_machine &)m console:(MAMEDebugConsole *)c; + +- (IBAction)changeSubview:(id)sender; + +@end diff --git a/src/osd/modules/debugger/osx/debugosxmemoryviewer.m b/src/osd/modules/debugger/osx/debugosxmemoryviewer.m new file mode 100644 index 00000000000..eeb8694342e --- /dev/null +++ b/src/osd/modules/debugger/osx/debugosxmemoryviewer.m @@ -0,0 +1,137 @@ +// license:BSD-3-Clause +// copyright-holders:Vas Crabb +//============================================================ +// +// debugosxmemoryviewer.m - MacOS X Cocoa debug window handling +// +// Copyright (c) 1996-2015, Nicola Salmoria and the MAME Team. +// Visit http://mamedev.org for licensing and usage restrictions. +// +//============================================================ + +#import "debugosxmemoryviewer.h" + +#import "debugosxdebugview.h" +#import "debugosxmemoryview.h" + +#include "debug/debugcpu.h" + + +@implementation MAMEMemoryViewer + +- (id)initWithMachine:(running_machine &)m console:(MAMEDebugConsole *)c { + NSScrollView *memoryScroll; + NSView *expressionContainer; + NSPopUpButton *actionButton, *subviewButton; + NSRect contentBounds, expressionFrame; + + if (!(self = [super initWithMachine:m title:@"Memory" console:c])) + return nil; + contentBounds = [[window contentView] bounds]; + + // create the expression field + expressionField = [[NSTextField alloc] initWithFrame:NSMakeRect(0, 0, 100, 19)]; + [expressionField setAutoresizingMask:(NSViewWidthSizable | NSViewMaxXMargin | NSViewMinYMargin)]; + [expressionField setFont:[[MAMEDebugView class] defaultFont]]; + [expressionField setFocusRingType:NSFocusRingTypeNone]; + [expressionField setTarget:self]; + [expressionField setAction:@selector(doExpression:)]; + [expressionField setDelegate:self]; + expressionFrame = [expressionField frame]; + expressionFrame.size.width = (contentBounds.size.width - expressionFrame.size.height) / 2; + [expressionField setFrameSize:expressionFrame.size]; + + // create the subview popup + subviewButton = [[NSPopUpButton alloc] initWithFrame:NSOffsetRect(expressionFrame, + expressionFrame.size.width, + 0)]; + [subviewButton setAutoresizingMask:(NSViewWidthSizable | NSViewMinXMargin | NSViewMinYMargin)]; + [subviewButton setBezelStyle:NSShadowlessSquareBezelStyle]; + [subviewButton setFocusRingType:NSFocusRingTypeNone]; + [subviewButton setFont:[[MAMEDebugView class] defaultFont]]; + [subviewButton setTarget:self]; + [subviewButton setAction:@selector(changeSubview:)]; + [[subviewButton cell] setArrowPosition:NSPopUpArrowAtBottom]; + + // create a container for the expression field and subview popup + expressionFrame = NSMakeRect(expressionFrame.size.height, + contentBounds.size.height - expressionFrame.size.height, + contentBounds.size.width - expressionFrame.size.height, + expressionFrame.size.height); + expressionContainer = [[NSView alloc] initWithFrame:expressionFrame]; + [expressionContainer setAutoresizingMask:(NSViewWidthSizable | NSViewMinYMargin)]; + [expressionContainer addSubview:expressionField]; + [expressionField release]; + [expressionContainer addSubview:subviewButton]; + [subviewButton release]; + [[window contentView] addSubview:expressionContainer]; + [expressionContainer release]; + + // create the memory view + memoryView = [[MAMEMemoryView alloc] initWithFrame:NSMakeRect(0, 0, 100, 100) + machine:*machine]; + [memoryView insertSubviewItemsInMenu:[subviewButton menu] atIndex:0]; + memoryScroll = [[NSScrollView alloc] initWithFrame:NSMakeRect(0, + 0, + contentBounds.size.width, + expressionFrame.origin.y)]; + [memoryScroll setDrawsBackground:YES]; + [memoryScroll setAutoresizingMask:(NSViewWidthSizable | NSViewHeightSizable)]; + [memoryScroll setHasHorizontalScroller:YES]; + [memoryScroll setHasVerticalScroller:YES]; + [memoryScroll setAutohidesScrollers:YES]; + [memoryScroll setBorderType:NSNoBorder]; + [memoryScroll setDocumentView:memoryView]; + [memoryView release]; + [[window contentView] addSubview:memoryScroll]; + [memoryScroll release]; + + // create the action popup + actionButton = [[self class] newActionButtonWithFrame:NSMakeRect(0, + expressionFrame.origin.y, + expressionFrame.size.height, + expressionFrame.size.height)]; + [actionButton setAutoresizingMask:(NSViewMaxXMargin | NSViewMinYMargin)]; + [memoryView insertActionItemsInMenu:[actionButton menu] atIndex:1]; + [[window contentView] addSubview:actionButton]; + [actionButton release]; + + // set default state + [memoryView selectSubviewForCPU:debug_cpu_get_visible_cpu(*machine)]; + [memoryView setExpression:@"0"]; + [expressionField setStringValue:@"0"]; + [expressionField selectText:self]; + [subviewButton selectItemAtIndex:[subviewButton indexOfItemWithTag:[memoryView selectedSubviewIndex]]]; + [window makeFirstResponder:expressionField]; + [window setTitle:[NSString stringWithFormat:@"Memory: %@", [memoryView selectedSubviewName]]]; + + // calculate the optimal size for everything + { + NSSize desired = [NSScrollView frameSizeForContentSize:[memoryView maximumFrameSize] + hasHorizontalScroller:YES + hasVerticalScroller:YES + borderType:[memoryScroll borderType]]; + [self cascadeWindowWithDesiredSize:desired forView:memoryScroll]; + } + + // don't forget the result + return self; +} + + +- (void)dealloc { + [super dealloc]; +} + + +- (id )documentView { + return memoryView; +} + + +- (IBAction)changeSubview:(id)sender { + [memoryView selectSubviewAtIndex:[[sender selectedItem] tag]]; + [window setTitle:[NSString stringWithFormat:@"Memory: %@", [memoryView selectedSubviewName]]]; +} + +@end diff --git a/src/osd/modules/debugger/osx/debugosxregistersview.h b/src/osd/modules/debugger/osx/debugosxregistersview.h new file mode 100644 index 00000000000..5951cef4dc2 --- /dev/null +++ b/src/osd/modules/debugger/osx/debugosxregistersview.h @@ -0,0 +1,33 @@ +// license:BSD-3-Clause +// copyright-holders:Vas Crabb +//============================================================ +// +// debugosxregistersview.h - MacOS X Cocoa debug window handling +// +// Copyright (c) 1996-2015, Nicola Salmoria and the MAME Team. +// Visit http://mamedev.org for licensing and usage restrictions. +// +//============================================================ + +#import "debugosx.h" +#import "debugosxdebugview.h" + +#include "emu.h" + +#import + + +@interface MAMERegistersView : MAMEDebugView +{ +} + +- (id)initWithFrame:(NSRect)f machine:(running_machine &)m; + +- (NSSize)maximumFrameSize; + +- (NSString *)selectedSubviewName; +- (int)selectedSubviewIndex; +- (void)selectSubviewAtIndex:(int)index; +- (void)selectSubviewForCPU:(device_t *)device; + +@end diff --git a/src/osd/modules/debugger/osx/debugosxregistersview.m b/src/osd/modules/debugger/osx/debugosxregistersview.m new file mode 100644 index 00000000000..49c635250eb --- /dev/null +++ b/src/osd/modules/debugger/osx/debugosxregistersview.m @@ -0,0 +1,71 @@ +// license:BSD-3-Clause +// copyright-holders:Vas Crabb +//============================================================ +// +// debugosxregistersview.m - MacOS X Cocoa debug window handling +// +// Copyright (c) 1996-2015, Nicola Salmoria and the MAME Team. +// Visit http://mamedev.org for licensing and usage restrictions. +// +//============================================================ + +#import "debugosxregistersview.h" + +#include "debug/debugcpu.h" +#include "debug/debugvw.h" + + +@implementation MAMERegistersView + +- (id)initWithFrame:(NSRect)f machine:(running_machine &)m { + if (!(self = [super initWithFrame:f type:DVT_STATE machine:m])) + return nil; + return self; +} + + +- (void)dealloc { + [super dealloc]; +} + + +- (NSSize)maximumFrameSize { + debug_view_xy max; + device_t *curcpu = debug_cpu_get_visible_cpu(*machine); + const debug_view_source *source = view->source_for_device(curcpu); + + max.x = max.y = 0; + for (const debug_view_source *source = view->source_list().first(); source != NULL; source = source->next()) + { + debug_view_xy current; + view->set_source(*source); + current = view->total_size(); + if (current.x > max.x) + max.x = current.x; + if (current.y > max.y) + max.y = current.y; + } + view->set_source(*source); + return NSMakeSize(max.x * fontWidth, max.y * fontHeight); +} + + +- (NSString *)selectedSubviewName { + return @""; +} + + +- (int)selectedSubviewIndex { + return -1; +} + + +- (void)selectSubviewAtIndex:(int)index { +} + + +- (void)selectSubviewForCPU:(device_t *)device { + view->set_source(*view->source_for_device(device)); +} + +@end diff --git a/src/osd/sdl/sdl.mak b/src/osd/sdl/sdl.mak index 1ee1ee62366..5813707a5d4 100644 --- a/src/osd/sdl/sdl.mak +++ b/src/osd/sdl/sdl.mak @@ -284,7 +284,24 @@ LIBS += -framework CoreAudio -framework CoreMIDI endif ifdef NO_USE_QTDEBUG -DEBUGOBJS = $(OSDOBJ)/modules/debugger/debugosx.o + +OBJDIRS += $(OSDOBJ)/modules/debugger/osx + +DEBUGOBJS = \ + $(OSDOBJ)/modules/debugger/debugosx.o \ + $(OSDOBJ)/modules/debugger/osx/debugosxconsoleview.o \ + $(OSDOBJ)/modules/debugger/osx/debugosxdebugcommandhistory.o \ + $(OSDOBJ)/modules/debugger/osx/debugosxdebugconsole.o \ + $(OSDOBJ)/modules/debugger/osx/debugosxdebugview.o \ + $(OSDOBJ)/modules/debugger/osx/debugosxdebugwindowhandler.o \ + $(OSDOBJ)/modules/debugger/osx/debugosxdisassemblyview.o \ + $(OSDOBJ)/modules/debugger/osx/debugosxdisassemblyviewer.o \ + $(OSDOBJ)/modules/debugger/osx/debugosxerrorlogview.o \ + $(OSDOBJ)/modules/debugger/osx/debugosxerrorlogviewer.o \ + $(OSDOBJ)/modules/debugger/osx/debugosxmemoryview.o \ + $(OSDOBJ)/modules/debugger/osx/debugosxmemoryviewer.o \ + $(OSDOBJ)/modules/debugger/osx/debugosxregistersview.o + endif SYNC_IMPLEMENTATION = ntc diff --git a/src/osd/sdl/video.c b/src/osd/sdl/video.c index 106c69a0194..2b834883828 100644 --- a/src/osd/sdl/video.c +++ b/src/osd/sdl/video.c @@ -250,8 +250,8 @@ void sdl_monitor_info::refresh() } #elif defined(SDLMAME_OS2) // OS2 version m_dimensions.x = m_dimensions.y = 0; - m_center_width = m_dimensions.w = WinQuerySysValue( HWND_DESKTOP, SV_CXSCREEN ); - m_center_height = m_dimensions.h = WinQuerySysValue( HWND_DESKTOP, SV_CYSCREEN ); + m_dimensions.w = WinQuerySysValue( HWND_DESKTOP, SV_CXSCREEN ); + m_dimensions.h = WinQuerySysValue( HWND_DESKTOP, SV_CYSCREEN ); strcpy(m_monitor_device, "OS/2 display"); #else #error Unknown SDLMAME_xx OS type! -- cgit v1.2.3 From 146653f9d701fe7c5acc8a2b66df06c08fd98c23 Mon Sep 17 00:00:00 2001 From: Vas Crabb Date: Sat, 14 Feb 2015 09:04:39 +1100 Subject: Far better handling of font metrics in Cocoa debugger, and more efficient drawing --- src/osd/modules/debugger/osx/debugosxdebugview.h | 4 + src/osd/modules/debugger/osx/debugosxdebugview.m | 196 ++++++++++++++------- .../modules/debugger/osx/debugosxdisassemblyview.m | 1 - src/osd/modules/debugger/osx/debugosxmemoryview.m | 1 - 4 files changed, 132 insertions(+), 70 deletions(-) diff --git a/src/osd/modules/debugger/osx/debugosxdebugview.h b/src/osd/modules/debugger/osx/debugosxdebugview.h index d87ecdb3015..9688fa48b8e 100644 --- a/src/osd/modules/debugger/osx/debugosxdebugview.h +++ b/src/osd/modules/debugger/osx/debugosxdebugview.h @@ -45,6 +45,10 @@ NSFont *font; CGFloat fontWidth, fontHeight, fontAscent; + + NSTextStorage *text; + NSTextContainer *textContainer; + NSLayoutManager *layoutManager; } + (NSFont *)defaultFont; diff --git a/src/osd/modules/debugger/osx/debugosxdebugview.m b/src/osd/modules/debugger/osx/debugosxdebugview.m index d893bb0ad2f..a0755650613 100644 --- a/src/osd/modules/debugger/osx/debugosxdebugview.m +++ b/src/osd/modules/debugger/osx/debugosxdebugview.m @@ -58,16 +58,64 @@ static void debugwin_view_update(debug_view &view, void *osdprivate) - (debug_view_xy)convertLocation:(NSPoint)location { debug_view_xy position; - position.x = lround(floor(location.x / fontWidth)); + position.y = lround(floor(location.y / fontHeight)); - if (position.x < 0) - position.x = 0; - else if (position.x >= totalWidth) - position.x = totalWidth - 1; if (position.y < 0) position.y = 0; else if (position.y >= totalHeight) position.y = totalHeight - 1; + + debug_view_xy const origin = view->visible_position(); + debug_view_xy const size = view->visible_size(); + debug_view_char const *data = view->viewdata(); + if (!data || (position.y < origin.y) || (position.y >= origin.y + size.y)) + { + // y coordinate outside visible area, x will be a guess + position.x = lround(floor(location.x / fontWidth)); + } + else + { + data += ((position.y - view->visible_position().y) * view->visible_size().x); + int attr = -1; + NSUInteger start = 0, length = 0; + for (UINT32 col = origin.x; col < origin.x + size.x; col++) + { + [[text mutableString] appendFormat:@"%c", data[col - origin.x].byte]; + if ((start < length) && (attr != data[col - origin.x].attrib)) + { + NSRange const run = NSMakeRange(start, length - start); + [text addAttribute:NSFontAttributeName + value:font + range:NSMakeRange(0, length)]; + [text addAttribute:NSForegroundColorAttributeName + value:[self foregroundForAttribute:attr] + range:run]; + start = length; + } + attr = data[col - origin.x].attrib; + length = [text length]; + } + if (start < length) + { + NSRange const run = NSMakeRange(start, length - start); + [text addAttribute:NSFontAttributeName + value:font + range:NSMakeRange(0, length)]; + [text addAttribute:NSForegroundColorAttributeName + value:[self foregroundForAttribute:attr] + range:run]; + } + CGFloat fraction; + NSUInteger const glyph = [layoutManager glyphIndexForPoint:NSMakePoint(location.x, fontHeight / 2) + inTextContainer:textContainer + fractionOfDistanceThroughGlyph:&fraction]; + position.x = [layoutManager characterIndexForGlyphAtIndex:glyph]; // FIXME: assumes 1:1 character mapping + } + if (position.x < 0) + position.x = 0; + else if (position.x >= totalWidth) + position.x = totalWidth - 1; + return position; } @@ -75,6 +123,8 @@ static void debugwin_view_update(debug_view &view, void *osdprivate) - (void)convertBounds:(NSRect)b toPosition:(debug_view_xy *)origin size:(debug_view_xy *)size { origin->x = lround(floor(b.origin.x / fontWidth)); origin->y = lround(floor(b.origin.y / fontHeight)); + + // FIXME: this is not using proper font metrics horizontally size->x = lround(ceil((b.origin.x + b.size.width) / fontWidth)) - origin->x; size->y = lround(ceil((b.origin.y + b.size.height) / fontHeight)) - origin->y; } @@ -107,7 +157,7 @@ static void debugwin_view_update(debug_view &view, void *osdprivate) { debug_view_xy newPos = view->cursor_position(); if ((newPos.x != oldPos.x) || (newPos.y != oldPos.y)) { - [self scrollRectToVisible:NSMakeRect(newPos.x * fontWidth, + [self scrollRectToVisible:NSMakeRect(newPos.x * fontWidth, // FIXME - use proper metrics newPos.y * fontHeight, fontWidth, fontHeight)]; @@ -120,8 +170,7 @@ static void debugwin_view_update(debug_view &view, void *osdprivate) + (NSFont *)defaultFont { - // maybe we should get the configured system fixed-width font... - return [NSFont fontWithName:@"Monaco" size:10]; + return [NSFont userFixedPitchFontOfSize:0]; } @@ -138,14 +187,21 @@ static void debugwin_view_update(debug_view &view, void *osdprivate) totalWidth = totalHeight = 0; originLeft = originTop = 0; [self setFont:[[self class] defaultFont]]; + text = [[NSTextStorage alloc] init]; + textContainer = [[NSTextContainer alloc] init]; + layoutManager = [[NSLayoutManager alloc] init]; + [layoutManager addTextContainer:textContainer]; + [text addLayoutManager:layoutManager]; return self; } - (void)dealloc { [[NSNotificationCenter defaultCenter] removeObserver:self]; - if (font != nil) - [font release]; + if (font != nil) [font release]; + if (text != nil) [text release]; + if (textContainer != nil) [textContainer release]; + if (layoutManager != nil) [layoutManager release]; [super dealloc]; } @@ -156,7 +212,7 @@ static void debugwin_view_update(debug_view &view, void *osdprivate) // resize our frame if the total size has changed newSize = view->total_size(); if ((newSize.x != totalWidth) || (newSize.y != totalHeight)) { - [self setFrameSize:NSMakeSize(fontWidth * newSize.x, fontHeight * newSize.y)]; + [self setFrameSize:NSMakeSize(fontWidth * newSize.x, fontHeight * newSize.y)]; // FIXME: metrics totalWidth = newSize.x; totalHeight = newSize.y; } @@ -221,7 +277,7 @@ static void debugwin_view_update(debug_view &view, void *osdprivate) debug_view_xy pos; view->set_cursor_visible(true); pos = view->cursor_position(); - [self scrollRectToVisible:NSMakeRect(pos.x * fontWidth, pos.y * fontHeight, fontWidth, fontHeight)]; + [self scrollRectToVisible:NSMakeRect(pos.x * fontWidth, pos.y * fontHeight, fontWidth, fontHeight)]; // FIXME: metrics [self setNeedsDisplay:YES]; return [super becomeFirstResponder]; } else { @@ -266,73 +322,77 @@ static void debugwin_view_update(debug_view &view, void *osdprivate) - (void)drawRect:(NSRect)dirtyRect { - const debug_view_char *base; - debug_view_xy origin, size; - debug_view_xy position, clip; - NSMutableString *text; - NSMutableDictionary *attributes; - UINT32 pass, row, col; + debug_view_xy position, clip; // work out how much we need to draw [self recomputeVisible]; - origin = view->visible_position(); - size = view->visible_size(); + debug_view_xy const origin = view->visible_position(); + debug_view_xy const size = view->visible_size(); [self convertBounds:dirtyRect toPosition:&position size:&clip]; // this gets the text for the whole visible area - base = view->viewdata(); - if (!base) + debug_view_char const *data = view->viewdata(); + if (!data) return; - text = [[NSMutableString alloc] initWithCapacity:clip.x]; - attributes = [[NSMutableDictionary alloc] initWithObjectsAndKeys:font, NSFontAttributeName, nil]; - for (pass = 0; pass < 2; pass++) { - const debug_view_char *data = base + ((position.y - origin.y) * size.x); - for (row = position.y; row < position.y + clip.y; row++, data += size.x) { - int attr = -1; - - if ((row < origin.y) || (row >= origin.y + size.y)) - continue; - - // render entire lines to get character alignment right - for (col = origin.x; col < origin.x + size.x; col++) { - if ((attr != data[col - origin.x].attrib) && ([text length] > 0)) { - if (pass == 0) { - [[self backgroundForAttribute:attr] set]; - [NSBezierPath fillRect:NSMakeRect((col - [text length]) * fontWidth, - row * fontHeight, - [text length] * fontWidth, - fontHeight)]; - } else { - [attributes setObject:[self foregroundForAttribute:attr] - forKey:NSForegroundColorAttributeName]; - [text drawAtPoint:NSMakePoint((col - [text length]) * fontWidth, row * fontHeight) - withAttributes:attributes]; - } - [text setString:@""]; - } - attr = data[col - origin.x].attrib; - [text appendFormat:@"%c", data[col - origin.x].byte]; - } - if ([text length] > 0) { - if (pass == 0) { - [[self backgroundForAttribute:attr] set]; - [NSBezierPath fillRect:NSMakeRect((col - [text length]) * fontWidth, - row * fontHeight, - [text length] * fontWidth, - fontHeight)]; - } else { - [attributes setObject:[self foregroundForAttribute:attr] - forKey:NSForegroundColorAttributeName]; - [text drawAtPoint:NSMakePoint((col - [text length]) * fontWidth, row * fontHeight) - withAttributes:attributes]; - } - [text setString:@""]; + data += ((position.y - origin.y) * size.x); + for (UINT32 row = position.y; row < position.y + clip.y; row++, data += size.x) + { + if ((row < origin.y) || (row >= origin.y + size.y)) + continue; + + // render entire lines to get character alignment right + int attr = -1; + NSUInteger start = 0, length = 0; + for (UINT32 col = origin.x; col < origin.x + size.x; col++) + { + [[text mutableString] appendFormat:@"%c", data[col - origin.x].byte]; + if ((start < length) && (attr != data[col - origin.x].attrib)) + { + NSRange const run = NSMakeRange(start, length - start); + [text addAttribute:NSFontAttributeName + value:font + range:NSMakeRange(0, length)]; + [text addAttribute:NSForegroundColorAttributeName + value:[self foregroundForAttribute:attr] + range:run]; + NSRange const glyphs = [layoutManager glyphRangeForCharacterRange:run + actualCharacterRange:NULL]; + NSRect const box = [layoutManager boundingRectForGlyphRange:glyphs + inTextContainer:textContainer]; + [[self backgroundForAttribute:attr] set]; + [NSBezierPath fillRect:NSMakeRect(box.origin.x, + row * fontHeight, + box.size.width, + fontHeight)]; + start = length; } + attr = data[col - origin.x].attrib; + length = [text length]; + } + if (start < length) + { + NSRange const run = NSMakeRange(start, length - start); + [text addAttribute:NSFontAttributeName + value:font + range:NSMakeRange(0, length)]; + [text addAttribute:NSForegroundColorAttributeName + value:[self foregroundForAttribute:attr] + range:run]; + NSRange const glyphs = [layoutManager glyphRangeForCharacterRange:run + actualCharacterRange:NULL]; + NSRect const box = [layoutManager boundingRectForGlyphRange:glyphs + inTextContainer:textContainer]; + [[self backgroundForAttribute:attr] set]; + [NSBezierPath fillRect:NSMakeRect(box.origin.x, + row * fontHeight, + box.size.width, + fontHeight)]; } + [layoutManager drawGlyphsForGlyphRange:[layoutManager glyphRangeForTextContainer:textContainer] + atPoint:NSMakePoint(0, row * fontHeight)]; + [text deleteCharactersInRange:NSMakeRange(0, length)]; } - [attributes release]; - [text release]; } diff --git a/src/osd/modules/debugger/osx/debugosxdisassemblyview.m b/src/osd/modules/debugger/osx/debugosxdisassemblyview.m index af0242b20b4..7a482cd8504 100644 --- a/src/osd/modules/debugger/osx/debugosxdisassemblyview.m +++ b/src/osd/modules/debugger/osx/debugosxdisassemblyview.m @@ -11,7 +11,6 @@ #import "debugosxdisassemblyview.h" -#include "emucore.h" #include "debug/debugcon.h" #include "debug/debugcpu.h" #include "debug/debugvw.h" diff --git a/src/osd/modules/debugger/osx/debugosxmemoryview.m b/src/osd/modules/debugger/osx/debugosxmemoryview.m index 8477a8cb6fa..beee0fa6156 100644 --- a/src/osd/modules/debugger/osx/debugosxmemoryview.m +++ b/src/osd/modules/debugger/osx/debugosxmemoryview.m @@ -11,7 +11,6 @@ #import "debugosxmemoryview.h" -#include "emucore.h" #include "debug/debugcpu.h" #include "debug/debugvw.h" #include "debug/dvmemory.h" -- cgit v1.2.3 From 6ec9472c846047715a216a442a54664be7c948e5 Mon Sep 17 00:00:00 2001 From: Vas Crabb Date: Sat, 14 Feb 2015 10:06:55 +1100 Subject: More intuitive command/expression history --- src/osd/modules/debugger/debugosx.m | 50 +++++++++++----------- .../debugger/osx/debugosxdebugcommandhistory.h | 1 + .../debugger/osx/debugosxdebugcommandhistory.m | 13 ++++-- .../modules/debugger/osx/debugosxdebugconsole.h | 2 +- .../modules/debugger/osx/debugosxdebugconsole.m | 10 +++++ src/osd/modules/debugger/osx/debugosxdebugview.h | 36 ++++++++-------- .../debugger/osx/debugosxdebugwindowhandler.h | 1 + .../debugger/osx/debugosxdebugwindowhandler.m | 7 +++ 8 files changed, 73 insertions(+), 47 deletions(-) diff --git a/src/osd/modules/debugger/debugosx.m b/src/osd/modules/debugger/debugosx.m index f8ea683a826..a662ef0a194 100644 --- a/src/osd/modules/debugger/debugosx.m +++ b/src/osd/modules/debugger/debugosx.m @@ -42,32 +42,34 @@ class debugger_osx : public osd_module, public debug_module { public: - debugger_osx() - : osd_module(OSD_DEBUG_PROVIDER, "osx"), debug_module(), - m_machine(NULL), - m_console(nil) - { - } - - virtual ~debugger_osx() - { - } - - virtual int init() - { - return 0; - } - - virtual void exit() - { - } - - virtual void init_debugger(running_machine &machine); - virtual void wait_for_debugger(device_t &device, bool firststop); - virtual void debugger_update(); + debugger_osx() + : osd_module(OSD_DEBUG_PROVIDER, "osx"), debug_module(), + m_machine(NULL), + m_console(nil) + { + } + + virtual ~debugger_osx() + { + if (m_console != nil) + [m_console release]; + } + + virtual int init() + { + return 0; + } + + virtual void exit() + { + } + + virtual void init_debugger(running_machine &machine); + virtual void wait_for_debugger(device_t &device, bool firststop); + virtual void debugger_update(); private: - running_machine *m_machine; + running_machine *m_machine; MAMEDebugConsole *m_console; }; diff --git a/src/osd/modules/debugger/osx/debugosxdebugcommandhistory.h b/src/osd/modules/debugger/osx/debugosxdebugcommandhistory.h index 78f8fbe42c7..3cb0f23d06c 100644 --- a/src/osd/modules/debugger/osx/debugosxdebugcommandhistory.h +++ b/src/osd/modules/debugger/osx/debugosxdebugcommandhistory.h @@ -31,6 +31,7 @@ - (void)add:(NSString *)entry; - (NSString *)previous:(NSString *)cur; - (NSString *)next:(NSString *)cur; +- (void)edit; - (void)reset; - (void)clear; diff --git a/src/osd/modules/debugger/osx/debugosxdebugcommandhistory.m b/src/osd/modules/debugger/osx/debugosxdebugcommandhistory.m index 9c1cd5093a0..0d9967370a5 100644 --- a/src/osd/modules/debugger/osx/debugosxdebugcommandhistory.m +++ b/src/osd/modules/debugger/osx/debugosxdebugcommandhistory.m @@ -50,8 +50,8 @@ - (void)setLength:(NSInteger)l { length = l; - while ([history count] > length) - [history removeLastObject]; + if ([history count] > length) + [history removeObjectsInRange:NSMakeRange(length, [history count] - length)]; } @@ -61,7 +61,7 @@ while ([history count] > length) [history removeLastObject]; } - position = -1; + position = 0; } @@ -81,7 +81,7 @@ - (NSString *)next:(NSString *)cur { if (position > 0) { return [history objectAtIndex:--position]; - } else if (position == 0) { + } else if ((position == 0) && (current != nil) && ![current isEqualToString:[history objectAtIndex:0]]) { position--; return [[current retain] autorelease]; } else { @@ -90,6 +90,11 @@ } +- (void)edit { + if (position == 0) + position--; +} + - (void)reset { position = -1; if (current != nil) { diff --git a/src/osd/modules/debugger/osx/debugosxdebugconsole.h b/src/osd/modules/debugger/osx/debugosxdebugconsole.h index 85639929c04..5de1d333b26 100644 --- a/src/osd/modules/debugger/osx/debugosxdebugconsole.h +++ b/src/osd/modules/debugger/osx/debugosxdebugconsole.h @@ -12,7 +12,6 @@ #import "debugosx.h" #import "debugosxdebugwindowhandler.h" -#include "device.h" #include "emu.h" #import @@ -44,6 +43,7 @@ - (void)showDebugger:(NSNotification *)notification; - (void)auxiliaryWindowWillClose:(NSNotification *)notification; +- (BOOL)control:(NSControl *)control textShouldBeginEditing:(NSText *)fieldEditor; - (BOOL)control:(NSControl *)control textView:(NSTextView *)textView doCommandBySelector:(SEL)command; - (void)windowWillClose:(NSNotification *)notification; diff --git a/src/osd/modules/debugger/osx/debugosxdebugconsole.m b/src/osd/modules/debugger/osx/debugosxdebugconsole.m index 4952e2ccdf6..56994dfc212 100644 --- a/src/osd/modules/debugger/osx/debugosxdebugconsole.m +++ b/src/osd/modules/debugger/osx/debugosxdebugconsole.m @@ -218,9 +218,11 @@ NSString *command = [sender stringValue]; if ([command length] == 0) { debug_cpu_get_visible_cpu(*machine)->debug()->single_step(); + [history reset]; } else { debug_console_execute_command(*machine, [command UTF8String], 1); [history add:command]; + [history edit]; } [sender setStringValue:@""]; } @@ -264,6 +266,14 @@ } +- (BOOL)control:(NSControl *)control textShouldBeginEditing:(NSText *)fieldEditor { + if (control == commandField) + [history edit]; + + return YES; +} + + - (BOOL)control:(NSControl *)control textView:(NSTextView *)textView doCommandBySelector:(SEL)command { if (control == commandField) { if (command == @selector(cancelOperation:)) { diff --git a/src/osd/modules/debugger/osx/debugosxdebugview.h b/src/osd/modules/debugger/osx/debugosxdebugview.h index 9688fa48b8e..06c25ea7c21 100644 --- a/src/osd/modules/debugger/osx/debugosxdebugview.h +++ b/src/osd/modules/debugger/osx/debugosxdebugview.h @@ -17,24 +17,6 @@ #import -@protocol MAMEDebugViewSubviewSupport - -- (NSString *)selectedSubviewName; -- (int)selectedSubviewIndex; -- (void)selectSubviewAtIndex:(int)index; -- (void)selectSubviewForCPU:(device_t *)device; - -@end - - -@protocol MAMEDebugViewExpressionSupport - -- (NSString *)expression; -- (void)setExpression:(NSString *)exp; - -@end - - @interface MAMEDebugView : NSView { int type; @@ -66,3 +48,21 @@ - (void)windowDidResignKey:(NSNotification *)notification; @end + + +@protocol MAMEDebugViewSubviewSupport + +- (NSString *)selectedSubviewName; +- (int)selectedSubviewIndex; +- (void)selectSubviewAtIndex:(int)index; +- (void)selectSubviewForCPU:(device_t *)device; + +@end + + +@protocol MAMEDebugViewExpressionSupport + +- (NSString *)expression; +- (void)setExpression:(NSString *)exp; + +@end diff --git a/src/osd/modules/debugger/osx/debugosxdebugwindowhandler.h b/src/osd/modules/debugger/osx/debugosxdebugwindowhandler.h index 35f8be2b67b..a45a65cac63 100644 --- a/src/osd/modules/debugger/osx/debugosxdebugwindowhandler.h +++ b/src/osd/modules/debugger/osx/debugosxdebugwindowhandler.h @@ -91,6 +91,7 @@ extern NSString *const MAMEAuxiliaryDebugWindowWillCloseNotification; - (IBAction)doExpression:(id)sender; +- (BOOL)control:(NSControl *)control textShouldBeginEditing:(NSText *)fieldEditor; - (BOOL)control:(NSControl *)control textView:(NSTextView *)textView doCommandBySelector:(SEL)command; @end diff --git a/src/osd/modules/debugger/osx/debugosxdebugwindowhandler.m b/src/osd/modules/debugger/osx/debugosxdebugwindowhandler.m index d5382c19454..e8585179b96 100644 --- a/src/osd/modules/debugger/osx/debugosxdebugwindowhandler.m +++ b/src/osd/modules/debugger/osx/debugosxdebugwindowhandler.m @@ -357,6 +357,13 @@ NSString *const MAMEAuxiliaryDebugWindowWillCloseNotification = @"MAMEAuxiliaryD } +- (BOOL)control:(NSControl *)control textShouldBeginEditing:(NSText *)fieldEditor +{ + [history edit]; + return YES; +} + + - (BOOL)control:(NSControl *)control textView:(NSTextView *)textView doCommandBySelector:(SEL)command { if (control == expressionField) { if (command == @selector(cancelOperation:)) { -- cgit v1.2.3 From 503f71a189a0e6bba0aa4fc23354c3f3f268664f Mon Sep 17 00:00:00 2001 From: Vas Crabb Date: Sat, 14 Feb 2015 10:09:31 +1100 Subject: Check which control sends event --- src/osd/modules/debugger/osx/debugosxdebugwindowhandler.m | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/osd/modules/debugger/osx/debugosxdebugwindowhandler.m b/src/osd/modules/debugger/osx/debugosxdebugwindowhandler.m index e8585179b96..9be854432aa 100644 --- a/src/osd/modules/debugger/osx/debugosxdebugwindowhandler.m +++ b/src/osd/modules/debugger/osx/debugosxdebugwindowhandler.m @@ -359,7 +359,9 @@ NSString *const MAMEAuxiliaryDebugWindowWillCloseNotification = @"MAMEAuxiliaryD - (BOOL)control:(NSControl *)control textShouldBeginEditing:(NSText *)fieldEditor { - [history edit]; + if (control == expressionField) + [history edit]; + return YES; } -- cgit v1.2.3 From 6519c9fee9b6b0c2e1d26a87bb1af559501e3723 Mon Sep 17 00:00:00 2001 From: Vas Crabb Date: Sat, 14 Feb 2015 21:12:16 +1100 Subject: Fix a dumb bug, use newer interfaces --- src/osd/modules/debugger/debugosx.m | 1 - src/osd/modules/debugger/osx/debugosxdebugview.m | 27 +++++------------------- 2 files changed, 5 insertions(+), 23 deletions(-) diff --git a/src/osd/modules/debugger/debugosx.m b/src/osd/modules/debugger/debugosx.m index a662ef0a194..440a201a2bf 100644 --- a/src/osd/modules/debugger/debugosx.m +++ b/src/osd/modules/debugger/debugosx.m @@ -14,7 +14,6 @@ // * Automatic scrolling for console and log views // * Using alpha for disabled foreground colours doesn't really work // * New windows created from auxiliary windows should inherit focus rather than pointing at current CPU -// * Improve behaviour of expression history in memory and disassembly windows - the double tap is annoying // * Keyboard shortcuts in error log windows // * Don't accept keyboard input while the game is running // * Interior focus rings - standard/exterior focus rings look really ugly here diff --git a/src/osd/modules/debugger/osx/debugosxdebugview.m b/src/osd/modules/debugger/osx/debugosxdebugview.m index a0755650613..a6e2e37da9e 100644 --- a/src/osd/modules/debugger/osx/debugosxdebugview.m +++ b/src/osd/modules/debugger/osx/debugosxdebugview.m @@ -110,6 +110,7 @@ static void debugwin_view_update(debug_view &view, void *osdprivate) inTextContainer:textContainer fractionOfDistanceThroughGlyph:&fraction]; position.x = [layoutManager characterIndexForGlyphAtIndex:glyph]; // FIXME: assumes 1:1 character mapping + [text deleteCharactersInRange:NSMakeRange(0, length)]; } if (position.x < 0) position.x = 0; @@ -397,32 +398,14 @@ static void debugwin_view_update(debug_view &view, void *osdprivate) - (void)mouseDown:(NSEvent *)event { - NSPoint location = [self convertPoint:[event locationInWindow] fromView:nil]; - if (view->cursor_supported()) { - view->set_cursor_position([self convertLocation:location]); - view->set_cursor_visible(true); - [self setNeedsDisplay:YES]; - } -} - - -- (void)mouseDragged:(NSEvent *)event { - NSPoint location = [self convertPoint:[event locationInWindow] fromView:nil]; - if (view->cursor_supported()) { - [self autoscroll:event]; - view->set_cursor_position([self convertLocation:location]); - [self setNeedsDisplay:YES]; - } + NSPoint const location = [self convertPoint:[event locationInWindow] fromView:nil]; + view->process_click(DCK_LEFT_CLICK, [self convertLocation:location]); } - (void)rightMouseDown:(NSEvent *)event { - NSPoint location = [self convertPoint:[event locationInWindow] fromView:nil]; - if (view->cursor_supported()) { - view->set_cursor_position([self convertLocation:location]); - view->set_cursor_visible(true); - [self setNeedsDisplay:YES]; - } + NSPoint const location = [self convertPoint:[event locationInWindow] fromView:nil]; + view->process_click(DCK_RIGHT_CLICK, [self convertLocation:location]); [super rightMouseDown:event]; } -- cgit v1.2.3 From 8918376d5685e1a6d90499e6400b10f07a330e73 Mon Sep 17 00:00:00 2001 From: Vas Crabb Date: Sat, 14 Feb 2015 22:51:10 +1100 Subject: More functionality, including (break|watch)points view --- .../modules/debugger/osx/debugosxbreakpointsview.h | 26 ++++ .../modules/debugger/osx/debugosxbreakpointsview.m | 30 +++++ .../modules/debugger/osx/debugosxdebugconsole.h | 1 + .../modules/debugger/osx/debugosxdebugconsole.m | 9 ++ src/osd/modules/debugger/osx/debugosxdebugview.m | 9 +- .../debugger/osx/debugosxdebugwindowhandler.h | 1 + .../debugger/osx/debugosxdebugwindowhandler.m | 8 ++ src/osd/modules/debugger/osx/debugosxmemoryview.h | 1 + src/osd/modules/debugger/osx/debugosxmemoryview.m | 88 +++++++----- .../modules/debugger/osx/debugosxmemoryviewer.m | 12 +- .../modules/debugger/osx/debugosxpointsviewer.h | 31 +++++ .../modules/debugger/osx/debugosxpointsviewer.m | 147 +++++++++++++++++++++ .../modules/debugger/osx/debugosxwatchpointsview.h | 26 ++++ .../modules/debugger/osx/debugosxwatchpointsview.m | 30 +++++ src/osd/sdl/sdl.mak | 5 +- 15 files changed, 379 insertions(+), 45 deletions(-) create mode 100644 src/osd/modules/debugger/osx/debugosxbreakpointsview.h create mode 100644 src/osd/modules/debugger/osx/debugosxbreakpointsview.m create mode 100644 src/osd/modules/debugger/osx/debugosxpointsviewer.h create mode 100644 src/osd/modules/debugger/osx/debugosxpointsviewer.m create mode 100644 src/osd/modules/debugger/osx/debugosxwatchpointsview.h create mode 100644 src/osd/modules/debugger/osx/debugosxwatchpointsview.m diff --git a/src/osd/modules/debugger/osx/debugosxbreakpointsview.h b/src/osd/modules/debugger/osx/debugosxbreakpointsview.h new file mode 100644 index 00000000000..16dd78f8420 --- /dev/null +++ b/src/osd/modules/debugger/osx/debugosxbreakpointsview.h @@ -0,0 +1,26 @@ +// license:BSD-3-Clause +// copyright-holders:Vas Crabb +//============================================================ +// +// debugosxbreakpointsview.h - MacOS X Cocoa debug window handling +// +// Copyright (c) 1996-2015, Nicola Salmoria and the MAME Team. +// Visit http://mamedev.org for licensing and usage restrictions. +// +//============================================================ + +#import "debugosx.h" +#import "debugosxdebugview.h" + +#include "emu.h" + +#import + + +@interface MAMEBreakpointsView : MAMEDebugView +{ +} + +- (id)initWithFrame:(NSRect)f machine:(running_machine &)m; + +@end diff --git a/src/osd/modules/debugger/osx/debugosxbreakpointsview.m b/src/osd/modules/debugger/osx/debugosxbreakpointsview.m new file mode 100644 index 00000000000..a244e17fe7e --- /dev/null +++ b/src/osd/modules/debugger/osx/debugosxbreakpointsview.m @@ -0,0 +1,30 @@ +// license:BSD-3-Clause +// copyright-holders:Vas Crabb +//============================================================ +// +// debugosxbreakpointsview.m - MacOS X Cocoa debug window handling +// +// Copyright (c) 1996-2015, Nicola Salmoria and the MAME Team. +// Visit http://mamedev.org for licensing and usage restrictions. +// +//============================================================ + +#import "debugosxbreakpointsview.h" + +#include "debug/debugvw.h" + + +@implementation MAMEBreakpointsView + +- (id)initWithFrame:(NSRect)f machine:(running_machine &)m { + if (!(self = [super initWithFrame:f type:DVT_BREAK_POINTS machine:m])) + return nil; + return self; +} + + +- (void)dealloc { + [super dealloc]; +} + +@end diff --git a/src/osd/modules/debugger/osx/debugosxdebugconsole.h b/src/osd/modules/debugger/osx/debugosxdebugconsole.h index 5de1d333b26..941a6ab2b9e 100644 --- a/src/osd/modules/debugger/osx/debugosxdebugconsole.h +++ b/src/osd/modules/debugger/osx/debugosxdebugconsole.h @@ -39,6 +39,7 @@ - (IBAction)debugNewMemoryWindow:(id)sender; - (IBAction)debugNewDisassemblyWindow:(id)sender; - (IBAction)debugNewErrorLogWindow:(id)sender; +- (IBAction)debugNewPointsWindow:(id)sender; - (void)showDebugger:(NSNotification *)notification; - (void)auxiliaryWindowWillClose:(NSNotification *)notification; diff --git a/src/osd/modules/debugger/osx/debugosxdebugconsole.m b/src/osd/modules/debugger/osx/debugosxdebugconsole.m index 56994dfc212..2b6785b3b9e 100644 --- a/src/osd/modules/debugger/osx/debugosxdebugconsole.m +++ b/src/osd/modules/debugger/osx/debugosxdebugconsole.m @@ -18,6 +18,7 @@ #import "debugosxdisassemblyviewer.h" #import "debugosxerrorlogviewer.h" #import "debugosxmemoryviewer.h" +#import "debugosxpointsviewer.h" #import "debugosxregistersview.h" #include "debug/debugcon.h" @@ -252,6 +253,14 @@ } +- (IBAction)debugNewPointsWindow:(id)sender{ + MAMEPointsViewer *win = [[MAMEPointsViewer alloc] initWithMachine:*machine console:self]; + [auxiliaryWindows addObject:win]; + [win release]; + [win activate]; +} + + - (void)showDebugger:(NSNotification *)notification { device_t *device = (device_t * )[[[notification userInfo] objectForKey:@"MAMEDebugDevice"] pointerValue]; if (&device->machine() == machine) { diff --git a/src/osd/modules/debugger/osx/debugosxdebugview.m b/src/osd/modules/debugger/osx/debugosxdebugview.m index a6e2e37da9e..3f6a4f56d03 100644 --- a/src/osd/modules/debugger/osx/debugosxdebugview.m +++ b/src/osd/modules/debugger/osx/debugosxdebugview.m @@ -187,12 +187,17 @@ static void debugwin_view_update(debug_view &view, void *osdprivate) } totalWidth = totalHeight = 0; originLeft = originTop = 0; - [self setFont:[[self class] defaultFont]]; + text = [[NSTextStorage alloc] init]; textContainer = [[NSTextContainer alloc] init]; layoutManager = [[NSLayoutManager alloc] init]; [layoutManager addTextContainer:textContainer]; + [textContainer release]; [text addLayoutManager:layoutManager]; + [layoutManager release]; + + [self setFont:[[self class] defaultFont]]; + return self; } @@ -201,8 +206,6 @@ static void debugwin_view_update(debug_view &view, void *osdprivate) [[NSNotificationCenter defaultCenter] removeObserver:self]; if (font != nil) [font release]; if (text != nil) [text release]; - if (textContainer != nil) [textContainer release]; - if (layoutManager != nil) [layoutManager release]; [super dealloc]; } diff --git a/src/osd/modules/debugger/osx/debugosxdebugwindowhandler.h b/src/osd/modules/debugger/osx/debugosxdebugwindowhandler.h index a45a65cac63..ba0f75fadad 100644 --- a/src/osd/modules/debugger/osx/debugosxdebugwindowhandler.h +++ b/src/osd/modules/debugger/osx/debugosxdebugwindowhandler.h @@ -71,6 +71,7 @@ extern NSString *const MAMEAuxiliaryDebugWindowWillCloseNotification; - (IBAction)debugNewMemoryWindow:(id)sender; - (IBAction)debugNewDisassemblyWindow:(id)sender; - (IBAction)debugNewErrorLogWindow:(id)sender; +- (IBAction)debugNewPointsWindow:(id)sender; - (void)windowWillClose:(NSNotification *)notification; diff --git a/src/osd/modules/debugger/osx/debugosxdebugwindowhandler.m b/src/osd/modules/debugger/osx/debugosxdebugwindowhandler.m index 9be854432aa..edfbb2a27fb 100644 --- a/src/osd/modules/debugger/osx/debugosxdebugwindowhandler.m +++ b/src/osd/modules/debugger/osx/debugosxdebugwindowhandler.m @@ -105,6 +105,9 @@ NSString *const MAMEAuxiliaryDebugWindowWillCloseNotification = @"MAMEAuxiliaryD [newMenu addItemWithTitle:@"Error Log Window" action:@selector(debugNewErrorLogWindow:) keyEquivalent:@"l"]; + [newMenu addItemWithTitle:@"(Break|Watch)points Window" + action:@selector(debugNewPointsWindow:) + keyEquivalent:@"b"]; } [menu addItem:[NSMenuItem separatorItem]]; [menu addItemWithTitle:@"Close Window" action:@selector(performClose:) keyEquivalent:@"w"]; @@ -287,6 +290,11 @@ NSString *const MAMEAuxiliaryDebugWindowWillCloseNotification = @"MAMEAuxiliaryD } +- (IBAction)debugNewPointsWindow:(id)sender { + [console debugNewPointsWindow:sender]; +} + + - (void)windowWillClose:(NSNotification *)notification { [[NSNotificationCenter defaultCenter] postNotificationName:MAMEAuxiliaryDebugWindowWillCloseNotification object:self]; diff --git a/src/osd/modules/debugger/osx/debugosxmemoryview.h b/src/osd/modules/debugger/osx/debugosxmemoryview.h index 24f4544955a..45f39787c5a 100644 --- a/src/osd/modules/debugger/osx/debugosxmemoryview.h +++ b/src/osd/modules/debugger/osx/debugosxmemoryview.h @@ -37,6 +37,7 @@ - (IBAction)showPhysicalAddresses:(id)sender; - (IBAction)showReverseView:(id)sender; - (IBAction)showReverseViewToggle:(id)sender; +- (IBAction)changeBytesPerLine:(id)sender; - (void)insertActionItemsInMenu:(NSMenu *)menu atIndex:(NSInteger)index; - (void)insertSubviewItemsInMenu:(NSMenu *)menu atIndex:(NSInteger)index; diff --git a/src/osd/modules/debugger/osx/debugosxmemoryview.m b/src/osd/modules/debugger/osx/debugosxmemoryview.m index beee0fa6156..3bebe290c79 100644 --- a/src/osd/modules/debugger/osx/debugosxmemoryview.m +++ b/src/osd/modules/debugger/osx/debugosxmemoryview.m @@ -148,44 +148,64 @@ } +- (IBAction)changeBytesPerLine:(id)sender { + debug_view_memory *const memView = downcast(view); + memView->set_chunks_per_row(memView->chunks_per_row() + [sender tag]); +} + + - (void)insertActionItemsInMenu:(NSMenu *)menu atIndex:(NSInteger)index { - { - NSInteger tag; - for (tag = 1; tag <= 8; tag <<= 1) { - NSString *title = [NSString stringWithFormat:@"%ld-byte Chunks", (long)tag]; - NSMenuItem *chunkItem = [menu insertItemWithTitle:title - action:@selector(showChunkSize:) - keyEquivalent:[NSString stringWithFormat:@"%ld", (long)tag] - atIndex:index++]; - [chunkItem setTarget:self]; - [chunkItem setTag:tag]; - } + NSInteger tag; + for (tag = 1; tag <= 8; tag <<= 1) { + NSString *title = [NSString stringWithFormat:@"%ld-byte Chunks", (long)tag]; + NSMenuItem *chunkItem = [menu insertItemWithTitle:title + action:@selector(showChunkSize:) + keyEquivalent:[NSString stringWithFormat:@"%ld", (long)tag] + atIndex:index++]; + [chunkItem setTarget:self]; + [chunkItem setTag:tag]; } + [menu insertItem:[NSMenuItem separatorItem] atIndex:index++]; - { - NSMenuItem *logicalItem = [menu insertItemWithTitle:@"Logical Addresses" - action:@selector(showPhysicalAddresses:) - keyEquivalent:@"v" - atIndex:index++]; - [logicalItem setTarget:self]; - [logicalItem setTag:FALSE]; - } - { - NSMenuItem *physicalItem = [menu insertItemWithTitle:@"Physical Addresses" - action:@selector(showPhysicalAddresses:) - keyEquivalent:@"y" - atIndex:index++]; - [physicalItem setTarget:self]; - [physicalItem setTag:TRUE]; - } + + NSMenuItem *logicalItem = [menu insertItemWithTitle:@"Logical Addresses" + action:@selector(showPhysicalAddresses:) + keyEquivalent:@"v" + atIndex:index++]; + [logicalItem setTarget:self]; + [logicalItem setTag:FALSE]; + + NSMenuItem *physicalItem = [menu insertItemWithTitle:@"Physical Addresses" + action:@selector(showPhysicalAddresses:) + keyEquivalent:@"y" + atIndex:index++]; + [physicalItem setTarget:self]; + [physicalItem setTag:TRUE]; + [menu insertItem:[NSMenuItem separatorItem] atIndex:index++]; - { - NSMenuItem *reverseItem = [menu insertItemWithTitle:@"Reverse View" - action:@selector(showReverseViewToggle:) - keyEquivalent:@"r" - atIndex:index++]; - [reverseItem setTarget:self]; - } + + NSMenuItem *reverseItem = [menu insertItemWithTitle:@"Reverse View" + action:@selector(showReverseViewToggle:) + keyEquivalent:@"r" + atIndex:index++]; + [reverseItem setTarget:self]; + + [menu insertItem:[NSMenuItem separatorItem] atIndex:index++]; + + NSMenuItem *increaseItem = [menu insertItemWithTitle:@"Increase Bytes Per Line" + action:@selector(changeBytesPerLine:) + keyEquivalent:@"p" + atIndex:index++]; + [increaseItem setTarget:self]; + [increaseItem setTag:1]; + + NSMenuItem *decreaseItem = [menu insertItemWithTitle:@"Decrease Bytes Per Line" + action:@selector(changeBytesPerLine:) + keyEquivalent:@"o" + atIndex:index++]; + [decreaseItem setTarget:self]; + [decreaseItem setTag:-1]; + if (index < [menu numberOfItems]) [menu insertItem:[NSMenuItem separatorItem] atIndex:index++]; } diff --git a/src/osd/modules/debugger/osx/debugosxmemoryviewer.m b/src/osd/modules/debugger/osx/debugosxmemoryviewer.m index eeb8694342e..d3413e58a99 100644 --- a/src/osd/modules/debugger/osx/debugosxmemoryviewer.m +++ b/src/osd/modules/debugger/osx/debugosxmemoryviewer.m @@ -106,13 +106,11 @@ [window setTitle:[NSString stringWithFormat:@"Memory: %@", [memoryView selectedSubviewName]]]; // calculate the optimal size for everything - { - NSSize desired = [NSScrollView frameSizeForContentSize:[memoryView maximumFrameSize] - hasHorizontalScroller:YES - hasVerticalScroller:YES - borderType:[memoryScroll borderType]]; - [self cascadeWindowWithDesiredSize:desired forView:memoryScroll]; - } + NSSize const desired = [NSScrollView frameSizeForContentSize:[memoryView maximumFrameSize] + hasHorizontalScroller:YES + hasVerticalScroller:YES + borderType:[memoryScroll borderType]]; + [self cascadeWindowWithDesiredSize:desired forView:memoryScroll]; // don't forget the result return self; diff --git a/src/osd/modules/debugger/osx/debugosxpointsviewer.h b/src/osd/modules/debugger/osx/debugosxpointsviewer.h new file mode 100644 index 00000000000..885affcc0a6 --- /dev/null +++ b/src/osd/modules/debugger/osx/debugosxpointsviewer.h @@ -0,0 +1,31 @@ +// license:BSD-3-Clause +// copyright-holders:Vas Crabb +//============================================================ +// +// debugosxpointsviewer.h - MacOS X Cocoa debug window handling +// +// Copyright (c) 1996-2015, Nicola Salmoria and the MAME Team. +// Visit http://mamedev.org for licensing and usage restrictions. +// +//============================================================ + +#import "debugosx.h" +#import "debugosxdebugwindowhandler.h" + +#include "emu.h" + +#import + + +@class MAMEDebugConsole; + +@interface MAMEPointsViewer : MAMEAuxiliaryDebugWindowHandler +{ + NSTabView *tabs; +} + +- (id)initWithMachine:(running_machine &)m console:(MAMEDebugConsole *)c; + +- (IBAction)changeSubview:(id)sender; + +@end diff --git a/src/osd/modules/debugger/osx/debugosxpointsviewer.m b/src/osd/modules/debugger/osx/debugosxpointsviewer.m new file mode 100644 index 00000000000..b5667581af1 --- /dev/null +++ b/src/osd/modules/debugger/osx/debugosxpointsviewer.m @@ -0,0 +1,147 @@ +// license:BSD-3-Clause +// copyright-holders:Vas Crabb +//============================================================ +// +// debugosxpointsviewer.m - MacOS X Cocoa debug window handling +// +// Copyright (c) 1996-2015, Nicola Salmoria and the MAME Team. +// Visit http://mamedev.org for licensing and usage restrictions. +// +//============================================================ + +#import "debugosxpointsviewer.h" + +#import "debugosxbreakpointsview.h" +#import "debugosxwatchpointsview.h" + + +@implementation MAMEPointsViewer + +- (id)initWithMachine:(running_machine &)m console:(MAMEDebugConsole *)c { + MAMEDebugView *breakView, *watchView; + NSScrollView *breakScroll, *watchScroll; + NSTabViewItem *breakTab, *watchTab; + NSPopUpButton *actionButton, *subviewButton; + NSRect contentBounds; + + if (!(self = [super initWithMachine:m title:@"(Break|Watch)points" console:c])) + return nil; + contentBounds = [[window contentView] bounds]; + + // create the subview popup + subviewButton = [[NSPopUpButton alloc] initWithFrame:NSMakeRect(19, + contentBounds.size.height - 19, + contentBounds.size.width - 19, + 19)]; + [subviewButton setAutoresizingMask:(NSViewWidthSizable | NSViewMinYMargin)]; + [subviewButton setBezelStyle:NSShadowlessSquareBezelStyle]; + [subviewButton setFocusRingType:NSFocusRingTypeNone]; + [subviewButton setFont:[[MAMEDebugView class] defaultFont]]; + [subviewButton setTarget:self]; + [subviewButton setAction:@selector(changeSubview:)]; + [[subviewButton cell] setArrowPosition:NSPopUpArrowAtBottom]; + [[[subviewButton menu] addItemWithTitle:@"All Breakpoints" + action:NULL + keyEquivalent:@""] setTag:0]; + [[[subviewButton menu] addItemWithTitle:@"All Watchpoints" + action:NULL + keyEquivalent:@""] setTag:1]; + [[window contentView] addSubview:subviewButton]; + [subviewButton release]; + + // create the action popup + actionButton = [[self class] newActionButtonWithFrame:NSMakeRect(0, + contentBounds.size.height - 19, + 19, + 19)]; + [actionButton setAutoresizingMask:(NSViewMaxXMargin | NSViewMinYMargin)]; + [[window contentView] addSubview:actionButton]; + [actionButton release]; + + // create the breakpoints view + breakView = [[MAMEBreakpointsView alloc] initWithFrame:NSMakeRect(0, 0, 100, 100) + machine:*machine]; + breakScroll = [[NSScrollView alloc] initWithFrame:NSMakeRect(0, + 0, + contentBounds.size.width, + contentBounds.size.height - 19)]; + [breakScroll setDrawsBackground:YES]; + [breakScroll setAutoresizingMask:(NSViewWidthSizable | NSViewHeightSizable)]; + [breakScroll setHasHorizontalScroller:YES]; + [breakScroll setHasVerticalScroller:YES]; + [breakScroll setAutohidesScrollers:YES]; + [breakScroll setBorderType:NSNoBorder]; + [breakScroll setDocumentView:breakView]; + [breakView release]; + breakTab = [[NSTabViewItem alloc] initWithIdentifier:nil]; + [breakTab setView:breakScroll]; + [breakScroll release]; + + // create the breakpoints view + watchView = [[MAMEWatchpointsView alloc] initWithFrame:NSMakeRect(0, 0, 100, 100) + machine:*machine]; + watchScroll = [[NSScrollView alloc] initWithFrame:NSMakeRect(0, + 0, + contentBounds.size.width, + contentBounds.size.height - 19)]; + [watchScroll setDrawsBackground:YES]; + [watchScroll setAutoresizingMask:(NSViewWidthSizable | NSViewHeightSizable)]; + [watchScroll setHasHorizontalScroller:YES]; + [watchScroll setHasVerticalScroller:YES]; + [watchScroll setAutohidesScrollers:YES]; + [watchScroll setBorderType:NSNoBorder]; + [watchScroll setDocumentView:watchView]; + [watchView release]; + watchTab = [[NSTabViewItem alloc] initWithIdentifier:nil]; + [watchTab setView:watchScroll]; + [watchScroll release]; + + // create a tabless tabview for the two subviews + tabs = [[NSTabView alloc] initWithFrame:NSMakeRect(0, + 0, + contentBounds.size.width, + contentBounds.size.height - 19)]; + [tabs setTabViewType:NSNoTabsNoBorder]; + [tabs setAutoresizingMask:(NSViewWidthSizable | NSViewHeightSizable)]; + [tabs addTabViewItem:breakTab]; + [breakTab release]; + [tabs addTabViewItem:watchTab]; + [watchTab release]; + [[window contentView] addSubview:tabs]; + [tabs release]; + + // set default state + [subviewButton selectItemAtIndex:0]; + [tabs selectFirstTabViewItem:self]; + [window makeFirstResponder:subviewButton]; + [window setTitle:[[subviewButton selectedItem] title]]; + + // calculate the optimal size for everything + NSSize const breakDesired = [NSScrollView frameSizeForContentSize:[breakView maximumFrameSize] + hasHorizontalScroller:YES + hasVerticalScroller:YES + borderType:[breakScroll borderType]]; + NSSize const watchDesired = [NSScrollView frameSizeForContentSize:[watchView maximumFrameSize] + hasHorizontalScroller:YES + hasVerticalScroller:YES + borderType:[watchScroll borderType]]; + NSSize const desired = NSMakeSize(MAX(breakDesired.width, watchDesired.width), + MAX(breakDesired.height, watchDesired.height)); + [self cascadeWindowWithDesiredSize:desired forView:tabs]; + + // don't forget the result + return self; +} + + +- (void)dealloc { + [super dealloc]; +} + + +- (IBAction)changeSubview:(id)sender { + [tabs selectTabViewItemAtIndex:[[sender selectedItem] tag]]; + [window setTitle:[[sender selectedItem] title]]; +} + +@end diff --git a/src/osd/modules/debugger/osx/debugosxwatchpointsview.h b/src/osd/modules/debugger/osx/debugosxwatchpointsview.h new file mode 100644 index 00000000000..02a2c885dfc --- /dev/null +++ b/src/osd/modules/debugger/osx/debugosxwatchpointsview.h @@ -0,0 +1,26 @@ +// license:BSD-3-Clause +// copyright-holders:Vas Crabb +//============================================================ +// +// debugosxwatchpointsview.h - MacOS X Cocoa debug window handling +// +// Copyright (c) 1996-2015, Nicola Salmoria and the MAME Team. +// Visit http://mamedev.org for licensing and usage restrictions. +// +//============================================================ + +#import "debugosx.h" +#import "debugosxdebugview.h" + +#include "emu.h" + +#import + + +@interface MAMEWatchpointsView : MAMEDebugView +{ +} + +- (id)initWithFrame:(NSRect)f machine:(running_machine &)m; + +@end diff --git a/src/osd/modules/debugger/osx/debugosxwatchpointsview.m b/src/osd/modules/debugger/osx/debugosxwatchpointsview.m new file mode 100644 index 00000000000..a023351eb77 --- /dev/null +++ b/src/osd/modules/debugger/osx/debugosxwatchpointsview.m @@ -0,0 +1,30 @@ +// license:BSD-3-Clause +// copyright-holders:Vas Crabb +//============================================================ +// +// debugosxwatchpointsview.m - MacOS X Cocoa debug window handling +// +// Copyright (c) 1996-2015, Nicola Salmoria and the MAME Team. +// Visit http://mamedev.org for licensing and usage restrictions. +// +//============================================================ + +#import "debugosxwatchpointsview.h" + +#include "debug/debugvw.h" + + +@implementation MAMEWatchpointsView + +- (id)initWithFrame:(NSRect)f machine:(running_machine &)m { + if (!(self = [super initWithFrame:f type:DVT_WATCH_POINTS machine:m])) + return nil; + return self; +} + + +- (void)dealloc { + [super dealloc]; +} + +@end diff --git a/src/osd/sdl/sdl.mak b/src/osd/sdl/sdl.mak index 5813707a5d4..f44cdd76c08 100644 --- a/src/osd/sdl/sdl.mak +++ b/src/osd/sdl/sdl.mak @@ -289,6 +289,7 @@ OBJDIRS += $(OSDOBJ)/modules/debugger/osx DEBUGOBJS = \ $(OSDOBJ)/modules/debugger/debugosx.o \ + $(OSDOBJ)/modules/debugger/osx/debugosxbreakpointsview.o \ $(OSDOBJ)/modules/debugger/osx/debugosxconsoleview.o \ $(OSDOBJ)/modules/debugger/osx/debugosxdebugcommandhistory.o \ $(OSDOBJ)/modules/debugger/osx/debugosxdebugconsole.o \ @@ -300,7 +301,9 @@ DEBUGOBJS = \ $(OSDOBJ)/modules/debugger/osx/debugosxerrorlogviewer.o \ $(OSDOBJ)/modules/debugger/osx/debugosxmemoryview.o \ $(OSDOBJ)/modules/debugger/osx/debugosxmemoryviewer.o \ - $(OSDOBJ)/modules/debugger/osx/debugosxregistersview.o + $(OSDOBJ)/modules/debugger/osx/debugosxpointsviewer.o \ + $(OSDOBJ)/modules/debugger/osx/debugosxregistersview.o \ + $(OSDOBJ)/modules/debugger/osx/debugosxwatchpointsview.o endif -- cgit v1.2.3 From 8a7a3abe07678bc674789812b090ea5ddd770866 Mon Sep 17 00:00:00 2001 From: Vas Crabb Date: Sat, 14 Feb 2015 23:01:09 +1100 Subject: Seems debug views don't mark dirty on click handling --- src/osd/modules/debugger/osx/debugosxdebugview.m | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/osd/modules/debugger/osx/debugosxdebugview.m b/src/osd/modules/debugger/osx/debugosxdebugview.m index 3f6a4f56d03..b9c6d49098d 100644 --- a/src/osd/modules/debugger/osx/debugosxdebugview.m +++ b/src/osd/modules/debugger/osx/debugosxdebugview.m @@ -403,12 +403,14 @@ static void debugwin_view_update(debug_view &view, void *osdprivate) - (void)mouseDown:(NSEvent *)event { NSPoint const location = [self convertPoint:[event locationInWindow] fromView:nil]; view->process_click(DCK_LEFT_CLICK, [self convertLocation:location]); + [self setNeedsDisplay:YES]; } - (void)rightMouseDown:(NSEvent *)event { NSPoint const location = [self convertPoint:[event locationInWindow] fromView:nil]; view->process_click(DCK_RIGHT_CLICK, [self convertLocation:location]); + [self setNeedsDisplay:YES]; [super rightMouseDown:event]; } -- cgit v1.2.3