git.y1.nz

SameBoy

Accurate GB/GBC emulator
download: https://git.y1.nz/archives/sameboy.tar.gz
README | Files | Log | Refs | LICENSE

QuickLook/generator.m

      1 #include <QuickLook/QuickLook.h>
      2 #include <Cocoa/Cocoa.h>
      3 #include "get_image_for_rom.h"
      4 
      5 OSStatus GBQuickLookRender(CGContextRef cgContext, CFURLRef url, bool showBorder)
      6 {
      7     /* Load the template NSImages when generating the first thumbnail */
      8     static NSImage *template = nil;
      9     static NSImage *templateUniversal = nil;
     10     static NSImage *templateColor = nil;
     11     static NSBundle *bundle = nil;
     12     static dispatch_once_t onceToken;
     13     dispatch_once(&onceToken, ^{
     14         bundle = [NSBundle bundleForClass:NSClassFromString(@"GBPanel")];
     15     });
     16     if (showBorder) {
     17         static dispatch_once_t onceToken;
     18         dispatch_once(&onceToken, ^{
     19             template = [[NSImage alloc] initWithContentsOfFile:[bundle pathForResource:@"CartridgeTemplate" ofType:@"png"]];
     20             templateUniversal = [[NSImage alloc] initWithContentsOfFile:[bundle pathForResource:@"UniversalCartridgeTemplate" ofType:@"png"]];
     21             templateColor = [[NSImage alloc] initWithContentsOfFile:[bundle pathForResource:@"ColorCartridgeTemplate" ofType:@"png"]];
     22         });
     23     }
     24     uint32_t bitmap[160*144];
     25     uint8_t cgbFlag = 0;
     26     
     27     /* The cgb_boot_fast boot ROM skips the boot animation */
     28     if (get_image_for_rom([[(__bridge NSURL *)url path] UTF8String],
     29                           [[bundle pathForResource:@"cgb_boot_fast" ofType:@"bin"] UTF8String],
     30                           bitmap, &cgbFlag)) {
     31         return -1;
     32     }
     33     
     34     /* Convert the screenshot to a CGImageRef */
     35     CGDataProviderRef provider = CGDataProviderCreateWithData(NULL, bitmap, sizeof(bitmap), NULL);
     36     CGColorSpaceRef colorSpaceRef = CGColorSpaceCreateDeviceRGB();
     37     CGBitmapInfo bitmapInfo = kCGBitmapByteOrderDefault | kCGImageAlphaNoneSkipLast;
     38     CGColorRenderingIntent renderingIntent = kCGRenderingIntentDefault;
     39     
     40     CGImageRef iref = CGImageCreate(160,
     41                                     144,
     42                                     8,
     43                                     32,
     44                                     4 * 160,
     45                                     colorSpaceRef,
     46                                     bitmapInfo,
     47                                     provider,
     48                                     NULL,
     49                                     true,
     50                                     renderingIntent);
     51     CGContextSetInterpolationQuality(cgContext, kCGInterpolationNone);
     52     NSGraphicsContext *context = [NSGraphicsContext graphicsContextWithGraphicsPort:(void *)cgContext flipped:false];
     53     [NSGraphicsContext setCurrentContext:context];
     54     
     55     
     56     double ratio = CGBitmapContextGetWidth(cgContext) / 1024.0;
     57     
     58     /* Convert the screenshot to a magnified NSImage */
     59     NSImage *screenshot = [[NSImage alloc] initWithCGImage:iref size:NSMakeSize(160, 144)];
     60     /* Draw the screenshot */
     61     if (showBorder) {
     62         [screenshot drawInRect:NSMakeRect(192 * ratio, 150 * ratio, 640 * ratio, 576 * ratio)];
     63     }
     64     else {
     65         [screenshot drawInRect:NSMakeRect(0, 0, 640, 576)];
     66     }
     67     
     68     if (showBorder) {
     69         /* Use the CGB flag to determine the cartridge "look":
     70          - DMG cartridges are grey
     71          - CGB cartridges are transparent
     72          - CGB cartridges that support DMG systems are black
     73          */
     74         NSImage *effectiveTemplate = nil;
     75         switch (cgbFlag) {
     76             case 0xC0:
     77                 effectiveTemplate = templateColor;
     78                 break;
     79             case 0x80:
     80                 effectiveTemplate = templateUniversal;
     81                 break;
     82             default:
     83                 effectiveTemplate = template;
     84         }
     85         
     86         CGContextSetInterpolationQuality(cgContext, kCGInterpolationMedium);
     87         /* Mask it with the template (The middle part of the template image is transparent) */
     88         [effectiveTemplate drawInRect:(NSRect){{0, 0}, {CGBitmapContextGetWidth(cgContext), CGBitmapContextGetHeight(cgContext)}}];
     89     }
     90     
     91     CGColorSpaceRelease(colorSpaceRef);
     92     CGDataProviderRelease(provider);
     93     CGImageRelease(iref);
     94     
     95     return noErr;
     96 }
     97 
     98 OSStatus GeneratePreviewForURL(void *thisInterface, QLPreviewRequestRef preview, CFURLRef url, CFStringRef contentTypeUTI, CFDictionaryRef options)
     99 {
    100     @autoreleasepool {
    101         CGContextRef cgContext = QLPreviewRequestCreateContext(preview, ((NSSize){640, 576}), true, nil);
    102         if (GBQuickLookRender(cgContext, url, false) == noErr) {
    103             QLPreviewRequestFlushContext(preview, cgContext);
    104             CGContextRelease(cgContext);
    105             return noErr;
    106         }
    107         CGContextRelease(cgContext);
    108         return -1;
    109     }
    110 }
    111 
    112 OSStatus GenerateThumbnailForURL(void *thisInterface, QLThumbnailRequestRef thumbnail, CFURLRef url, CFStringRef contentTypeUTI, CFDictionaryRef options, CGSize maxSize)
    113 {
    114     extern NSString *kQLThumbnailPropertyIconFlavorKey;
    115     @autoreleasepool {
    116         CGContextRef cgContext = QLThumbnailRequestCreateContext(thumbnail, ((NSSize){1024, 1024}), true, (__bridge CFDictionaryRef)(@{kQLThumbnailPropertyIconFlavorKey : @(0)}));
    117         if (GBQuickLookRender(cgContext, url, true) == noErr) {
    118             QLThumbnailRequestFlushContext(thumbnail, cgContext);
    119             CGContextRelease(cgContext);
    120             return noErr;
    121         }
    122         CGContextRelease(cgContext);
    123         return -1;
    124     }
    125 }

This webpage is intended to be an accessible preview of this repository. To get a fuller picture, clone it and use the git CLI.