ViewVC Help
View File | Revision Log | Show Annotations | Revision Graph | Root Listing
root/cebix/BasiliskII/src/MacOSX/EmulatorView.mm
Revision: 1.4
Committed: 2002-05-30T12:46:15Z (22 years, 6 months ago) by nigel
Branch: MAIN
Changes since 1.3: +25 -5 lines
Log Message:
New way of storing if emulator is in full screen mode

File Contents

# User Rev Content
1 nigel 1.1 /*
2     * EmulatorView.mm - Custom NSView for Basilisk II graphics output
3     *
4 nigel 1.4 * $Id: EmulatorView.mm,v 1.3 2002/05/12 10:34:16 nigel Exp $
5 nigel 1.1 *
6     * Basilisk II (C) 1997-2002 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
10     * the Free Software Foundation; either version 2 of the License, or
11     * (at your option) any later version.
12     *
13     * This program is distributed in the hope that it will be useful,
14     * but WITHOUT ANY WARRANTY; without even the implied warranty of
15     * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16     * GNU General Public License for more details.
17     *
18     * You should have received a copy of the GNU General Public License
19     * along with this program; if not, write to the Free Software
20     * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
21     */
22    
23     #import "sysdeps.h" // Types used in Basilisk C++ code,
24    
25     #define DEBUG 0
26     #import <debug.h>
27    
28     #import <Cocoa/Cocoa.h>
29    
30     #import "main_macosx.h" // For WarningAlert() et al prototypes
31     #import "misc_macosx.h" // For InfoSheet() prototype
32     #import "video_macosx.h" // For init_* globals, and bitmap drawing strategy
33    
34     #import "EmulatorView.h"
35    
36     @implementation EmulatorView
37    
38    
39     //
40     // Standard NSView methods that we override
41     //
42    
43     - (id) initWithFrame: (NSRect) frameRect
44     {
45     self = [super initWithFrame: frameRect];
46    
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 nigel 1.4 fullScreen = NO;
51 nigel 1.1
52     #ifdef SAVE_GSTATE
53     [self allocateGState];
54     #endif
55    
56     return self;
57     }
58    
59     - (void) dealloc
60     {
61     #ifdef SAVE_GSTATE
62     [self releaseGState];
63     #endif
64     [super dealloc];
65     }
66    
67     // Mouse click in this window. If window is not active, should click be passed to this view?
68     - (BOOL) acceptsFirstMouse: (NSEvent *) event
69     {
70     return [self mouseInView];
71     }
72    
73    
74     #include <adb.h>
75    
76     static int prevFlags;
77    
78     - (void) flagsChanged: (NSEvent *) event
79     {
80     int flags = [event modifierFlags];
81    
82     if ( (flags & NSAlphaShiftKeyMask) != (prevFlags & NSAlphaShiftKeyMask) )
83     if ( flags & NSAlphaShiftKeyMask )
84     ADBKeyDown(0x39); // CAPS_LOCK
85     else
86     ADBKeyUp(0x39);
87    
88     if ( (flags & NSShiftKeyMask) != (prevFlags & NSShiftKeyMask) )
89     if ( flags & NSShiftKeyMask )
90     ADBKeyDown(0x38); // SHIFT_LEFT
91     else
92     ADBKeyUp(0x38);
93    
94     if ( (flags & NSControlKeyMask) != (prevFlags & NSControlKeyMask) )
95     if ( flags & NSControlKeyMask )
96     ADBKeyDown(0x36); // CTL_LEFT
97     else
98     ADBKeyUp(0x36);
99    
100     if ( (flags & NSAlternateKeyMask) != (prevFlags & NSAlternateKeyMask) )
101     if ( flags & NSAlternateKeyMask )
102     ADBKeyDown(0x3a); // OPTION_LEFT
103     else
104     ADBKeyUp(0x3a);
105    
106     if ( (flags & NSCommandKeyMask) != (prevFlags & NSCommandKeyMask) )
107     if ( flags & NSCommandKeyMask )
108     ADBKeyDown(0x37); // APPLE_LEFT
109     else
110     ADBKeyUp(0x37);
111    
112     prevFlags = flags;
113     }
114    
115     - (BOOL) mouseInView: (NSEvent *) event
116     {
117     NSPoint loc = [event locationInWindow];
118 nigel 1.4 NSRect box;
119     if ( fullScreen )
120     return YES;
121     else
122     box = [self frame];
123 nigel 1.1 D(NSLog (@"%s - loc.x=%f, loc.y=%f, box.origin.x=%f, box.origin.y=%f",
124     __PRETTY_FUNCTION__, loc.x, loc.y, box.origin.x, box.origin.y));
125     return [self mouse: loc inRect: box];
126     }
127    
128     - (BOOL) mouseInView
129     {
130     NSPoint loc = [[self window] mouseLocationOutsideOfEventStream];
131     NSRect box = [self frame];
132     D(NSLog (@"%s - loc.x=%f, loc.y=%f, box.origin.x=%f, box.origin.y=%f",
133     __PRETTY_FUNCTION__, loc.x, loc.y, box.origin.x, box.origin.y));
134     return [self mouse: loc inRect: box];
135     }
136    
137    
138     //
139     // Custom methods
140     //
141    
142     - (void) benchmark
143     {
144     int i;
145     float seconds;
146     NSDate *startDate;
147    
148     if ( ! drawView )
149     return;
150    
151     drawView = NO;
152     [self lockFocus];
153     startDate = [NSDate date];
154     for (i = 1; i < 300; ++i )
155     #ifdef NSBITMAP
156     [bitmap draw];
157     #endif
158     #ifdef CGIMAGEREF
159     cgDrawInto([self bounds], bitmap);
160     #endif
161     #ifdef CGDRAWBITMAP
162     [self CGDrawBitmap];
163     #endif
164     seconds = -[startDate timeIntervalSinceNow];
165     [self unlockFocus];
166     drawView = YES;
167    
168     InfoSheet(@"Benchmark run. 300 frames.",
169     [NSString stringWithFormat:
170     @"%.2f seconds, %.3f frames per second", seconds, i/seconds],
171     @"Thanks", [self window]);
172     }
173    
174     // Return a TIFF for a snapshot of the screen image
175     - (NSData *) TIFFrep
176     {
177     #ifdef NSBITMAP
178     return [bitmap TIFFRepresentation];
179     #else
180     WarningAlert("How do I get a TIFF from a CGImageRef?");
181     #endif
182     return nil;
183     }
184    
185     // Enable display of, and drawing into, the view
186     #ifdef NSBITMAP
187     - (void) readyToDraw: (NSBitmapImageRep *) theBitmap
188     imageWidth: (short) width
189     imageHeight: (short) height
190     {
191     bitmap = theBitmap;
192     #endif
193     #ifdef CGIMAGEREF
194     - (void) readyToDraw: (CGImageRef) image
195     imageWidth: (short) width
196     imageHeight: (short) height
197     {
198     bitmap = image;
199     #endif
200     #ifdef CGDRAWBITMAP
201     - (void) readyToDraw: (void *) theBitmap
202     width: (short) width
203     height: (short) height
204     bps: (short) bitsPerSample
205     spp: (short) samplesPerPixel
206     bpp: (short) bitsPerPixel
207     bpr: (int) bpr
208     isPlanar: (BOOL) planar
209     hasAlpha: (BOOL) alpha
210     {
211     bitmap = theBitmap;
212     bps = bitsPerSample;
213     spp = samplesPerPixel;
214     bpp = bitsPerPixel;
215     bytesPerRow = bpr;
216     isPlanar = planar;
217     hasAlpha = alpha;
218     #endif
219     x = width, y = height;
220     drawView = YES;
221    
222     [[self window] setAcceptsMouseMovedEvents: YES];
223     // [[self window] setInitialFirstResponder: self];
224     [[self window] makeFirstResponder: self];
225     }
226    
227     - (void) disableDrawing
228     {
229     drawView = NO;
230     }
231    
232 nigel 1.4 - (void) startedFullScreen
233     {
234     fullScreen = YES;
235     }
236    
237 nigel 1.1 - (short) width
238     {
239     return (short)[self bounds].size.width;
240     }
241    
242     - (short) height
243     {
244     return (short)[self bounds].size.height;
245     }
246    
247 nigel 1.4 - (BOOL) isFullScreen
248     {
249     return fullScreen;
250     }
251    
252 nigel 1.1 - (BOOL) isOpaque
253     {
254     return drawView;
255     }
256    
257     - (BOOL) processKeyEvent: (NSEvent *) event
258     {
259 nigel 1.4 if ( fullScreen || [self acceptsFirstMouse: event] )
260 nigel 1.1 if ( [event isARepeat] )
261     return NO;
262     else
263     return YES;
264    
265     [self interpretKeyEvents:[NSArray arrayWithObject:event]];
266     return NO;
267     }
268    
269     - (void) keyDown: (NSEvent *) event
270     {
271     if ( [self processKeyEvent: event] )
272 nigel 1.2 {
273     int code = [event keyCode];
274    
275     if ( code == 126 ) code = 0x3e; // CURS_UP
276     if ( code == 125 ) code = 0x3d; // CURS_DOWN
277     if ( code == 124 ) code = 0x3c; // CURS_RIGHT
278     if ( code == 123 ) code = 0x3b; // CURS_LEFT
279    
280     ADBKeyDown(code);
281     }
282 nigel 1.1 }
283    
284     - (void) keyUp: (NSEvent *) event
285     {
286     if ( [self processKeyEvent: event] )
287 nigel 1.2 {
288     int code = [event keyCode];
289    
290     if ( code == 126 ) code = 0x3e; // CURS_UP
291     if ( code == 125 ) code = 0x3d; // CURS_DOWN
292     if ( code == 124 ) code = 0x3c; // CURS_RIGHT
293     if ( code == 123 ) code = 0x3b; // CURS_LEFT
294    
295     ADBKeyUp(code);
296     }
297 nigel 1.1 }
298    
299     static NSPoint mouse; // Previous/current mouse location
300    
301     - (BOOL) processMouseMove: (NSEvent *) event
302     {
303     NSPoint locInView;
304    
305 nigel 1.4 if ( fullScreen )
306 nigel 1.1 locInView = [NSEvent mouseLocation];
307 nigel 1.4 // CGAssociateMouseAndMouseCursorPosition(bool)
308     // which will let you unlink the mouse input and the mouse cursor. So I
309     // unlink the two, and the cursor doesn't move, but I still receive
310     // MouseMoved events and can get the movement value using
311     // CGGetLastMouseDelta.
312 nigel 1.1 else
313     locInView = [self convertPoint: [event locationInWindow] fromView:nil];
314    
315     if ( NSEqualPoints(locInView, mouse) )
316     return NO;
317    
318     mouse = locInView;
319    
320 nigel 1.4 if ( fullScreen )
321 nigel 1.1 {
322     ADBMouseMoved((int)mouse.x, screen_height - (int)mouse.y);
323     return YES;
324     }
325    
326     #ifdef CAN_RESIZE_VIEW
327     int mouseY = y - y * mouse.y / [self height];
328     int mouseX = x * mouse.x / [self width];
329     #else
330     int mouseY = y - (int) mouse.y;
331     int mouseX = (int) mouse.x;
332     #endif
333    
334     ADBMouseMoved(mouseX, mouseY);
335     return YES;
336     }
337    
338     - (void) mouseDown: (NSEvent *) event
339     {
340     [self processMouseMove: event];
341     ADBMouseDown(0);
342     }
343    
344     - (void) mouseDragged: (NSEvent *) event
345     {
346     [self processMouseMove: event];
347     }
348    
349     - (void) mouseMoved: (NSEvent *) event
350     {
351     #if DEBUG
352     if ( ! [self mouseInView] )
353     {
354     NSLog (@"%s - Received event while outside of view", __PRETTY_FUNCTION__);
355     return;
356     }
357     #endif
358     [self processMouseMove: event];
359     }
360    
361     - (void) mouseUp: (NSEvent *) event
362     {
363     [self processMouseMove: event];
364     ADBMouseUp(0);
365     }
366    
367     #if DEBUG
368     - (void) randomise // Draw some coloured snow in the bitmap
369     {
370     unsigned char *pixel;
371    
372     for ( int i = 0; i < 1000; ++i )
373     {
374     pixel = [bitmap bitmapData]
375     + (int) (1.0 * [bitmap bytesPerRow] * 342 //[bitmap height]
376     * rand() / RAND_MAX);
377     *pixel = (unsigned char) (256.0 * rand() / RAND_MAX);
378     }
379     }
380     #endif
381    
382     - (void) drawRect: (NSRect) rect
383     {
384     if ( ! drawView ) // If the emulator is still being setup,
385     return; // we do not want to draw
386    
387     #if DEBUG
388     NSLog(@"In drawRect");
389     [self randomise];
390     #endif
391    
392     #ifdef NSBITMAP
393     NSRectClip(rect);
394     [bitmap draw];
395     #endif
396     #ifdef CGIMAGEREF
397     cgDrawInto(rect, bitmap);
398     #endif
399     #ifdef CGDRAWBITMAP
400     [self CGDrawBitmap];
401     #endif
402     }
403    
404     //
405     // Extra drawing stuff
406     //
407    
408     #ifdef CGDRAWBITMAP
409     extern "C" void CGDrawBitmap();
410    
411     - (void) CGDrawBitmap
412     {
413     CGContextRef cgContext = [[NSGraphicsContext currentContext]
414     graphicsPort];
415     NSRect rect = [self bounds];
416     CGRect cgRect = {
417     {rect.origin.x, rect.origin.y},
418     {rect.size.width, rect.size.height}
419     };
420    
421     CGColorSpaceRef colourSpace = CGColorSpaceCreateDeviceRGB();
422    
423    
424     CGContextSetShouldAntialias(cgContext, NO); // Seems to have no effect?
425    
426     CGDrawBitmap(cgContext, cgRect, x, y, bps, spp, bpp,
427     bytesPerRow, isPlanar, hasAlpha, colourSpace, &bitmap);
428     }
429     #endif
430    
431     #ifdef CGIMAGEREF
432     void
433     cgDrawInto(NSRect rect, CGImageRef bitmap)
434     {
435     CGContextRef cgContext = [[NSGraphicsContext currentContext]
436     graphicsPort];
437     CGRect cgRect = {
438     {rect.origin.x, rect.origin.y},
439     {rect.size.width, rect.size.height}
440     };
441    
442     CGContextSetShouldAntialias(cgContext, NO); // Seems to have no effect?
443    
444     CGContextDrawImage(cgContext, cgRect, bitmap);
445     }
446     #endif
447    
448 nigel 1.3 @end