ViewVC Help
View File | Revision Log | Show Annotations | Revision Graph | Root Listing
root/cebix/BasiliskII/src/MacOSX/EmulatorView.mm
(Generate patch)

Comparing BasiliskII/src/MacOSX/EmulatorView.mm (file contents):
Revision 1.1 by nigel, 2002-03-16T04:00:18Z vs.
Revision 1.13 by nigel, 2004-01-29T12:10:47Z

# Line 1 | Line 1
1   /*
2 < *      EmulatorView.mm - Custom NSView for Basilisk II graphics output
2 > *      EmulatorView.mm - Custom NSView for Basilisk II windowed graphics output
3   *
4   *      $Id$
5   *
6 < *  Basilisk II (C) 1997-2002 Christian Bauer
6 > *  Basilisk II (C) 1997-2004 Christian Bauer
7   *
8   *  This program is free software; you can redistribute it and/or modify
9   *  it under the terms of the GNU General Public License as published by
# Line 47 | Line 47
47          output = self;          // Set global for access by Basilisk C++ code
48   //      bitmap = nil;           // Set by readyToDraw:
49          drawView = NO;          // Disable drawing until later
50 <
51 < #ifdef SAVE_GSTATE
52 <        [self allocateGState];
53 < #endif
50 >        fullScreen = NO;
51  
52          return self;
53   }
54  
55 < - (void) dealloc
55 > - (void) awakeFromNib
56   {
57 < #ifdef SAVE_GSTATE
58 <        [self releaseGState];
59 < #endif
63 <        [super dealloc];
57 >        // Here we store the height of the screen which the app was opened on.
58 >        // NSApplication's sendEvent: always uses that screen for its mouse co-ords
59 >        screen_height = (int) [[NSScreen mainScreen] frame].size.height;
60   }
61  
62 < // Mouse click in this window. If window is not active, should click be passed to this view?
62 >
63 > // Mouse click in this window. If window is not active,
64 > // should the click be passed to this view?
65   - (BOOL) acceptsFirstMouse: (NSEvent *) event
66   {
67          return [self mouseInView];
68   }
69  
70 < /*****
71 < - (BOOL) acceptsFirstResponder
72 < {
73 < //      return YES;
74 <        return [self mouseInView];
75 < }
78 < *****/
70 >
71 > //
72 > // Key event processing.
73 > // OS X doesn't send us separate events for the modifier keys
74 > // (shift/control/command), so we need to monitor them separately
75 > //
76  
77   #include <adb.h>
78  
# Line 118 | Line 115 | static int prevFlags;
115          prevFlags = flags;
116   }
117  
118 + //
119 + // Windowed mode. We only send mouse/key events
120 + // if the OS X mouse is within the little screen
121 + //
122   - (BOOL) mouseInView: (NSEvent *) event
123   {
124 <        NSPoint loc = [event locationInWindow];
125 <        NSRect  box = [self frame];
126 <        D(NSLog (@"%s - loc.x=%f, loc.y=%f, box.origin.x=%f, box.origin.y=%f",
127 <                                __PRETTY_FUNCTION__, loc.x, loc.y, box.origin.x, box.origin.y));
124 >        NSRect  box;
125 >        NSPoint loc;
126 >
127 >        if ( fullScreen )
128 >        {
129 >                box = displayBox;
130 >                loc = [NSEvent mouseLocation];
131 >        }
132 >        else
133 >        {
134 >                box = [self frame];
135 >                loc = [event locationInWindow];
136 >        }
137 >
138 >        D(NSLog (@"%s - loc.x=%f, loc.y=%f, box.origin.x=%f, box.origin.y=%f, box.size.width=%f, box.size.height=%f", __PRETTY_FUNCTION__, loc.x, loc.y, box.origin.x, box.origin.y, box.size.width, box.size.height));
139          return [self mouse: loc inRect: box];
140   }
141  
# Line 136 | Line 148 | static int prevFlags;
148          return [self mouse: loc inRect: box];
149   }
150  
139
151   //
152   // Custom methods
153   //
# Line 146 | Line 157 | static int prevFlags;
157          int                     i;
158          float           seconds;
159          NSDate          *startDate;
160 +        char            *method;
161  
162          if ( ! drawView )
163 +        {
164 +                WarningSheet (@"The emulator has not been setup yet.",
165 +                                          @"Try to run, then pause the emulator, first.", nil, [self window]);
166                  return;
167 +        }
168  
169          drawView = NO;
170          [self lockFocus];
# Line 158 | Line 174 | static int prevFlags;
174                  [bitmap draw];
175   #endif
176   #ifdef CGIMAGEREF
177 <                cgDrawInto([self bounds], bitmap);
177 >                cgDrawInto([self bounds], cgImgRep);
178   #endif
179   #ifdef CGDRAWBITMAP
180                  [self CGDrawBitmap];
# Line 167 | Line 183 | static int prevFlags;
183          [self unlockFocus];
184          drawView = YES;
185  
186 <        InfoSheet(@"Benchmark run. 300 frames.",
186 > #ifdef NSBITMAP
187 >        method = "NSBITMAP";
188 > #endif
189 > #ifdef CGIMAGEREF
190 >        method = "CGIMAGEREF";
191 > #endif
192 > #ifdef CGDRAWBITMAP
193 >        method = "CGDRAWBITMAP";
194 > #endif
195 >
196 >        InfoSheet(@"Ran benchmark (300 screen redraws)",
197                            [NSString stringWithFormat:
198 <                                @"%.2f seconds, %.3f frames per second", seconds, i/seconds],
198 >                                @"%.2f seconds, %.3f frames per second (using %s implementation)",
199 >                                seconds, i/seconds, method],
200                            @"Thanks", [self window]);
201   }
202  
# Line 179 | Line 206 | static int prevFlags;
206   #ifdef NSBITMAP
207          return [bitmap TIFFRepresentation];
208   #else
209 <        WarningAlert("How do I get a TIFF from a CGImageRef?");
209 >        NSBitmapImageRep        *b = [NSBitmapImageRep alloc];
210 >
211 >        b = [b initWithBitmapDataPlanes: (unsigned char **) &bitmap
212 >                                                 pixelsWide: x
213 >                                                 pixelsHigh: y
214 >  #ifdef CGIMAGEREF
215 >                                          bitsPerSample: CGImageGetBitsPerComponent(cgImgRep)
216 >                                        samplesPerPixel: 3
217 >                                                   hasAlpha: NO
218 >                                                   isPlanar: NO
219 >                                         colorSpaceName: NSCalibratedRGBColorSpace
220 >                                                bytesPerRow: CGImageGetBytesPerRow(cgImgRep)
221 >                                           bitsPerPixel: CGImageGetBitsPerPixel(cgImgRep)];
222 >  #endif
223 >  #ifdef CGDRAWBITMAP
224 >                                          bitsPerSample: bps
225 >                                        samplesPerPixel: spp
226 >                                                   hasAlpha: hasAlpha
227 >                                                   isPlanar: isPlanar
228 >                                         colorSpaceName: NSCalibratedRGBColorSpace
229 >                                                bytesPerRow: bytesPerRow
230 >                                           bitsPerPixel: bpp];
231 >  #endif
232 >
233 >    if ( ! b )
234 >        {
235 >                ErrorAlert("Could not allocate an NSBitmapImageRep for the TIFF");
236 >                return nil;
237 >        }
238 >
239 >        return [b TIFFRepresentation];
240   #endif
184        return nil;
241   }
242  
243   // Enable display of, and drawing into, the view
# Line 190 | Line 246 | static int prevFlags;
246                    imageWidth: (short) width
247                   imageHeight: (short) height
248   {
249 <        bitmap = theBitmap;
249 >        numBytes = [theBitmap bytesPerRow] * height;
250   #endif
251   #ifdef CGIMAGEREF
252   - (void) readyToDraw: (CGImageRef) image
253 +                          bitmap: (void *) theBitmap
254                    imageWidth: (short) width
255                   imageHeight: (short) height
256   {
257 <        bitmap = image;
257 >        cgImgRep = image;
258 >        numBytes = CGImageGetBytesPerRow(image) * height;
259   #endif
260   #ifdef CGDRAWBITMAP
261   - (void) readyToDraw: (void *) theBitmap
# Line 210 | Line 268 | static int prevFlags;
268                          isPlanar: (BOOL)  planar
269                          hasAlpha: (BOOL)  alpha
270   {
213        bitmap = theBitmap;
271          bps = bitsPerSample;
272          spp = samplesPerPixel;
273          bpp = bitsPerPixel;
274          bytesPerRow = bpr;
275          isPlanar = planar;
276          hasAlpha = alpha;
277 +        numBytes = bpr * height;
278   #endif
279 +        D(NSLog(@"readyToDraw: theBitmap=%lx\n", theBitmap));
280 +
281 +        bitmap = theBitmap;
282          x = width, y = height;
283          drawView = YES;
223
284          [[self window] setAcceptsMouseMovedEvents:      YES];
285   //      [[self window] setInitialFirstResponder:        self];
286          [[self window] makeFirstResponder:                      self];
# Line 231 | Line 291 | static int prevFlags;
291          drawView = NO;
292   }
293  
294 + - (void) startedFullScreen: (CGDirectDisplayID) display
295 + {
296 +        CGRect  displayBounds = CGDisplayBounds(display);
297 +
298 +        fullScreen = YES;
299 +        memcpy(&displayBox, &displayBounds, sizeof(displayBox));
300 + }
301 +
302   - (short) width
303   {
304          return (short)[self bounds].size.width;
# Line 241 | Line 309 | static int prevFlags;
309          return (short)[self bounds].size.height;
310   }
311  
312 + - (BOOL) isFullScreen
313 + {
314 +        return fullScreen;
315 + }
316 +
317   - (BOOL) isOpaque
318   {
319          return drawView;
# Line 248 | Line 321 | static int prevFlags;
321  
322   - (BOOL) processKeyEvent: (NSEvent *) event
323   {
324 <        if ( [self acceptsFirstMouse: event] || FULLSCREEN )
324 >        if ( fullScreen || [self acceptsFirstMouse: event] )
325                  if ( [event isARepeat] )
326                          return NO;
327                  else
# Line 261 | Line 334 | static int prevFlags;
334   - (void) keyDown: (NSEvent *) event
335   {
336          if ( [self processKeyEvent: event] )
337 <                ADBKeyDown([event keyCode]);
337 >        {
338 >                int     code = [event keyCode];
339 >
340 >                if ( code == 126 )      code = 0x3e;    // CURS_UP
341 >                if ( code == 125 )      code = 0x3d;    // CURS_DOWN
342 >                if ( code == 124 )      code = 0x3c;    // CURS_RIGHT
343 >                if ( code == 123 )      code = 0x3b;    // CURS_LEFT
344 >
345 >                ADBKeyDown(code);
346 >        }
347   }
348  
349   - (void) keyUp: (NSEvent *) event
350   {
351          if ( [self processKeyEvent: event] )
352 <                ADBKeyUp([event keyCode]);
352 >        {
353 >                int     code = [event keyCode];
354 >
355 >                if ( code == 126 )      code = 0x3e;    // CURS_UP
356 >                if ( code == 125 )      code = 0x3d;    // CURS_DOWN
357 >                if ( code == 124 )      code = 0x3c;    // CURS_RIGHT
358 >                if ( code == 123 )      code = 0x3b;    // CURS_LEFT
359 >
360 >                ADBKeyUp(code);
361 >        }
362   }
363  
273 static NSPoint  mouse;                  // Previous/current mouse location
364  
365 < - (BOOL) processMouseMove: (NSEvent *) event
365 > - (void) fullscreenMouseMove
366   {
367 <        NSPoint locInView;
367 >        NSPoint location = [NSEvent mouseLocation];
368  
369 <        if ( FULLSCREEN )
370 <                locInView = [NSEvent mouseLocation];
371 <        else
372 <                locInView = [self convertPoint: [event locationInWindow] fromView:nil];
369 >        D(NSLog (@"%s - loc.x=%f, loc.y=%f",
370 >                                __PRETTY_FUNCTION__, location.x, location.y));
371 >        D(NSLog (@"%s - Sending ADBMouseMoved(%d,%d). (%d-%d)",
372 >                                        __PRETTY_FUNCTION__, (int)location.x,
373 >                                        screen_height - (int)location.y, screen_height, (int)location.y));
374 >        ADBMouseMoved((int)location.x, screen_height - (int)location.y);
375 > }
376  
377 <        if ( NSEqualPoints(locInView, mouse) )
285 <                return NO;
377 > static NSPoint  mouse;                  // Previous/current mouse location
378  
379 <        mouse = locInView;
379 > - (BOOL) processMouseMove: (NSEvent *) event
380 > {
381 >        if ( ! drawView )
382 >        {
383 >                D(NSLog(@"Unable to process event - Emulator has not started yet"));
384 >                return NO;
385 >        }
386  
387 <        if ( FULLSCREEN )
387 >        if ( fullScreen )
388          {
389 <                ADBMouseMoved((int)mouse.x, screen_height - (int)mouse.y);
389 >                [self fullscreenMouseMove];
390                  return YES;
391          }
392  
393 < #ifdef CAN_RESIZE_VIEW
394 <        int     mouseY = y - y * mouse.y / [self height];
395 <        int     mouseX =         x * mouse.x / [self width];
396 < #else
397 <        int     mouseY = y - (int) mouse.y;
398 <        int     mouseX =         (int) mouse.x;
399 < #endif
393 >        NSPoint location = [self convertPoint: [event locationInWindow] fromView:nil];
394 >
395 >        D(NSLog (@"%s - loc.x=%f, loc.y=%f",
396 >                                __PRETTY_FUNCTION__, location.x, location.y));
397 >
398 >        if ( NSEqualPoints(location, mouse) )
399 >                return NO;
400 >
401 >        mouse = location;
402 >
403 >        int     mouseY = y - (int) (y * mouse.y / [self height]);
404 >        int     mouseX =         (int) (x * mouse.x / [self width]);
405 >        // If the view was not resizable, then this would be simpler:
406 >        // int  mouseY = y - (int) mouse.y;
407 >        // int  mouseX =         (int) mouse.x;
408  
409          ADBMouseMoved(mouseX, mouseY);
410          return YES;
# Line 336 | Line 442 | static NSPoint mouse;                  // Previous/curr
442   #if DEBUG
443   - (void) randomise              // Draw some coloured snow in the bitmap
444   {
445 <        unsigned char    *pixel;
445 >        unsigned char   *data,
446 >                                        *pixel;
447 >
448 >  #ifdef NSBITMAP
449 >        data = [bitmap bitmapData];
450 >  #else
451 >        data = bitmap;
452 >  #endif
453  
454          for ( int i = 0; i < 1000; ++i )
455          {
456 <                pixel = [bitmap bitmapData]
344 <                                + (int) (1.0 * [bitmap bytesPerRow] * 342       //[bitmap height]
345 <                                                         * rand() / RAND_MAX);
456 >                pixel  = data + (int) (numBytes * rand() / RAND_MAX);
457                  *pixel = (unsigned char) (256.0 * rand() / RAND_MAX);
458          }
459   }
# Line 363 | Line 474 | static NSPoint mouse;                  // Previous/curr
474          [bitmap draw];
475   #endif
476   #ifdef CGIMAGEREF
477 <        cgDrawInto(rect, bitmap);
477 >        cgDrawInto(rect, cgImgRep);
478   #endif
479   #ifdef CGDRAWBITMAP
480          [self CGDrawBitmap];
481   #endif
482   }
483  
484 + - (void) setTo: (int) val               // Set all of bitmap to val
485 + {
486 +        unsigned char   *data
487 +  #ifdef NSBITMAP
488 +                                                        = [bitmap bitmapData];
489 +  #else
490 +                                                        = (unsigned char *) bitmap;
491 +  #endif
492 +
493 +        memset(data, val, (long unsigned)numBytes);
494 + }
495 +
496 + - (void) blacken        // Set bitmap black
497 + {
498 +        [self setTo: 0];
499 + }
500 +
501 + - (void) clear          // Set bitmap white
502 + {
503 +        [self setTo: 0xFF];
504 + }
505 +
506   //
507   // Extra drawing stuff
508   //
509  
510   #ifdef CGDRAWBITMAP
511 < extern "C" void CGDrawBitmap();
511 > extern "C" void CGDrawBitmap(...);
512  
513   - (void) CGDrawBitmap
514   {
515 <        CGContextRef    cgContext = [[NSGraphicsContext currentContext]
516 <                                                                                                                graphicsPort];
515 >        CGContextRef    cgContext = (CGContextRef) [[NSGraphicsContext currentContext]
516 >                                                                                                graphicsPort];
517          NSRect                  rect = [self bounds];
518          CGRect                  cgRect = {
519                                                                  {rect.origin.x, rect.origin.y},
# Line 390 | Line 523 | extern "C" void CGDrawBitmap();
523          CGColorSpaceRef colourSpace = CGColorSpaceCreateDeviceRGB();
524  
525  
526 <        CGContextSetShouldAntialias(cgContext, NO);             // Seems to have no effect?
526 > //      CGContextSetShouldAntialias(cgContext, NO);             // Seems to have no effect?
527  
528          CGDrawBitmap(cgContext, cgRect, x, y, bps, spp, bpp,
529                                          bytesPerRow, isPlanar, hasAlpha, colourSpace, &bitmap);
# Line 399 | Line 532 | extern "C" void CGDrawBitmap();
532  
533   #ifdef CGIMAGEREF
534   void
535 < cgDrawInto(NSRect rect, CGImageRef bitmap)
535 > cgDrawInto(NSRect rect, CGImageRef cgImgRep)
536   {
537 <        CGContextRef    cgContext = [[NSGraphicsContext currentContext]
538 <                                                                                                                graphicsPort];
537 >        CGContextRef    cgContext = (CGContextRef) [[NSGraphicsContext currentContext]
538 >                                                                                                graphicsPort];
539          CGRect                  cgRect = {
540                                                                  {rect.origin.x, rect.origin.y},
541                                                                  {rect.size.width, rect.size.height}
542                                                           };
543  
544 <        CGContextSetShouldAntialias(cgContext, NO);             // Seems to have no effect?
544 > //      CGContextSetShouldAntialias(cgContext, NO);             // Seems to have no effect?
545  
546 <        CGContextDrawImage(cgContext, cgRect, bitmap);
546 >        CGContextDrawImage(cgContext, cgRect, cgImgRep);
547   }
548   #endif
549  
550 < @end
550 > @end

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines