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

Comparing BasiliskII/src/MacOSX/video_macosx.mm (file contents):
Revision 1.6 by nigel, 2002-12-19T10:40:40Z vs.
Revision 1.15 by gbeauche, 2005-01-30T21:42:13Z

# Line 4 | Line 4
4   *  video_macosx.mm - Interface between Basilisk II and Cocoa windowing.
5   *                    Based on video_amiga.cpp and video_x.cpp
6   *
7 < *  Basilisk II (C) 1997-2002 Christian Bauer
7 > *  Basilisk II (C) 1997-2005 Christian Bauer
8   *
9   *  This program is free software; you can redistribute it and/or modify
10   *  it under the terms of the GNU General Public License as published by
# Line 101 | Line 101 | colours_from_depth(const uint16 depth)
101   bool
102   parse_screen_prefs(const char *mode_str)
103   {
104 +        if ( ! mode_str )
105 +        {
106 +                // No screen pref was found. Supply a default:
107 +                mode_str = "win/512/384";
108 +        }
109 +
110          if (sscanf(mode_str, "win/%hd/%hd/%hd",
111                                  &init_width, &init_height, &init_depth) == 3)
112                  display_type = DISPLAY_WINDOW;
# Line 268 | Line 274 | static bool add_CGDirectDisplay_modes()
274   #ifdef MAC_OS_X_VERSION_10_2
275                                  int32   bytes  = getCFint32(modeSpec, kCGDisplayBytesPerRow);
276   #else
277 <                                int32   bytes = 0;
277 >                                int32   bytes  = 0;
278   #endif
279                                  video_depth     depth = DepthModeForPixelDepth(bpp);
280  
# Line 366 | Line 372 | class OSX_monitor : public monitor_desc
372  
373  
374   #ifdef CGIMAGEREF
375 +                CGColorSpaceRef         colourSpace;
376 +                uint8                           *colourTable;
377                  CGImageRef                      imageRef;
378 +                CGDataProviderRef       provider;
379 +                short                           x, y, bpp, depth, bpr;
380   #endif
381   #ifdef NSBITMAP
382                  NSBitmapImageRep        *bitmap;
# Line 388 | Line 398 | OSX_monitor :: OSX_monitor (const      vector
398                          : monitor_desc (available_modes, default_depth, default_id)
399   {
400   #ifdef CGIMAGEREF
401 +        colourSpace = nil;
402 +        colourTable = (uint8 *) malloc(256 * 3);
403          imageRef = nil;
404 +        provider = nil;
405   #endif
406   #ifdef NSBITMAP
407          bitmap = nil;
# Line 398 | Line 411 | OSX_monitor :: OSX_monitor (const      vector
411          theDisplay = nil;
412   };
413  
414 + // Should also have a destructor which does
415 + //#ifdef CGIMAGEREF
416 + //      free(colourTable);
417 + //#endif
418 +
419  
420   // Set Mac frame layout and base address (uses the_buffer/MacFrameBaseMac)
421   void
# Line 437 | Line 455 | resizeWinBy(const short deltaX, const sh
455  
456          D(bug(", new x=%g, y=%g\n", rect.size.width, rect.size.height));
457  
458 <        [the_win setFrame: rect display: YES];
458 >        [the_win setFrame: rect display: YES animate: YES];
459 >        [the_win center];
460          rect = [the_win frame];
461   }
462  
# Line 456 | Line 475 | void resizeWinTo(const uint16 newWidth,
475   bool
476   OSX_monitor::init_window(const video_mode &mode)
477   {
459 #ifdef CGIMAGEREF
460        CGColorSpaceRef         colourSpace;
461        CGDataProviderRef       provider;
462 #endif
463        short                           bitsPer, samplesPer;    // How big is each Pixel?
464        int                                     the_buffer_size;
465
478          D(bug("init_window: depth=%d(%d bits)\n",
479                          mode.depth, bits_from_depth(mode.depth) ));
480  
# Line 471 | Line 483 | OSX_monitor::init_window(const video_mod
483          ADBSetRelMouseMode(false);
484  
485  
486 <        // Open window
486 >        // Is the window open?
487          if ( ! the_win )
488          {
489                  ErrorAlert(STR_OPEN_WINDOW_ERR);
# Line 481 | Line 493 | OSX_monitor::init_window(const video_mod
493  
494  
495          // Create frame buffer ("height + 2" for safety)
496 <        the_buffer_size = mode.bytes_per_row * (mode.y + 2);
496 >        int the_buffer_size = mode.bytes_per_row * (mode.y + 2);
497 >
498          the_buffer = calloc(the_buffer_size, 1);
499          if ( ! the_buffer )
500          {
# Line 492 | Line 505 | OSX_monitor::init_window(const video_mod
505          D(bug("the_buffer = %p\n", the_buffer));
506  
507  
508 <        if ( mode.depth == VDEPTH_1BIT )
509 <                bitsPer = 1;
497 <        else
498 <                bitsPer = 8;
499 <
500 <        if ( mode.depth == VDEPTH_32BIT )
501 <                samplesPer = 3;
502 <        else
503 <                samplesPer = 1;
508 >        unsigned char *offsetBuffer = (unsigned char *) the_buffer;
509 >        offsetBuffer += 1;              // OS X NSBitmaps are RGBA, but Basilisk generates ARGB
510  
511   #ifdef CGIMAGEREF
512          switch ( mode.depth )
513          {
514 <                //case VDEPTH_1BIT:     colourSpace = CGColorSpaceCreateDeviceMono(); break
515 <                case VDEPTH_8BIT:       colourSpace = CGColorSpaceCreateDeviceGray(); break;
516 <                case VDEPTH_32BIT:      colourSpace = CGColorSpaceCreateDeviceRGB();  break;
517 <                default:                        colourSpace = NULL;
514 >                case VDEPTH_1BIT:       bpp = 1; break;
515 >                case VDEPTH_2BIT:       bpp = 2; break;
516 >                case VDEPTH_4BIT:       bpp = 4; break;
517 >                case VDEPTH_8BIT:       bpp = 8; break;
518 >                case VDEPTH_16BIT:      bpp = 5; break;
519 >                case VDEPTH_32BIT:      bpp = 8; break;
520 >        }
521 >
522 >        x = mode.x, y = mode.y, depth = bits_from_depth(mode.depth), bpr = mode.bytes_per_row;
523 >
524 >        colourSpace = CGColorSpaceCreateDeviceRGB();
525 >
526 >        if ( mode.depth < VDEPTH_16BIT )
527 >        {
528 >                CGColorSpaceRef oldColourSpace = colourSpace;
529 >
530 >                colourSpace = CGColorSpaceCreateIndexed(colourSpace, 255, colourTable);
531 >
532 >                CGColorSpaceRelease(oldColourSpace);
533          }
534  
535          if ( ! colourSpace )
# Line 524 | Line 545 | OSX_monitor::init_window(const video_mod
545                  ErrorAlert("Could not create CGDataProvider from buffer data");
546                  return false;
547          }
548 <        imageRef = CGImageCreate(mode.x,
549 <                                                         mode.y,
529 <                                                         bitsPer,
530 <                                                         bits_from_depth(mode.depth),
531 <                                                         mode.bytes_per_row,
532 <                                                         colourSpace,
548 >
549 >        imageRef = CGImageCreate(x, y, bpp, depth, bpr, colourSpace,
550    #ifdef CG_USE_ALPHA
551                                                           kCGImageAlphaPremultipliedFirst,
552    #else
# Line 544 | Line 561 | OSX_monitor::init_window(const video_mod
561                  ErrorAlert("Could not create CGImage from CGDataProvider");
562                  return false;
563          }
547        CGDataProviderRelease(provider);
548        CGColorSpaceRelease(colourSpace);
564  
565          [output readyToDraw: imageRef
566 <                         imageWidth: mode.x
567 <                        imageHeight: mode.y];
566 >                                 bitmap: offsetBuffer
567 >                         imageWidth: x
568 >                        imageHeight: y];
569 >
570  
571    #ifdef CG_USE_ALPHA
572 <        mask_buffer(the_buffer, mode.x, the_buffer_size);
572 >        mask_buffer(the_buffer, x, the_buffer_size);
573 >
574 > /* Create an image mask with this call? */
575 > //CG_EXTERN CGImageRef
576 > //CGImageMaskCreate(size_t width, size_t height, size_t bitsPerComponent,
577 > //                                      size_t bitsPerPixel, size_t bytesPerRow,
578 > //                                      CGDataProviderRef provider, const float decode[], bool shouldInterpolate);
579    #endif
580 < #else
581 <        unsigned char *offsetBuffer = (unsigned char *) the_buffer;
582 <        offsetBuffer += 1;      // OS X NSBitmaps are RGBA, but Basilisk generates ARGB
580 >
581 >        return true;
582 > #endif
583 >
584 >
585 > #ifndef CGIMAGEREF
586 >        short   bitsPer, samplesPer;    // How big is each Pixel?
587 >
588 >        if ( mode.depth == VDEPTH_1BIT )
589 >                bitsPer = 1;
590 >        else
591 >                bitsPer = 8;
592 >
593 >        if ( mode.depth == VDEPTH_32BIT )
594 >                samplesPer = 3;
595 >        else
596 >                samplesPer = 1;
597   #endif
598  
599 +
600   #ifdef NSBITMAP
601          bitmap = [NSBitmapImageRep alloc];
602          bitmap = [bitmap initWithBitmapDataPlanes: (unsigned char **) &offsetBuffer
# Line 649 | Line 687 | OSX_monitor::init_screen(video_mode &mod
687                  return false;
688          }
689  
652        // For mouse event processing: update screen height
653        [output startedFullScreen: theDisplay];
654
690          the_buffer = CGDisplayBaseAddress(theDisplay);
691          if ( ! the_buffer )
692          {
# Line 662 | Line 697 | OSX_monitor::init_screen(video_mode &mod
697                  return false;
698          }
699  
665        D(NSLog(@"Starting full screen mode, height = %d",
666                                                CGDisplayPixelsHigh(theDisplay)));
667
668        [output startedFullScreen: theDisplay];         // For mouse event processing
669
700          if ( mode.bytes_per_row != CGDisplayBytesPerRow(theDisplay) )
701          {
702                  D(bug("Bytes per row (%d) doesn't match current (%ld)\n",
# Line 680 | Line 710 | OSX_monitor::init_screen(video_mode &mod
710          {
711                  CGDisplayHideCursor(theDisplay);
712  
713 <                // Send real mouse to emulated location
684 <                if ( CGDisplayMoveCursorToPoint(theDisplay, CGPointMake(15,15))
685 <                                                                                                                != CGDisplayNoErr )
686 <                {
687 <                        video_close();
688 <                        ErrorSheet(@"Could move (jump) cursor on screen", the_win);
689 <                        return false;
690 <                }
713 >                [output startedFullScreen: theDisplay];
714  
715                  // Send emulated mouse to current location
716 < //              [output performSelector: @selector(processMouseMove:)
694 < //                                       withObject: nil
695 < //                                       afterDelay: 7.0];
696 < //              NNTimer *moveMouse = [[NNTimer new] retain];
697 < //              [moveMouse perform: @selector(processMouseMove:)
698 < //                                              of: output
699 < //                                       after: 3
700 < //                                       units: NNseconds];
716 >                [output fullscreenMouseMove];
717          }
718          else
719          {
# Line 771 | Line 787 | bool VideoInit(bool classic)
787                          case DISPLAY_OPENGL:
788                                  // Same as window depths and sizes?
789                          case DISPLAY_WINDOW:
790 <                                //add_standard_modes(VDEPTH_1BIT);
791 <                                //add_standard_modes(VDEPTH_8BIT);
792 <                                //add_standard_modes(VDEPTH_16BIT);
790 > #ifdef CGIMAGEREF
791 >                                add_standard_modes(VDEPTH_1BIT);
792 >                                add_standard_modes(VDEPTH_2BIT);
793 >                                add_standard_modes(VDEPTH_4BIT);
794 >                                add_standard_modes(VDEPTH_8BIT);
795 >                                add_standard_modes(VDEPTH_16BIT);
796 > #endif
797                                  add_standard_modes(VDEPTH_32BIT);
798                                  break;
799                  }
# Line 848 | Line 868 | OSX_monitor::video_close()
868                          // Free frame buffer stuff
869   #ifdef CGIMAGEREF
870                          CGImageRelease(imageRef);
871 +                        CGColorSpaceRelease(colourSpace);
872 +                        CGDataProviderRelease(provider);
873   #endif
874   #ifdef NSBITMAP
875                          [bitmap release];
# Line 887 | Line 909 | void VideoExit(void)
909  
910          for (i = VideoMonitors.begin(); i != end; ++i)
911                  dynamic_cast<OSX_monitor *>(*i)->video_close();
912 +
913 +        VideoMonitors.clear();
914 +        VideoModes.clear();
915   }
916  
917  
# Line 910 | Line 935 | OSX_monitor::set_palette(uint8 *pal, int
935                          NSLog(@"Failed to set palette, error = %d", err);
936                  CGPaletteRelease(CGpal);
937          }
938 +
939 + #ifdef CGIMAGEREF
940 +        if ( display_type != DISPLAY_WINDOW )
941 +                return;
942 +
943 +        // To change the palette, we have to regenerate
944 +        // the CGImageRef with the new colour space.
945 +
946 +        CGImageRef                      oldImageRef = imageRef;
947 +        CGColorSpaceRef         oldColourSpace = colourSpace;
948 +
949 +        colourSpace = CGColorSpaceCreateDeviceRGB();
950 +
951 +        if ( depth < 16 )
952 +        {
953 +                CGColorSpaceRef         tempColourSpace = colourSpace;
954 +
955 +                colourSpace = CGColorSpaceCreateIndexed(colourSpace, 255, pal);
956 +                CGColorSpaceRelease(tempColourSpace);
957 +        }
958 +
959 +        if ( ! colourSpace )
960 +        {
961 +                ErrorAlert("No valid colour space");
962 +                return;
963 +        }
964 +
965 +        imageRef = CGImageCreate(x, y, bpp, depth, bpr, colourSpace,
966 +  #ifdef CG_USE_ALPHA
967 +                                                         kCGImageAlphaPremultipliedFirst,
968 +  #else
969 +                                                         kCGImageAlphaNoneSkipFirst,
970 +  #endif
971 +                                                         provider,
972 +                                                         NULL,  // colourMap translation table
973 +                                                         NO,    // shouldInterpolate colours?
974 +                                                         kCGRenderingIntentDefault);
975 +        if ( ! imageRef )
976 +        {
977 +                ErrorAlert("Could not create CGImage from CGDataProvider");
978 +                return;
979 +        }
980 +
981 +        unsigned char *offsetBuffer = (unsigned char *) the_buffer;
982 +        offsetBuffer += 1;              // OS X NSBitmaps are RGBA, but Basilisk generates ARGB
983 +
984 +        [output readyToDraw: imageRef
985 +                                 bitmap: offsetBuffer
986 +                         imageWidth: x
987 +                        imageHeight: y];
988 +
989 +        CGColorSpaceRelease(oldColourSpace);
990 +        CGImageRelease(oldImageRef);
991 + #endif
992   }
993  
994  
# Line 955 | Line 1034 | OSX_monitor::switch_to_current_mode(void
1034                  if ( ! failure &&
1035                           ! ( the_buffer = CGDisplayBaseAddress(theDisplay) ) )
1036                          failure = "Could not get base address of screen";
1037 +
1038 +        }
1039 + #ifdef CGIMAGEREF
1040 +        // Clean up the old CGImageRef stuff
1041 +        else if ( display_type == DISPLAY_WINDOW && imageRef )
1042 +        {
1043 +                CGImageRef                      oldImageRef             = imageRef;
1044 +                CGColorSpaceRef         oldColourSpace  = colourSpace;
1045 +                CGDataProviderRef       oldProvider             = provider;
1046 +                void                            *oldBuffer              = the_buffer;
1047 +
1048 +                if ( video_open(mode) )
1049 +                {
1050 +                        CGImageRelease(oldImageRef);
1051 +                        CGColorSpaceRelease(oldColourSpace);
1052 +                        CGDataProviderRelease(oldProvider);
1053 +                        free(oldBuffer);
1054 +                }
1055                  else
1056 <                        // Send emulated mouse to current location
960 <                        [output processMouseMove: nil];
1056 >                        failure = "Could not video_open() requested mode";
1057          }
1058 + #endif
1059          else if ( ! video_open(mode) )
1060                  failure = "Could not video_open() requested mode";
1061  
1062 +        if ( ! failure && display_type == DISPLAY_SCREEN )
1063 +        {
1064 +                // Whenever we change screen resolution, the MacOS mouse starts
1065 +                // up in the top left corner. Send real mouse to that location
1066 + //              if ( CGDisplayMoveCursorToPoint(theDisplay, CGPointMake(15,15))
1067 + //                                                                                                              == CGDisplayNoErr )
1068 + //              {
1069 +                        //
1070 +                        [output fullscreenMouseMove];
1071 + //              }
1072 + //              else
1073 + //                      failure = "Could move (jump) cursor on screen";
1074 +        }
1075 +
1076          if ( failure )
1077          {
1078                  NSLog(@"In switch_to_current_mode():");
# Line 1000 | Line 1111 | void VideoInterrupt(void)
1111   void VideoRefresh(void)
1112   {
1113   }
1114 +
1115 +
1116 +
1117 + // Deal with a memory access signal referring to the screen.
1118 + // For now, just ignore
1119 + bool Screen_fault_handler(char *a, char *b)
1120 + {
1121 + //      NSLog(@"Got a screen fault %lx %lx", a, b);
1122 + //      [output setNeedsDisplay: YES];
1123 +        return YES;
1124 + }

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines