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.4 by nigel, 2002-05-30T12:46:15Z vs.
Revision 1.11 by nigel, 2003-04-02T00:37:34Z

# 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-2003 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 49 | Line 49
49          drawView = NO;          // Disable drawing until later
50          fullScreen = NO;
51  
52 #ifdef SAVE_GSTATE
53        [self allocateGState];
54 #endif
55
52          return self;
53   }
54  
55 < - (void) dealloc
55 > - (void) awakeFromNib
56   {
57 < #ifdef SAVE_GSTATE
58 <        [self releaseGState];
59 < #endif
64 <        [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 + //
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  
79   static int prevFlags;
# Line 112 | 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   {
117        NSPoint loc = [event locationInWindow];
124          NSRect  box;
125 +        NSPoint loc;
126 +
127          if ( fullScreen )
128 <                return YES;
128 >        {
129 >                box = displayBox;
130 >                loc = [NSEvent mouseLocation];
131 >        }
132          else
133 +        {
134                  box = [self frame];
135 <        D(NSLog (@"%s - loc.x=%f, loc.y=%f, box.origin.x=%f, box.origin.y=%f",
136 <                                __PRETTY_FUNCTION__, loc.x, loc.y, box.origin.x, box.origin.y));
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 134 | Line 148 | static int prevFlags;
148          return [self mouse: loc inRect: box];
149   }
150  
137
151   //
152   // Custom methods
153   //
# Line 144 | 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 156 | 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 165 | 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 177 | 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
182        return nil;
241   }
242  
243   // Enable display of, and drawing into, the view
# Line 188 | 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 208 | Line 268 | static int prevFlags;
268                          isPlanar: (BOOL)  planar
269                          hasAlpha: (BOOL)  alpha
270   {
211        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;
221
284          [[self window] setAcceptsMouseMovedEvents:      YES];
285   //      [[self window] setInitialFirstResponder:        self];
286          [[self window] makeFirstResponder:                      self];
# Line 229 | Line 291 | static int prevFlags;
291          drawView = NO;
292   }
293  
294 < - (void) startedFullScreen
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
# Line 296 | Line 361 | static int prevFlags;
361          }
362   }
363  
299 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 < // CGAssociateMouseAndMouseCursorPosition(bool)
372 < // which will let you unlink the mouse input and the mouse cursor. So I
373 < // unlink the two, and the cursor doesn't move, but I still receive
374 < // MouseMoved events and can get the movement value using
375 < // CGGetLastMouseDelta.
312 <        else
313 <                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) )
316 <                return NO;
377 > static NSPoint  mouse;                  // Previous/current mouse location
378  
379 <        mouse = locInView;
379 > - (BOOL) processMouseMove: (NSEvent *) event
380 > {
381 >        NSPoint location;
382  
383          if ( fullScreen )
384          {
385 <                ADBMouseMoved((int)mouse.x, screen_height - (int)mouse.y);
385 >                [self fullscreenMouseMove];
386                  return YES;
387          }
388  
389 < #ifdef CAN_RESIZE_VIEW
390 <        int     mouseY = y - y * mouse.y / [self height];
391 <        int     mouseX =         x * mouse.x / [self width];
392 < #else
393 <        int     mouseY = y - (int) mouse.y;
394 <        int     mouseX =         (int) mouse.x;
395 < #endif
389 >        location = [self convertPoint: [event locationInWindow] fromView:nil];
390 >
391 >        D(NSLog (@"%s - loc.x=%f, loc.y=%f",
392 >                                __PRETTY_FUNCTION__, location.x, location.y));
393 >
394 >        if ( NSEqualPoints(location, mouse) )
395 >                return NO;
396 >
397 >        mouse = location;
398 >
399 >        int     mouseY = y - (int) (y * mouse.y / [self height]);
400 >        int     mouseX =         (int) (x * mouse.x / [self width]);
401 >        // If the view was not resizable, then this would be simpler:
402 >        // int  mouseY = y - (int) mouse.y;
403 >        // int  mouseX =         (int) mouse.x;
404  
405          ADBMouseMoved(mouseX, mouseY);
406          return YES;
# Line 367 | Line 438 | static NSPoint mouse;                  // Previous/curr
438   #if DEBUG
439   - (void) randomise              // Draw some coloured snow in the bitmap
440   {
441 <        unsigned char    *pixel;
441 >        unsigned char   *data,
442 >                                        *pixel;
443 >
444 >  #ifdef NSBITMAP
445 >        data = [bitmap bitmapData];
446 >  #else
447 >        data = bitmap;
448 >  #endif
449  
450          for ( int i = 0; i < 1000; ++i )
451          {
452 <                pixel = [bitmap bitmapData]
375 <                                + (int) (1.0 * [bitmap bytesPerRow] * 342       //[bitmap height]
376 <                                                         * rand() / RAND_MAX);
452 >                pixel  = data + (int) (numBytes * rand() / RAND_MAX);
453                  *pixel = (unsigned char) (256.0 * rand() / RAND_MAX);
454          }
455   }
# Line 394 | Line 470 | static NSPoint mouse;                  // Previous/curr
470          [bitmap draw];
471   #endif
472   #ifdef CGIMAGEREF
473 <        cgDrawInto(rect, bitmap);
473 >        cgDrawInto(rect, cgImgRep);
474   #endif
475   #ifdef CGDRAWBITMAP
476          [self CGDrawBitmap];
477   #endif
478   }
479  
480 + - (void) setTo: (int) val               // Set all of bitmap to val
481 + {
482 +        unsigned char   *data
483 +  #ifdef NSBITMAP
484 +                                                        = [bitmap bitmapData];
485 +  #else
486 +                                                        = (unsigned char *) bitmap;
487 +  #endif
488 +
489 +        memset(data, val, (long unsigned)numBytes);
490 + }
491 +
492 + - (void) blacken        // Set bitmap black
493 + {
494 +        [self setTo: 0];
495 + }
496 +
497 + - (void) clear          // Set bitmap white
498 + {
499 +        [self setTo: 0xFF];
500 + }
501 +
502   //
503   // Extra drawing stuff
504   //
505  
506   #ifdef CGDRAWBITMAP
507 < extern "C" void CGDrawBitmap();
507 > extern "C" void CGDrawBitmap(...);
508  
509   - (void) CGDrawBitmap
510   {
511 <        CGContextRef    cgContext = [[NSGraphicsContext currentContext]
512 <                                                                                                                graphicsPort];
511 >        CGContextRef    cgContext = (CGContextRef) [[NSGraphicsContext currentContext]
512 >                                                                                                graphicsPort];
513          NSRect                  rect = [self bounds];
514          CGRect                  cgRect = {
515                                                                  {rect.origin.x, rect.origin.y},
# Line 421 | Line 519 | extern "C" void CGDrawBitmap();
519          CGColorSpaceRef colourSpace = CGColorSpaceCreateDeviceRGB();
520  
521  
522 <        CGContextSetShouldAntialias(cgContext, NO);             // Seems to have no effect?
522 > //      CGContextSetShouldAntialias(cgContext, NO);             // Seems to have no effect?
523  
524          CGDrawBitmap(cgContext, cgRect, x, y, bps, spp, bpp,
525                                          bytesPerRow, isPlanar, hasAlpha, colourSpace, &bitmap);
# Line 430 | Line 528 | extern "C" void CGDrawBitmap();
528  
529   #ifdef CGIMAGEREF
530   void
531 < cgDrawInto(NSRect rect, CGImageRef bitmap)
531 > cgDrawInto(NSRect rect, CGImageRef cgImgRep)
532   {
533 <        CGContextRef    cgContext = [[NSGraphicsContext currentContext]
534 <                                                                                                                graphicsPort];
533 >        CGContextRef    cgContext = (CGContextRef) [[NSGraphicsContext currentContext]
534 >                                                                                                graphicsPort];
535          CGRect                  cgRect = {
536                                                                  {rect.origin.x, rect.origin.y},
537                                                                  {rect.size.width, rect.size.height}
538                                                           };
539  
540 <        CGContextSetShouldAntialias(cgContext, NO);             // Seems to have no effect?
540 > //      CGContextSetShouldAntialias(cgContext, NO);             // Seems to have no effect?
541  
542 <        CGContextDrawImage(cgContext, cgRect, bitmap);
542 >        CGContextDrawImage(cgContext, cgRect, cgImgRep);
543   }
544   #endif
545  

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines