mirror of
https://github.com/kanjitalk755/macemu.git
synced 2025-03-08 08:30:34 +00:00
Now supports all bit depth when in windowed mode
(but only when using CGIMAGEREF drawing strategy)
This commit is contained in:
parent
dea9029450
commit
3fe9f5701e
@ -4,7 +4,7 @@
|
|||||||
* video_macosx.mm - Interface between Basilisk II and Cocoa windowing.
|
* video_macosx.mm - Interface between Basilisk II and Cocoa windowing.
|
||||||
* Based on video_amiga.cpp and video_x.cpp
|
* Based on video_amiga.cpp and video_x.cpp
|
||||||
*
|
*
|
||||||
* Basilisk II (C) 1997-2002 Christian Bauer
|
* Basilisk II (C) 1997-2003 Christian Bauer
|
||||||
*
|
*
|
||||||
* This program is free software; you can redistribute it and/or modify
|
* This program is free software; you can redistribute it and/or modify
|
||||||
* it under the terms of the GNU General Public License as published by
|
* it under the terms of the GNU General Public License as published by
|
||||||
@ -366,7 +366,11 @@ class OSX_monitor : public monitor_desc
|
|||||||
|
|
||||||
|
|
||||||
#ifdef CGIMAGEREF
|
#ifdef CGIMAGEREF
|
||||||
|
CGColorSpaceRef colourSpace;
|
||||||
|
uint8 *colourTable;
|
||||||
CGImageRef imageRef;
|
CGImageRef imageRef;
|
||||||
|
CGDataProviderRef provider;
|
||||||
|
short x, y, bpp, depth, bpr;
|
||||||
#endif
|
#endif
|
||||||
#ifdef NSBITMAP
|
#ifdef NSBITMAP
|
||||||
NSBitmapImageRep *bitmap;
|
NSBitmapImageRep *bitmap;
|
||||||
@ -388,7 +392,10 @@ OSX_monitor :: OSX_monitor (const vector<video_mode> &available_modes,
|
|||||||
: monitor_desc (available_modes, default_depth, default_id)
|
: monitor_desc (available_modes, default_depth, default_id)
|
||||||
{
|
{
|
||||||
#ifdef CGIMAGEREF
|
#ifdef CGIMAGEREF
|
||||||
|
colourSpace = nil;
|
||||||
|
colourTable = (uint8 *) malloc(256 * 3);
|
||||||
imageRef = nil;
|
imageRef = nil;
|
||||||
|
provider = nil;
|
||||||
#endif
|
#endif
|
||||||
#ifdef NSBITMAP
|
#ifdef NSBITMAP
|
||||||
bitmap = nil;
|
bitmap = nil;
|
||||||
@ -398,6 +405,11 @@ OSX_monitor :: OSX_monitor (const vector<video_mode> &available_modes,
|
|||||||
theDisplay = nil;
|
theDisplay = nil;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// Should also have a destructor which does
|
||||||
|
//#ifdef CGIMAGEREF
|
||||||
|
// free(colourTable);
|
||||||
|
//#endif
|
||||||
|
|
||||||
|
|
||||||
// Set Mac frame layout and base address (uses the_buffer/MacFrameBaseMac)
|
// Set Mac frame layout and base address (uses the_buffer/MacFrameBaseMac)
|
||||||
void
|
void
|
||||||
@ -456,13 +468,6 @@ void resizeWinTo(const uint16 newWidth, const uint16 newHeight)
|
|||||||
bool
|
bool
|
||||||
OSX_monitor::init_window(const video_mode &mode)
|
OSX_monitor::init_window(const video_mode &mode)
|
||||||
{
|
{
|
||||||
#ifdef CGIMAGEREF
|
|
||||||
CGColorSpaceRef colourSpace;
|
|
||||||
CGDataProviderRef provider;
|
|
||||||
#endif
|
|
||||||
short bitsPer, samplesPer; // How big is each Pixel?
|
|
||||||
int the_buffer_size;
|
|
||||||
|
|
||||||
D(bug("init_window: depth=%d(%d bits)\n",
|
D(bug("init_window: depth=%d(%d bits)\n",
|
||||||
mode.depth, bits_from_depth(mode.depth) ));
|
mode.depth, bits_from_depth(mode.depth) ));
|
||||||
|
|
||||||
@ -471,7 +476,7 @@ OSX_monitor::init_window(const video_mode &mode)
|
|||||||
ADBSetRelMouseMode(false);
|
ADBSetRelMouseMode(false);
|
||||||
|
|
||||||
|
|
||||||
// Open window
|
// Is the window open?
|
||||||
if ( ! the_win )
|
if ( ! the_win )
|
||||||
{
|
{
|
||||||
ErrorAlert(STR_OPEN_WINDOW_ERR);
|
ErrorAlert(STR_OPEN_WINDOW_ERR);
|
||||||
@ -481,7 +486,8 @@ OSX_monitor::init_window(const video_mode &mode)
|
|||||||
|
|
||||||
|
|
||||||
// Create frame buffer ("height + 2" for safety)
|
// Create frame buffer ("height + 2" for safety)
|
||||||
the_buffer_size = mode.bytes_per_row * (mode.y + 2);
|
int the_buffer_size = mode.bytes_per_row * (mode.y + 2);
|
||||||
|
|
||||||
the_buffer = calloc(the_buffer_size, 1);
|
the_buffer = calloc(the_buffer_size, 1);
|
||||||
if ( ! the_buffer )
|
if ( ! the_buffer )
|
||||||
{
|
{
|
||||||
@ -492,23 +498,31 @@ OSX_monitor::init_window(const video_mode &mode)
|
|||||||
D(bug("the_buffer = %p\n", the_buffer));
|
D(bug("the_buffer = %p\n", the_buffer));
|
||||||
|
|
||||||
|
|
||||||
if ( mode.depth == VDEPTH_1BIT )
|
unsigned char *offsetBuffer = (unsigned char *) the_buffer;
|
||||||
bitsPer = 1;
|
offsetBuffer += 1; // OS X NSBitmaps are RGBA, but Basilisk generates ARGB
|
||||||
else
|
|
||||||
bitsPer = 8;
|
|
||||||
|
|
||||||
if ( mode.depth == VDEPTH_32BIT )
|
|
||||||
samplesPer = 3;
|
|
||||||
else
|
|
||||||
samplesPer = 1;
|
|
||||||
|
|
||||||
#ifdef CGIMAGEREF
|
#ifdef CGIMAGEREF
|
||||||
switch ( mode.depth )
|
switch ( mode.depth )
|
||||||
{
|
{
|
||||||
//case VDEPTH_1BIT: colourSpace = CGColorSpaceCreateDeviceMono(); break
|
case VDEPTH_1BIT: bpp = 1; break;
|
||||||
case VDEPTH_8BIT: colourSpace = CGColorSpaceCreateDeviceGray(); break;
|
case VDEPTH_2BIT: bpp = 2; break;
|
||||||
case VDEPTH_32BIT: colourSpace = CGColorSpaceCreateDeviceRGB(); break;
|
case VDEPTH_4BIT: bpp = 4; break;
|
||||||
default: colourSpace = NULL;
|
case VDEPTH_8BIT: bpp = 8; break;
|
||||||
|
case VDEPTH_16BIT: bpp = 5; break;
|
||||||
|
case VDEPTH_32BIT: bpp = 8; break;
|
||||||
|
}
|
||||||
|
|
||||||
|
x = mode.x, y = mode.y, depth = bits_from_depth(mode.depth), bpr = mode.bytes_per_row;
|
||||||
|
|
||||||
|
colourSpace = CGColorSpaceCreateDeviceRGB();
|
||||||
|
|
||||||
|
if ( mode.depth < VDEPTH_16BIT )
|
||||||
|
{
|
||||||
|
CGColorSpaceRef oldColourSpace = colourSpace;
|
||||||
|
|
||||||
|
colourSpace = CGColorSpaceCreateIndexed(colourSpace, 255, colourTable);
|
||||||
|
|
||||||
|
CGColorSpaceRelease(oldColourSpace);
|
||||||
}
|
}
|
||||||
|
|
||||||
if ( ! colourSpace )
|
if ( ! colourSpace )
|
||||||
@ -524,12 +538,8 @@ OSX_monitor::init_window(const video_mode &mode)
|
|||||||
ErrorAlert("Could not create CGDataProvider from buffer data");
|
ErrorAlert("Could not create CGDataProvider from buffer data");
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
imageRef = CGImageCreate(mode.x,
|
|
||||||
mode.y,
|
imageRef = CGImageCreate(x, y, bpp, depth, bpr, colourSpace,
|
||||||
bitsPer,
|
|
||||||
bits_from_depth(mode.depth),
|
|
||||||
mode.bytes_per_row,
|
|
||||||
colourSpace,
|
|
||||||
#ifdef CG_USE_ALPHA
|
#ifdef CG_USE_ALPHA
|
||||||
kCGImageAlphaPremultipliedFirst,
|
kCGImageAlphaPremultipliedFirst,
|
||||||
#else
|
#else
|
||||||
@ -544,21 +554,36 @@ OSX_monitor::init_window(const video_mode &mode)
|
|||||||
ErrorAlert("Could not create CGImage from CGDataProvider");
|
ErrorAlert("Could not create CGImage from CGDataProvider");
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
CGDataProviderRelease(provider);
|
|
||||||
CGColorSpaceRelease(colourSpace);
|
|
||||||
|
|
||||||
[output readyToDraw: imageRef
|
[output readyToDraw: imageRef
|
||||||
imageWidth: mode.x
|
bitmap: offsetBuffer
|
||||||
imageHeight: mode.y];
|
imageWidth: x
|
||||||
|
imageHeight: y];
|
||||||
|
|
||||||
|
|
||||||
#ifdef CG_USE_ALPHA
|
#ifdef CG_USE_ALPHA
|
||||||
mask_buffer(the_buffer, mode.x, the_buffer_size);
|
mask_buffer(the_buffer, x, the_buffer_size);
|
||||||
#endif
|
#endif
|
||||||
#else
|
|
||||||
unsigned char *offsetBuffer = (unsigned char *) the_buffer;
|
return true;
|
||||||
offsetBuffer += 1; // OS X NSBitmaps are RGBA, but Basilisk generates ARGB
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
#ifndef CGIMAGEREF
|
||||||
|
short bitsPer, samplesPer; // How big is each Pixel?
|
||||||
|
|
||||||
|
if ( mode.depth == VDEPTH_1BIT )
|
||||||
|
bitsPer = 1;
|
||||||
|
else
|
||||||
|
bitsPer = 8;
|
||||||
|
|
||||||
|
if ( mode.depth == VDEPTH_32BIT )
|
||||||
|
samplesPer = 3;
|
||||||
|
else
|
||||||
|
samplesPer = 1;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
#ifdef NSBITMAP
|
#ifdef NSBITMAP
|
||||||
bitmap = [NSBitmapImageRep alloc];
|
bitmap = [NSBitmapImageRep alloc];
|
||||||
bitmap = [bitmap initWithBitmapDataPlanes: (unsigned char **) &offsetBuffer
|
bitmap = [bitmap initWithBitmapDataPlanes: (unsigned char **) &offsetBuffer
|
||||||
@ -749,8 +774,10 @@ bool VideoInit(bool classic)
|
|||||||
case DISPLAY_OPENGL:
|
case DISPLAY_OPENGL:
|
||||||
// Same as window depths and sizes?
|
// Same as window depths and sizes?
|
||||||
case DISPLAY_WINDOW:
|
case DISPLAY_WINDOW:
|
||||||
#ifdef MAC_OS_X_VERSION_SUPPORTS_LOWER_DEPTHS
|
#ifdef CGIMAGEREF
|
||||||
add_standard_modes(VDEPTH_1BIT);
|
add_standard_modes(VDEPTH_1BIT);
|
||||||
|
add_standard_modes(VDEPTH_2BIT);
|
||||||
|
add_standard_modes(VDEPTH_4BIT);
|
||||||
add_standard_modes(VDEPTH_8BIT);
|
add_standard_modes(VDEPTH_8BIT);
|
||||||
add_standard_modes(VDEPTH_16BIT);
|
add_standard_modes(VDEPTH_16BIT);
|
||||||
#endif
|
#endif
|
||||||
@ -828,6 +855,8 @@ OSX_monitor::video_close()
|
|||||||
// Free frame buffer stuff
|
// Free frame buffer stuff
|
||||||
#ifdef CGIMAGEREF
|
#ifdef CGIMAGEREF
|
||||||
CGImageRelease(imageRef);
|
CGImageRelease(imageRef);
|
||||||
|
CGColorSpaceRelease(colourSpace);
|
||||||
|
CGDataProviderRelease(provider);
|
||||||
#endif
|
#endif
|
||||||
#ifdef NSBITMAP
|
#ifdef NSBITMAP
|
||||||
[bitmap release];
|
[bitmap release];
|
||||||
@ -890,6 +919,60 @@ OSX_monitor::set_palette(uint8 *pal, int num)
|
|||||||
NSLog(@"Failed to set palette, error = %d", err);
|
NSLog(@"Failed to set palette, error = %d", err);
|
||||||
CGPaletteRelease(CGpal);
|
CGPaletteRelease(CGpal);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifdef CGIMAGEREF
|
||||||
|
if ( display_type != DISPLAY_WINDOW )
|
||||||
|
return;
|
||||||
|
|
||||||
|
// To change the palette, we have to regenerate
|
||||||
|
// the CGImageRef with the new colour space.
|
||||||
|
|
||||||
|
CGImageRef oldImageRef = imageRef;
|
||||||
|
CGColorSpaceRef oldColourSpace = colourSpace;
|
||||||
|
|
||||||
|
colourSpace = CGColorSpaceCreateDeviceRGB();
|
||||||
|
|
||||||
|
if ( depth < 16 )
|
||||||
|
{
|
||||||
|
CGColorSpaceRef tempColourSpace = colourSpace;
|
||||||
|
|
||||||
|
colourSpace = CGColorSpaceCreateIndexed(colourSpace, 255, pal);
|
||||||
|
CGColorSpaceRelease(tempColourSpace);
|
||||||
|
}
|
||||||
|
|
||||||
|
if ( ! colourSpace )
|
||||||
|
{
|
||||||
|
ErrorAlert("No valid colour space");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
imageRef = CGImageCreate(x, y, bpp, depth, bpr, colourSpace,
|
||||||
|
#ifdef CG_USE_ALPHA
|
||||||
|
kCGImageAlphaPremultipliedFirst,
|
||||||
|
#else
|
||||||
|
kCGImageAlphaNoneSkipFirst,
|
||||||
|
#endif
|
||||||
|
provider,
|
||||||
|
NULL, // colourMap translation table
|
||||||
|
NO, // shouldInterpolate colours?
|
||||||
|
kCGRenderingIntentDefault);
|
||||||
|
if ( ! imageRef )
|
||||||
|
{
|
||||||
|
ErrorAlert("Could not create CGImage from CGDataProvider");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
unsigned char *offsetBuffer = (unsigned char *) the_buffer;
|
||||||
|
offsetBuffer += 1; // OS X NSBitmaps are RGBA, but Basilisk generates ARGB
|
||||||
|
|
||||||
|
[output readyToDraw: imageRef
|
||||||
|
bitmap: offsetBuffer
|
||||||
|
imageWidth: x
|
||||||
|
imageHeight: y];
|
||||||
|
|
||||||
|
CGColorSpaceRelease(oldColourSpace);
|
||||||
|
CGImageRelease(oldImageRef);
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user