Merge pull request #48 from rakslice/gamma

Hook up Mac OS gamma settings in SS and with SDL1/SDL2
This commit is contained in:
kanjitalk755 2020-08-19 19:18:47 +09:00 committed by GitHub
commit 565c133662
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 140 additions and 5 deletions

View File

@ -155,6 +155,11 @@ static SDL_mutex *frame_buffer_lock = NULL;
#define LOCK_FRAME_BUFFER SDL_LockMutex(frame_buffer_lock)
#define UNLOCK_FRAME_BUFFER SDL_UnlockMutex(frame_buffer_lock)
// Previously set gamma tables
static uint16 last_gamma_red[256];
static uint16 last_gamma_green[256];
static uint16 last_gamma_blue[256];
// Video refresh function
static void VideoRefreshInit(void);
static void (*video_refresh)(void);
@ -1363,9 +1368,51 @@ void SDL_monitor_desc::set_palette(uint8 *pal, int num_in)
{
const VIDEO_MODE &mode = get_current_mode();
// FIXME: how can we handle the gamma ramp?
if ((int)VIDEO_MODE_DEPTH > VIDEO_DEPTH_8BIT)
if ((int)VIDEO_MODE_DEPTH > VIDEO_DEPTH_8BIT) {
// handle the gamma ramp
if (pal[0] == 127 && pal[num_in*3-1] == 127) // solid grey
return; // ignore
uint16 red[256];
uint16 green[256];
uint16 blue[256];
int repeats = 256 / num_in;
for (int i = 0; i < num_in; i++) {
for (int j = 0; j < repeats; j++) {
red[i*repeats + j] = pal[i*3 + 0] << 8;
green[i*repeats + j] = pal[i*3 + 1] << 8;
blue[i*repeats + j] = pal[i*3 + 2] << 8;
}
}
// fill remaining entries (if any) with last value
for (int i = num_in * repeats; i < 256; i++) {
red[i] = pal[(num_in - 1) * 3] << 8;
green[i] = pal[(num_in - 1) * 3 + 1] << 8;
blue[i] = pal[(num_in - 1) * 3 + 2] << 8;
}
bool changed = (memcmp(red, last_gamma_red, 512) != 0 ||
memcmp(green, last_gamma_green, 512) != 0 ||
memcmp(blue, last_gamma_blue, 512) != 0);
if (changed) {
int result = SDL_SetGammaRamp(red, green, blue);
if (result < 0) {
fprintf(stderr, "SDL_SetGammaRamp returned %d, SDL error: %s\n", result, SDL_GetError());
}
memcpy(last_gamma_red, red, 512);
memcpy(last_gamma_green, green, 512);
memcpy(last_gamma_blue, blue, 512);
}
return;
}
LOCK_PALETTE;

View File

@ -168,6 +168,11 @@ static SDL_mutex *frame_buffer_lock = NULL;
#define LOCK_FRAME_BUFFER SDL_LockMutex(frame_buffer_lock)
#define UNLOCK_FRAME_BUFFER SDL_UnlockMutex(frame_buffer_lock)
// Previously set gamma tables
static uint16 last_gamma_red[256];
static uint16 last_gamma_green[256];
static uint16 last_gamma_blue[256];
// Video refresh function
static void VideoRefreshInit(void);
static void (*video_refresh)(void);
@ -1751,9 +1756,51 @@ void SDL_monitor_desc::set_palette(uint8 *pal, int num_in)
{
const VIDEO_MODE &mode = get_current_mode();
// FIXME: how can we handle the gamma ramp?
if ((int)VIDEO_MODE_DEPTH > VIDEO_DEPTH_8BIT)
if ((int)VIDEO_MODE_DEPTH > VIDEO_DEPTH_8BIT) {
// handle the gamma ramp
if (pal[0] == 127 && pal[num_in*3-1] == 127) // solid grey
return; // ignore
uint16 red[256];
uint16 green[256];
uint16 blue[256];
int repeats = 256 / num_in;
for (int i = 0; i < num_in; i++) {
for (int j = 0; j < repeats; j++) {
red[i*repeats + j] = pal[i*3 + 0] << 8;
green[i*repeats + j] = pal[i*3 + 1] << 8;
blue[i*repeats + j] = pal[i*3 + 2] << 8;
}
}
// fill remaining entries (if any) with last value
for (int i = num_in * repeats; i < 256; i++) {
red[i] = pal[(num_in - 1) * 3] << 8;
green[i] = pal[(num_in - 1) * 3 + 1] << 8;
blue[i] = pal[(num_in - 1) * 3 + 2] << 8;
}
bool changed = (memcmp(red, last_gamma_red, 512) != 0 ||
memcmp(green, last_gamma_green, 512) != 0 ||
memcmp(blue, last_gamma_blue, 512) != 0);
if (changed && sdl_window) {
int result = SDL_SetWindowGammaRamp(sdl_window, red, green, blue);
if (result < 0) {
fprintf(stderr, "SDL_SetWindowGammaRamp returned %d, SDL error: %s\n", result, SDL_GetError());
}
memcpy(last_gamma_red, red, 512);
memcpy(last_gamma_green, green, 512);
memcpy(last_gamma_blue, blue, 512);
}
return;
}
LOCK_PALETTE;

View File

@ -211,6 +211,10 @@ static bool allocate_gamma_table(VidLocals *csSave, uint32 size)
return true;
}
static inline uint8 max(uint8 a, uint8 b) {
return a > b? a : b;
}
static int16 set_gamma(VidLocals *csSave, uint32 gamma)
{
if (gamma == 0) { // Build linear ramp, 256 entries
@ -229,8 +233,11 @@ static int16 set_gamma(VidLocals *csSave, uint32 gamma)
// Build the linear ramp
uint32 p = csSave->gammaTable + gFormulaData;
for (int i=0; i<256; i++)
for (int i=0; i<256; i++) {
WriteMacInt8(p + i, i);
mac_pal[i].red = mac_pal[i].green = mac_pal[i].blue = i;
}
} else { // User-supplied gamma table
@ -256,7 +263,41 @@ static int16 set_gamma(VidLocals *csSave, uint32 gamma)
// Copy table
Mac2Mac_memcpy(csSave->gammaTable, gamma, size);
// Save new gamma data for video impl
if (data_width != 8) {
// FIXME: handle bit-packed data
} else {
uint32 p = csSave->gammaTable + gFormulaData + gFormulaSize;
uint32 p_red;
uint32 p_green;
uint32 p_blue;
// make values increasing as some implementations really don't like it when gamma tables aren't
uint8 max_red = 0;
uint8 max_green = 0;
uint8 max_blue = 0;
if (chan_cnt == 3) {
p_red = p;
p_green = p + data_cnt;
p_blue = p + data_cnt * 2;
} else {
p_red = p_green = p_blue = p;
}
for (int i=0; i < data_cnt; i++) {
max_red = max(max_red, ReadMacInt8(p_red++));
max_green = max(max_green, ReadMacInt8(p_green++));
max_blue = max(max_blue, ReadMacInt8(p_blue++));
mac_pal[i].red = max_red;
mac_pal[i].green = max_green;
mac_pal[i].blue = max_blue;
}
}
}
video_set_palette();
return noErr;
}