mirror of
https://github.com/Pecusx/libretro-atari800.git
synced 2026-05-21 06:39:36 +02:00
507 lines
19 KiB
C
507 lines
19 KiB
C
/*
|
|
* colours_pal.c - Atari PAL colour palette generation and adjustment
|
|
*
|
|
* Copyright (C) 2009-2014 Atari800 development team (see DOC/CREDITS)
|
|
*
|
|
* This file is part of the Atari800 emulator project which emulates
|
|
* the Atari 400, 800, 800XL, 130XE, and 5200 8-bit computers.
|
|
*
|
|
* Atari800 is free software; you can redistribute it and/or modify
|
|
* it under the terms of the GNU General Public License as published by
|
|
* the Free Software Foundation; either version 2 of the License, or
|
|
* (at your option) any later version.
|
|
*
|
|
* Atari800 is distributed in the hope that it will be useful,
|
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
* GNU General Public License for more details.
|
|
*
|
|
* You should have received a copy of the GNU General Public License
|
|
* along with Atari800; if not, write to the Free Software
|
|
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
|
*/
|
|
#include <math.h>
|
|
#include <stdlib.h>
|
|
#include <string.h>
|
|
|
|
#include "colours_pal.h"
|
|
|
|
#include "atari.h" /* for TRUE/FALSE */
|
|
#include "colours.h"
|
|
#include "log.h"
|
|
#include "util.h"
|
|
|
|
#ifndef M_PI
|
|
#define M_PI 3.14159265358979323846
|
|
#endif
|
|
|
|
Colours_setup_t COLOURS_PAL_setup;
|
|
|
|
/* PAL-specific default setup. */
|
|
static struct {
|
|
double color_delay;
|
|
} const default_setup = {
|
|
23.2, /* chosen by eye to give a smooth rainbow */
|
|
};
|
|
|
|
COLOURS_EXTERNAL_t COLOURS_PAL_external = { "", FALSE, FALSE };
|
|
|
|
/* Fills YUV_TABLE from external palette. External palette is not adjusted if
|
|
COLOURS_PAL_external.adjust is false. */
|
|
static void GetYUVFromExternal(double yuv_table[256*5])
|
|
{
|
|
unsigned char *ext_ptr = COLOURS_PAL_external.palette;
|
|
int n;
|
|
|
|
double const hue = COLOURS_PAL_setup.hue * M_PI;
|
|
double const s = sin(hue);
|
|
double const c = cos(hue);
|
|
|
|
for (n = 0; n < 256; n ++) {
|
|
/* Convert RGB values from external palette to YUV. */
|
|
double r = (double)*ext_ptr++ / 255.0;
|
|
double g = (double)*ext_ptr++ / 255.0;
|
|
double b = (double)*ext_ptr++ / 255.0;
|
|
double y, u, v, tmp_u;
|
|
Colours_RGB2YUV(r, g, b, &y, &u, &v);
|
|
tmp_u = u;
|
|
u = tmp_u * c - v * s;
|
|
v = tmp_u * s + v * c;
|
|
/* Optionally adjust external palette. */
|
|
if (COLOURS_PAL_external.adjust) {
|
|
y *= COLOURS_PAL_setup.contrast * 0.5 + 1;
|
|
y += COLOURS_PAL_setup.brightness * 0.5;
|
|
if (y > 1.0)
|
|
y = 1.0;
|
|
else if (y < 0.0)
|
|
y = 0.0;
|
|
u *= COLOURS_PAL_setup.saturation + 1.0;
|
|
v *= COLOURS_PAL_setup.saturation + 1.0;
|
|
}
|
|
|
|
*yuv_table++ = y;
|
|
/* Cannot retrieve different U/V values for even and odd lines from an
|
|
external palette - instead write each value twice. */
|
|
*yuv_table++ = u;
|
|
*yuv_table++ = u;
|
|
*yuv_table++ = v;
|
|
*yuv_table++ = v;
|
|
}
|
|
}
|
|
|
|
/* Below are conclusions from analysis of oscillograms of PAL GTIA output.
|
|
The oscillograms are available at:
|
|
http://www.atari.org.pl/forum/viewtopic.php?pid=164037#p164037
|
|
|
|
Like the NTSC GTIA, the PAL GTIA produces color signal by delaying
|
|
(phase-shifting) a base chrominance subcarrier by a specified time -
|
|
different for each displayed hue. The subcarrier's frequency is
|
|
4433618.75 Hz (4.43 MHz in short). The subcarrier is provided at the chip's
|
|
PAL pin; output signal is produced at the COL pin.
|
|
|
|
As in NTSC, the delay introduced by the PAL GTIA can be adjusted to a
|
|
certain extent by changing voltage applied at the DEL pin.
|
|
|
|
This is where the similarities between the PAL GTIA and its NTSC
|
|
counterpart end.
|
|
|
|
In NTSC, each screen line contains, in its back porch, a burst of about 10
|
|
cycles of color subcarrier (known as the coloburst). The colorburst is used
|
|
by the TV as a reference for decoding colors in each line. Signal with
|
|
phase shift equal to the colorburst's (ie. equal to the subcarrier's) is
|
|
decoded as 180 deg angle in the YUV colorspace (-U). Delaying the signal is
|
|
interpreted as rotating the angle clockwise in YUV.
|
|
|
|
In PAL, there's also colorburst, but it is not equal to the color
|
|
subcarrier. In even lines it lags the subcarrier by 45 deg, and in odd
|
|
lines it leads it subcarrier by 45 deg. The resulting 90 deg difference is
|
|
used by the TV to distinguish even and odd lines. The original subcarrier
|
|
is recreated by the receiver by summing colorbursts from two consecutive
|
|
lines (and adjusting its amplitude, since sum of two sine waves shifted by
|
|
90 deg has higher amplitude than the original waves).
|
|
|
|
Then, as in NTSC, signals equal in phase to the (recreated) subcarrier are
|
|
decoded as 180 deg angle in YUV. But other signals are decoded differently
|
|
in even and in odd lines. In even lines (or "NTSC lines"), delaying the
|
|
signal is interpreted as rotating the angle clockwise in YUV, just like in
|
|
NTSC. But in odd lines (or "PAL lines"), delaying the signal is akin to
|
|
rotating the angle counter-clockwise. So, to achieve the same color in even
|
|
and odd lines, the transmitter must send signal delayed wrt. the subcarrier
|
|
in even lines but "rushed" (anti-delayed?) in odd lines.
|
|
|
|
PAL GTIA can only delay input signal; it can't "rush" it, it would involve
|
|
creating output before input has arrived. So the requirements of the PAL
|
|
system are achieved in the chip by delaying the signal differently in even
|
|
and odd lines.
|
|
|
|
Measurements indicate that the PAL GTIA delays the input subcarrier by
|
|
95.2ns; then it might delay it by further 100.7ns if needed; and finally
|
|
can delay it further by X, 2*X, 3*X, ..., 7*X, where X is a delay adjusted
|
|
by voltage at the DEL pin. The general formula is:
|
|
DELAY(hue) = 95.2ns + ADD(hue)*100.7ns + MULT(hue)*X
|
|
where
|
|
ADD(hue) depends on a given hue and can be 0 or 1,
|
|
MULT(hue) depends on a given hue and can be 0, 1, 2, ..., 7,
|
|
X depends on voltage at the DEL pin.
|
|
So, the chip can shift the input signal by 8*2=16 different delays.
|
|
|
|
Mapping of ADD and MULT values to specific hues is random - it is
|
|
implemented in the source code as the del_coeffs structure.
|
|
|
|
The relation between DEL pin voltage and the resulting delay is not linear
|
|
- it was measured to be:
|
|
17.37ns at 5V,
|
|
10.60ns at 7V,
|
|
7.44ns at 9V.
|
|
|
|
The PAL GTIA apparently contains a series of 7 delay elements similarly to
|
|
the NTSC version (which contains 15 of them), and an additional 100.7ns
|
|
delay element. (When looking at the oscillograms, for each hue that passes
|
|
through this 100.7ns delay, the resulting waveform is different than for
|
|
hues that don't involve the delay - it looks like it was inverted
|
|
vertically. This gives a hint about how the delay is implemented
|
|
internally.)
|
|
|
|
The end result is, PAL GTIA actually produces more than 256 colors. It
|
|
produces different hues in odd and even lines, but it is not normally
|
|
visible since PAL TVs average hues on each two consecutive lines - but
|
|
it can be made visible with specially-crafted screens. Currently this
|
|
feature of the chip is not implemented - only 256 colors are produced,
|
|
each one being an average of "even" and "odd" hues.
|
|
|
|
In PAL GTIA, just as in NTSC, the colorburst signals have the same phase as
|
|
Hue 1. But by changing voltage at the DEL pin, we also change the relative
|
|
phase shift of the colorburst between even and odd lines - it is not always
|
|
90 degrees. It has the following consequences - all of them observed on a
|
|
real machine, and all currently emulated:
|
|
1. Changing phase shift between odd and even colorbursts also changes
|
|
amplitude of the resulting subcarrier, which is recreated by summing the
|
|
two colorbursts. Since amplitude of the color subcarrier is used as a
|
|
reference for decoding color saturation, changing voltage at DEL not only
|
|
changes hues of displayed colors; it also changes their saturation.
|
|
2. With appropriately chosen DEL voltage, phase shift between even and odd
|
|
colorbursts can reach 180 deg. At this point the PAL TV can no longer
|
|
distinguish even and odd lines, and stops interpreting color signal,
|
|
displaying screen as black-and-white with visible chroma dots.
|
|
3. Changing DEL voltage further causes phase shift between even and odd
|
|
colorbursts to to be larger than 180 deg, at which point the TV starts
|
|
interpreting color signal "backwards", as if the color subcarrier suddenly
|
|
shifted by 180 deg.
|
|
*/
|
|
|
|
/* Generates PAL palette into YUV_TABLE. */
|
|
static void GetYUVFromGenerated(double yuv_table[256*5])
|
|
{
|
|
struct del_coeff {
|
|
int add;
|
|
int mult;
|
|
};
|
|
|
|
/* Delay coefficients for each hue. */
|
|
static struct {
|
|
struct del_coeff even[15];
|
|
struct del_coeff odd[15];
|
|
} const del_coeffs = {
|
|
{ { 1, 5 }, /* Hue $1 in even lines */
|
|
{ 1, 6 }, /* Hue $2 in even lines */
|
|
{ 1, 7 },
|
|
{ 0, 0 },
|
|
{ 0, 1 },
|
|
{ 0, 2 },
|
|
{ 0, 4 },
|
|
{ 0, 5 },
|
|
{ 0, 6 },
|
|
{ 0, 7 },
|
|
{ 1, 1 },
|
|
{ 1, 2 },
|
|
{ 1, 3 },
|
|
{ 1, 4 },
|
|
{ 1, 5 } /* Hue $F in even lines */
|
|
},
|
|
{ { 1, 1 }, /* Hue $1 in odd lines */
|
|
{ 1, 0 }, /* Hue $2 in odd lines */
|
|
{ 0, 7 },
|
|
{ 0, 6 },
|
|
{ 0, 5 },
|
|
{ 0, 4 },
|
|
{ 0, 2 },
|
|
{ 0, 1 },
|
|
{ 0, 0 },
|
|
{ 1, 7 },
|
|
{ 1, 5 },
|
|
{ 1, 4 },
|
|
{ 1, 3 },
|
|
{ 1, 2 },
|
|
{ 1, 1 } /* Hue $F in odd lines */
|
|
}
|
|
};
|
|
int cr, lm;
|
|
|
|
double const scaled_black_level = (double)COLOURS_PAL_setup.black_level / 255.0f;
|
|
double const scaled_white_level = (double)COLOURS_PAL_setup.white_level / 255.0f;
|
|
|
|
/* NTSC luma multipliers from CGIA.PDF */
|
|
static double const luma_mult[16] = {
|
|
0.6941, 0.7091, 0.7241, 0.7401,
|
|
0.7560, 0.7741, 0.7931, 0.8121,
|
|
0.8260, 0.8470, 0.8700, 0.8930,
|
|
0.9160, 0.9420, 0.9690, 1.0000};
|
|
|
|
/* When phase shift between even and odd colorbursts is close to 180 deg, the
|
|
TV stops interpreting color signal. This value determines how close to 180
|
|
deg that phase shift must be. It is specific to a TV set. */
|
|
static double const color_disable_threshold = 0.05;
|
|
/* Base delay - 1/4.43MHz * base_del = ca. 95.2ns */
|
|
static double const base_del = 0.421894970414201;
|
|
/* Additional delay - 1/4.43MHz * add_del = ca. 100.7ns */
|
|
static double const add_del = 0.446563064859117;
|
|
/* Delay introduced by the DEL pin voltage. */
|
|
double const del_adj = COLOURS_PAL_setup.color_delay / 360.0;
|
|
|
|
/* Phase delays of colorbursts in even and odd lines. They are equal to
|
|
Hue 1. */
|
|
double const even_burst_del = base_del + add_del * del_coeffs.even[0].add + del_adj * del_coeffs.even[0].mult;
|
|
double const odd_burst_del = base_del + add_del * del_coeffs.odd[0].add + del_adj * del_coeffs.odd[0].mult;
|
|
|
|
/* Reciprocal of the recreated subcarrier's amplitude. */
|
|
double saturation_mult;
|
|
/* Phase delay of the recreated amplitude. */
|
|
double subcarrier_del = (even_burst_del + odd_burst_del + COLOURS_PAL_setup.hue) / 2.0;
|
|
|
|
/* Phase difference between colorbursts in even and odd lines. */
|
|
double burst_diff = even_burst_del - odd_burst_del;
|
|
burst_diff -= floor(burst_diff); /* Normalize to 0..1. */
|
|
|
|
if (burst_diff > 0.5 - color_disable_threshold && burst_diff < 0.5 + color_disable_threshold)
|
|
/* Shift between colorbursts close to 180 deg. Don't produce color. */
|
|
saturation_mult = 0.0;
|
|
else {
|
|
/* Subcarrier is a sum of two waves with equal frequency and amplitude,
|
|
but phase-shifted by 2pi*burst_diff. The formula is derived from
|
|
http://2000clicks.com/mathhelp/GeometryTrigEquivPhaseShift.aspx */
|
|
double subcarrier_amplitude = sqrt(2.0 * cos(burst_diff*2.0*M_PI) + 2.0);
|
|
/* Normalise saturation_mult by multiplying by sqrt(2), so that it
|
|
equals 1.0 when odd & even colorbursts are shifted by 90 deg (ie.
|
|
burst_diff == 0.25). */
|
|
saturation_mult = sqrt(2.0) / subcarrier_amplitude;
|
|
}
|
|
|
|
for (cr = 0; cr < 16; cr ++) {
|
|
double even_u = 0.0;
|
|
double odd_u = 0.0;
|
|
double even_v = 0.0;
|
|
double odd_v = 0.0;
|
|
if (cr) {
|
|
struct del_coeff const *even_delay = &(del_coeffs.even[cr - 1]);
|
|
struct del_coeff const *odd_delay = &(del_coeffs.odd[cr - 1]);
|
|
double even_del = base_del + add_del * even_delay->add + del_adj * even_delay->mult;
|
|
double odd_del = base_del + add_del * odd_delay->add + del_adj * odd_delay->mult;
|
|
double even_angle = (0.5 - (even_del - subcarrier_del)) * 2.0 * M_PI;
|
|
double odd_angle = (0.5 + (odd_del - subcarrier_del)) * 2.0 * M_PI;
|
|
double saturation = (COLOURS_PAL_setup.saturation + 1) * 0.175 * saturation_mult;
|
|
even_u = cos(even_angle) * saturation;
|
|
even_v = sin(even_angle) * saturation;
|
|
odd_u = cos(odd_angle) * saturation;
|
|
odd_v = sin(odd_angle) * saturation;
|
|
}
|
|
for (lm = 0; lm < 16; lm ++) {
|
|
/* calculate yuv for color entry */
|
|
double y = (luma_mult[lm] - luma_mult[0]) / (luma_mult[15] - luma_mult[0]);
|
|
y *= COLOURS_PAL_setup.contrast * 0.5 + 1;
|
|
y += COLOURS_PAL_setup.brightness * 0.5;
|
|
/* Scale the Y signal's range from 0..1 to
|
|
scaled_black_level..scaled_white_level */
|
|
y = y * (scaled_white_level - scaled_black_level) + scaled_black_level;
|
|
/*
|
|
if (y < scaled_black_level)
|
|
y = scaled_black_level;
|
|
else if (y > scaled_white_level)
|
|
y = scaled_white_level;
|
|
*/
|
|
*yuv_table++ = y;
|
|
*yuv_table++ = even_u;
|
|
*yuv_table++ = odd_u;
|
|
*yuv_table++ = even_v;
|
|
*yuv_table++ = odd_v;
|
|
}
|
|
}
|
|
}
|
|
|
|
void COLOURS_PAL_GetYUV(double yuv_table[256*5])
|
|
{
|
|
if (COLOURS_PAL_external.loaded)
|
|
GetYUVFromExternal(yuv_table);
|
|
else
|
|
GetYUVFromGenerated(yuv_table);
|
|
}
|
|
|
|
/* Averages YUV values from YUV_TABLE and converts them to RGB values. Stores
|
|
them in COLOURTABLE. */
|
|
static void YUV2RGB(int colourtable[256], double const yuv_table[256*5])
|
|
{
|
|
double const *yuv_ptr = yuv_table;
|
|
int n;
|
|
for (n = 0; n < 256; ++n) {
|
|
double y = *yuv_ptr++;
|
|
double even_u = *yuv_ptr++;
|
|
double odd_u = *yuv_ptr++;
|
|
double even_v = *yuv_ptr++;
|
|
double odd_v = *yuv_ptr++;
|
|
double r, g, b;
|
|
/* The different colors in odd and even lines are not
|
|
emulated - instead the palette contains averaged values. */
|
|
double u = (even_u + odd_u) / 2.0;
|
|
double v = (even_v + odd_v) / 2.0;
|
|
Colours_YUV2RGB(y, u, v, &r, &g, &b);
|
|
|
|
if (!COLOURS_PAL_external.loaded || COLOURS_PAL_external.adjust) {
|
|
/* The r, g, b values derived from the YUV signal are non-linear
|
|
(ie. gamma-corrected). We convert them to linear values,
|
|
assuming the CRT TV's gamma = COLOURS_PAL_setup.gamma. */
|
|
r = Colours_Gamma2Linear(r, COLOURS_PAL_setup.gamma);
|
|
g = Colours_Gamma2Linear(g, COLOURS_PAL_setup.gamma);
|
|
b = Colours_Gamma2Linear(b, COLOURS_PAL_setup.gamma);
|
|
/* Now we convert the linear values to the sRGB colourspace. */
|
|
r = Colours_Linear2sRGB(r);
|
|
g = Colours_Linear2sRGB(g);
|
|
b = Colours_Linear2sRGB(b);
|
|
}
|
|
|
|
Colours_SetRGB(n, (int) (r * 255), (int) (g * 255), (int) (b * 255), colourtable);
|
|
}
|
|
}
|
|
|
|
void COLOURS_PAL_Update(int colourtable[256])
|
|
{
|
|
double yuv_table[256*5];
|
|
COLOURS_PAL_GetYUV(yuv_table);
|
|
YUV2RGB(colourtable, yuv_table);
|
|
}
|
|
|
|
void COLOURS_PAL_RestoreDefaults(void)
|
|
{
|
|
COLOURS_PAL_setup.color_delay = default_setup.color_delay;
|
|
}
|
|
|
|
Colours_preset_t COLOURS_PAL_GetPreset()
|
|
{
|
|
if (Util_almostequal(COLOURS_PAL_setup.color_delay, default_setup.color_delay, 0.001))
|
|
return COLOURS_PRESET_STANDARD;
|
|
return COLOURS_PRESET_CUSTOM;
|
|
}
|
|
|
|
int COLOURS_PAL_ReadConfig(char *option, char *ptr)
|
|
{
|
|
if (strcmp(option, "COLOURS_PAL_SATURATION") == 0)
|
|
return Util_sscandouble(ptr, &COLOURS_PAL_setup.saturation);
|
|
else if (strcmp(option, "COLOURS_PAL_CONTRAST") == 0)
|
|
return Util_sscandouble(ptr, &COLOURS_PAL_setup.contrast);
|
|
else if (strcmp(option, "COLOURS_PAL_BRIGHTNESS") == 0)
|
|
return Util_sscandouble(ptr, &COLOURS_PAL_setup.brightness);
|
|
else if (strcmp(option, "COLOURS_PAL_GAMMA") == 0)
|
|
return Util_sscandouble(ptr, &COLOURS_PAL_setup.gamma);
|
|
else if (strcmp(option, "COLOURS_PAL_HUE") == 0)
|
|
return Util_sscandouble(ptr, &COLOURS_PAL_setup.hue);
|
|
else if (strcmp(option, "COLOURS_PAL_GTIA_DELAY") == 0)
|
|
return Util_sscandouble(ptr, &COLOURS_PAL_setup.color_delay);
|
|
else if (strcmp(option, "COLOURS_PAL_EXTERNAL_PALETTE") == 0)
|
|
Util_strlcpy(COLOURS_PAL_external.filename, ptr, sizeof(COLOURS_PAL_external.filename));
|
|
else if (strcmp(option, "COLOURS_PAL_EXTERNAL_PALETTE_LOADED") == 0)
|
|
/* Use the "loaded" flag to indicate that the palette must be loaded later. */
|
|
return (COLOURS_PAL_external.loaded = Util_sscanbool(ptr)) != -1;
|
|
else if (strcmp(option, "COLOURS_PAL_ADJUST_EXTERNAL_PALETTE") == 0)
|
|
return (COLOURS_PAL_external.adjust = Util_sscanbool(ptr)) != -1;
|
|
else
|
|
return FALSE;
|
|
return TRUE;
|
|
}
|
|
|
|
void COLOURS_PAL_WriteConfig(FILE *fp)
|
|
{
|
|
fprintf(fp, "COLOURS_PAL_SATURATION=%g\n", COLOURS_PAL_setup.saturation);
|
|
fprintf(fp, "COLOURS_PAL_CONTRAST=%g\n", COLOURS_PAL_setup.contrast);
|
|
fprintf(fp, "COLOURS_PAL_BRIGHTNESS=%g\n", COLOURS_PAL_setup.brightness);
|
|
fprintf(fp, "COLOURS_PAL_GAMMA=%g\n", COLOURS_PAL_setup.gamma);
|
|
fprintf(fp, "COLOURS_PAL_HUE=%g\n", COLOURS_PAL_setup.hue);
|
|
fprintf(fp, "COLOURS_PAL_GTIA_DELAY=%g\n", COLOURS_PAL_setup.color_delay);
|
|
fprintf(fp, "COLOURS_PAL_EXTERNAL_PALETTE=%s\n", COLOURS_PAL_external.filename);
|
|
fprintf(fp, "COLOURS_PAL_EXTERNAL_PALETTE_LOADED=%d\n", COLOURS_PAL_external.loaded);
|
|
fprintf(fp, "COLOURS_PAL_ADJUST_EXTERNAL_PALETTE=%d\n", COLOURS_PAL_external.adjust);
|
|
}
|
|
|
|
int COLOURS_PAL_Initialise(int *argc, char *argv[])
|
|
{
|
|
int i;
|
|
int j;
|
|
|
|
for (i = j = 1; i < *argc; i++) {
|
|
int i_a = (i + 1 < *argc); /* is argument available? */
|
|
int a_m = FALSE; /* error, argument missing! */
|
|
|
|
if (strcmp(argv[i], "-pal-saturation") == 0) {
|
|
if (i_a)
|
|
COLOURS_PAL_setup.saturation = atof(argv[++i]);
|
|
else a_m = TRUE;
|
|
}
|
|
else if (strcmp(argv[i], "-pal-contrast") == 0) {
|
|
if (i_a)
|
|
COLOURS_PAL_setup.contrast = atof(argv[++i]);
|
|
else a_m = TRUE;
|
|
}
|
|
else if (strcmp(argv[i], "-pal-brightness") == 0) {
|
|
if (i_a)
|
|
COLOURS_PAL_setup.brightness = atof(argv[++i]);
|
|
else a_m = TRUE;
|
|
}
|
|
else if (strcmp(argv[i], "-pal-gamma") == 0) {
|
|
if (i_a)
|
|
COLOURS_PAL_setup.gamma = atof(argv[++i]);
|
|
else a_m = TRUE;
|
|
}
|
|
else if (strcmp(argv[i], "-pal-tint") == 0) {
|
|
if (i_a)
|
|
COLOURS_PAL_setup.hue = atof(argv[++i]);
|
|
else a_m = TRUE;
|
|
}
|
|
else if (strcmp(argv[i], "-pal-colordelay") == 0) {
|
|
if (i_a)
|
|
COLOURS_PAL_setup.color_delay = atof(argv[++i]);
|
|
else a_m = TRUE;
|
|
}
|
|
else if (strcmp(argv[i], "-palettep") == 0) {
|
|
if (i_a) {
|
|
Util_strlcpy(COLOURS_PAL_external.filename, argv[++i], sizeof(COLOURS_PAL_external.filename));
|
|
/* Use the "loaded" flag to indicate that the palette must be loaded later. */
|
|
COLOURS_PAL_external.loaded = TRUE;
|
|
} else a_m = TRUE;
|
|
}
|
|
else if (strcmp(argv[i], "-palettep-adjust") == 0)
|
|
COLOURS_PAL_external.adjust = TRUE;
|
|
else {
|
|
if (strcmp(argv[i], "-help") == 0) {
|
|
Log_print("\t-pal-saturation <num> Set PAL color saturation");
|
|
Log_print("\t-pal-contrast <num> Set PAL contrast");
|
|
Log_print("\t-pal-brightness <num> Set PAL brightness");
|
|
Log_print("\t-pal-gamma <num> Set PAL color gamma factor");
|
|
Log_print("\t-pal-tint <num> Set PAL tint");
|
|
Log_print("\t-pal-colordelay <num> Set PAL GTIA color delay");
|
|
Log_print("\t-palettep <filename> Load PAL external palette");
|
|
Log_print("\t-palettep-adjust Apply adjustments to PAL external palette");
|
|
}
|
|
argv[j++] = argv[i];
|
|
}
|
|
|
|
if (a_m) {
|
|
Log_print("Missing argument for '%s'", argv[i]);
|
|
return FALSE;
|
|
}
|
|
}
|
|
*argc = j;
|
|
|
|
/* Try loading an external palette if needed. */
|
|
if (COLOURS_PAL_external.loaded && !COLOURS_EXTERNAL_Read(&COLOURS_PAL_external))
|
|
Log_print("Cannot read PAL palette from %s", COLOURS_PAL_external.filename);
|
|
|
|
return TRUE;
|
|
}
|