Comments (16)
Is the curve there identical to that in SameBoy?
Yes.
from rgbds.
rgba.cpp credits its color curve to LIJI32/SameBoy@65dd02c. SameBoy's color correction is designed to make PC colors appear like GBC hardware ones, with less contrast and brightness. RGBGFX would want to do the reverse, and exaggerate the colors so playing on real hardware would look like the designer's PC mockups.
To do: fill in the gaps in this reversed mapping:
static std::array<uint8_t, 256> reverse_curve{
0, __, 1, __, 2, __, __, 3, __, __, __, __, 4, __, __, __, // These
__, __, 5, __, __, __, __, __, __, 6, __, __, __, __, __, __, // comments
__, __, 7, __, __, __, __, __, __, __, 8, __, __, __, __, __, // prevent
__, __, __, __, 9, __, __, __, __, __, __, __, __, __, 10, __, // clang-format
__, __, __, __, __, __, __, __, __, 11, __, __, __, __, __, __, // from
__, __, __, __, __, 12, __, __, __, __, __, __, __, __, __, __, // reflowing
__, 13, __, __, __, __, __, __, __, __, __, __, __, 14, __, __, // these
__, __, __, __, __, __, __, __, __, 15, __, __, __, __, __, __, // sixteen
__, __, __, __, __, __, 16, __, __, __, __, __, __, __, __, __, // 16-item
__, __, 17, __, __, __, __, __, __, __, __, __, __, __, 18, __, // lines,
__, __, __, __, __, __, __, __, __, __, 19, __, __, __, __, __, // which,
__, __, __, __, __, __, 20, __, __, __, __, __, __, __, __, __, // in
__, 21, __, __, __, __, __, __, __, __, __, 22, __, __, __, __, // my
__, __, __, __, __, 23, __, __, __, __, __, __, __, 24, __, __, // opinion,
__, __, __, __, __, __, 25, __, __, __, __, __, __, 26, __, __, // help
__, __, __, 27, __, __, __, __, 28, __, __, 29, __, 30, __, 31, // visualization!
};
from rgbds.
Is the curve there identical to that in SameBoy?
from rgbds.
SameBoy has a lot of colour correction settings, but I think we should stick to GB_COLOR_CORRECTION_CORRECT_CURVES
(which, I believe, corresponds to what @LIJI32 calls "Harsh Reality"). Then comes the question of which curve we want to stick to; I'd favour the "default" one over SGB or AGB.
from rgbds.
I was slightly lazy and linearly interpolated between those points:
static std::array<uint8_t, 256> reverse_curve{
0, 0, 0, 1, 1, 1, 1, 1, 1, 2, 2, 2, 2, 2, 2, 2, // These
3, 3, 3, 3, 3, 3, 3, 3, 4, 4, 4, 4, 4, 4, 4, 4, // comments
5, 5, 5, 5, 5, 5, 5, 5, 5, 6, 6, 6, 6, 6, 6, 6, // prevent
6, 6, 6, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 8, 8, 8, // clang-format
8, 8, 8, 8, 8, 8, 8, 9, 9, 9, 9, 9, 9, 9, 9, 9, // from
9, 9, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 11, 11, // reflowing
11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 12, 12, 12, 12, 12, // these
12, 12, 12, 12, 12, 12, 12, 13, 13, 13, 13, 13, 13, 13, 13, 13, // sixteen
13, 13, 13, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 15, // 16-item
15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 16, 16, 16, 16, 16, // lines,
16, 16, 16, 16, 16, 16, 16, 17, 17, 17, 17, 17, 17, 17, 17, 17, // which
17, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 19, 19, 19, 19, 19, // in my
19, 19, 19, 19, 19, 20, 20, 20, 20, 20, 20, 20, 20, 20, 21, 21, // opinion,
21, 21, 21, 21, 21, 21, 22, 22, 22, 22, 22, 22, 22, 22, 23, 23, // improves
23, 23, 23, 23, 23, 24, 24, 24, 24, 24, 24, 25, 25, 25, 25, 25, // the
25, 26, 26, 26, 26, 27, 27, 27, 27, 28, 28, 29, 29, 30, 30, 31, // readability!
};
Code used to generate this:
const CURVE: [u8; 32] = [
0, 6, 12, 20, 28, 36, 45, 56, 66, 76, 88, 100, 113, 125, 137, 149, 161, 172, 182, 192, 202,
210, 218, 225, 232, 238, 243, 247, 250, 252, 254, 255,
];
fn main() {
for i in 0..=255 {
let rev = match CURVE.binary_search(&i) {
Ok(idx) => idx,
Err(insert_idx) => {
let lower = CURVE[insert_idx - 1];
let higher = CURVE[insert_idx];
// Linearly interpolate between these two.
if i - lower < higher - i {
insert_idx - 1
} else {
insert_idx
}
}
};
print!("{rev:2}, ");
if i % 16 == 15 {
println!();
}
}
}
from rgbds.
Just by looking at the data, I can't recognize the function itself, but the second derivative is small enough that a linear interpolation shouldn't be too far off.
from rgbds.
I got a polynomial regression of -0.0134x³ + 0.5484x² + 4.2072x - 5.3585 to match with R² = 0.9998. I don't know if that helps.
from rgbds.
I was slightly lazy and linearly interpolated between those points:
That curve is still the reverse of what we need. It should be identical to the reverse_curve
above, but with the __
s filled in.
I generated one with NumPy; here's the code:
curve.py
#!/usr/bin/env python3
import numpy
# Copied from https://github.com/LIJI32/SameBoy/commit/65dd02cc#diff-34ffdb0f13b7232c28e80c9e78e86d5ea95bc08ca0a45d8c3ab195f18e4e1921R230
xs = [0,2,4,7,12,18,25,34,42,52,62,73,85,97,109,121,134,146,158,170,182,193,203,213,221,230,237,243,248,251,253,255]
ys = [(v << 3) | (v >> 2) for v in range(32)]
degree = 9 # minimum need to not have errors greater than 1
fit = numpy.polynomial.polynomial.polyfit(xs, ys, deg=degree)
def interpolate(x):
return int(round(sum(fit[i]*x**i for i in range(degree + 1))))
print('x', 'y', 'interpolated', sep='\t')
for x, y in zip(xs, ys):
interpolated = interpolate(x)
error = ['!'] if abs(y - interpolated) > 1 else []
print(*[x, y, interpolated, *error], sep='\t')
print()
data = [(ys[xs.index(x)] if x in xs else interpolate(x)) >> 3 for x in range(256)]
comments = ['These', 'comments', 'prevent', 'clang-format', 'from', 'reflowing', 'these', 'sixteen',
'16-item', 'lines,', 'which,', 'in', 'my', 'opinion,', 'help', 'visualization!',]
print('static std::array<uint8_t, 256> reverse_curve{')
for i in range(16):
print(f" {', '.join(f'{v:2}' for v in data[i*16:i*16+16])}, // {comments[i]}")
print('};')
This is the completely interpolated array:
static std::array<uint8_t, 256> reverse_curve{
0, 0, 1, 1, 2, 2, 2, 3, 3, 3, 3, 4, 4, 4, 4, 4, // These
4, 5, 5, 5, 5, 5, 5, 5, 6, 6, 6, 6, 6, 6, 6, 6, // comments
7, 7, 7, 7, 7, 7, 7, 7, 7, 8, 8, 8, 8, 8, 8, 8, // prevent
8, 8, 9, 9, 9, 9, 9, 9, 9, 9, 9, 10, 10, 10, 10, 10, // clang-format
10, 10, 10, 10, 10, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, // from
12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 13, 13, 13, // reflowing
13, 13, 13, 13, 13, 13, 13, 13, 13, 14, 14, 14, 14, 14, 14, 14, // these
14, 14, 14, 14, 14, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, // sixteen
16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 17, 17, 17, 17, 17, // 16-item
17, 17, 17, 17, 17, 17, 17, 18, 18, 18, 18, 18, 18, 18, 18, 18, // lines,
18, 18, 18, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, // which,
20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 21, 21, 21, 21, 21, // in
21, 21, 21, 21, 21, 22, 22, 22, 22, 22, 22, 22, 22, 22, 23, 23, // my
23, 23, 23, 23, 23, 23, 23, 24, 24, 24, 24, 24, 24, 24, 24, 24, // opinion,
25, 25, 25, 25, 25, 25, 25, 25, 26, 26, 26, 26, 26, 26, 26, 27, // help
27, 27, 27, 27, 27, 28, 28, 28, 28, 29, 29, 29, 30, 30, 31, 31, // visualization!
};
from rgbds.
Hmm, that's based on an old curve; https://github.com/LIJI32/SameBoy/blob/master/Core/display.c#L257 is different.
When I use those values for xs
in the above curve.py script, I get this reverse curve:
static std::array<uint8_t, 256> reverse_curve{
0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 2, 2, 2, 2, // These
2, 2, 2, 2, 3, 3, 3, 3, 3, 3, 3, 3, 4, 4, 4, 4, // comments
4, 4, 4, 4, 5, 5, 5, 5, 5, 5, 5, 5, 6, 6, 6, 6, // prevent
6, 6, 6, 6, 6, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 8, // clang-format
8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 9, 9, 9, 9, 9, 9, // from
9, 9, 9, 9, 9, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, // reflowing
10, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 12, 12, 12, // these
12, 12, 12, 12, 12, 12, 12, 12, 13, 13, 13, 13, 13, 13, 13, 13, // sixteen
13, 13, 13, 13, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 15, // 16-item
15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 16, 16, 16, 16, 16, // lines,
16, 16, 16, 16, 16, 16, 16, 17, 17, 17, 17, 17, 17, 17, 17, 17, // which,
17, 17, 18, 18, 18, 18, 18, 18, 18, 18, 18, 19, 19, 19, 19, 19, // in
19, 19, 19, 19, 20, 20, 20, 20, 20, 20, 20, 20, 21, 21, 21, 21, // my
21, 21, 21, 21, 22, 22, 22, 22, 22, 22, 22, 22, 23, 23, 23, 23, // opinion,
23, 23, 23, 23, 24, 24, 24, 24, 24, 24, 24, 25, 25, 25, 25, 25, // help
26, 26, 26, 26, 27, 27, 27, 27, 28, 28, 28, 29, 29, 30, 30, 31, // visualization!
};
I've updated #1241 to use this data.
from rgbds.
If that's still desaturated, then swapping xs
and ys
gives this:
static std::array<uint8_t, 256> reverse_curve{
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, // These
1, 1, 1, 1, 2, 2, 2, 2, 2, 2, 2, 2, 2, 3, 3, 3, // comments
3, 3, 3, 3, 3, 4, 4, 4, 4, 4, 4, 4, 5, 5, 5, 5, // prevent
5, 5, 5, 6, 6, 6, 6, 6, 6, 7, 7, 7, 7, 7, 7, 7, // clang-format
7, 8, 8, 8, 8, 8, 8, 9, 9, 9, 9, 9, 10, 10, 10, 10, // from
10, 10, 11, 11, 11, 11, 11, 11, 12, 12, 12, 12, 12, 13, 13, 13, // reflowing
13, 13, 14, 14, 14, 14, 14, 14, 15, 15, 15, 15, 15, 16, 16, 16, // these
16, 16, 16, 17, 17, 17, 17, 17, 18, 18, 18, 18, 18, 18, 19, 19, // sixteen
19, 19, 19, 20, 20, 20, 20, 20, 20, 21, 21, 21, 21, 21, 21, 22, // 16-item
22, 22, 22, 22, 22, 22, 23, 23, 23, 23, 23, 23, 24, 24, 24, 24, // lines,
24, 24, 24, 25, 25, 25, 25, 25, 25, 25, 25, 26, 26, 26, 26, 26, // which,
26, 26, 26, 27, 27, 27, 27, 27, 27, 27, 27, 27, 28, 28, 28, 28, // in
28, 28, 28, 28, 28, 28, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, // my
29, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, // opinion,
31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, // help
31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, // visualization!
};
from rgbds.
Testing all the possible colors:
With the first curve:
With the second curve:
Code:
colors.py
#!/usr/bin/env python3
import sys
import png
mode = sys.argv[1] if len(sys.argv) > 1 else 'raw'
if mode not in {'raw', 'rev1', 'rev2'}:
print(f'Usage: {sys.argv[0]} (raw | rev1 | rev2)', file=sys.stderr)
exit(1)
def up(c):
if mode == 'rev1':
# https://github.com/gbdev/rgbds/issues/1226#issuecomment-1809210877
c = [
0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 2, 2, 2, 2,
2, 2, 2, 2, 3, 3, 3, 3, 3, 3, 3, 3, 4, 4, 4, 4,
4, 4, 4, 4, 5, 5, 5, 5, 5, 5, 5, 5, 6, 6, 6, 6,
6, 6, 6, 6, 6, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 8,
8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 9, 9, 9, 9, 9, 9,
9, 9, 9, 9, 9, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10,
10, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 12, 12, 12,
12, 12, 12, 12, 12, 12, 12, 12, 13, 13, 13, 13, 13, 13, 13, 13,
13, 13, 13, 13, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 15,
15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 16, 16, 16, 16, 16,
16, 16, 16, 16, 16, 16, 16, 17, 17, 17, 17, 17, 17, 17, 17, 17,
17, 17, 18, 18, 18, 18, 18, 18, 18, 18, 18, 19, 19, 19, 19, 19,
19, 19, 19, 19, 20, 20, 20, 20, 20, 20, 20, 20, 21, 21, 21, 21,
21, 21, 21, 21, 22, 22, 22, 22, 22, 22, 22, 22, 23, 23, 23, 23,
23, 23, 23, 23, 24, 24, 24, 24, 24, 24, 24, 25, 25, 25, 25, 25,
26, 26, 26, 26, 27, 27, 27, 27, 28, 28, 28, 29, 29, 30, 30, 31,
][(c << 3) | (c >> 2)]
elif mode == 'rev2':
# https://github.com/gbdev/rgbds/issues/1226#issuecomment-1809231223
c = [
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1,
1, 1, 1, 1, 2, 2, 2, 2, 2, 2, 2, 2, 2, 3, 3, 3,
3, 3, 3, 3, 3, 4, 4, 4, 4, 4, 4, 4, 5, 5, 5, 5,
5, 5, 5, 6, 6, 6, 6, 6, 6, 7, 7, 7, 7, 7, 7, 7,
7, 8, 8, 8, 8, 8, 8, 9, 9, 9, 9, 9, 10, 10, 10, 10,
10, 10, 11, 11, 11, 11, 11, 11, 12, 12, 12, 12, 12, 13, 13, 13,
13, 13, 14, 14, 14, 14, 14, 14, 15, 15, 15, 15, 15, 16, 16, 16,
16, 16, 16, 17, 17, 17, 17, 17, 18, 18, 18, 18, 18, 18, 19, 19,
19, 19, 19, 20, 20, 20, 20, 20, 20, 21, 21, 21, 21, 21, 21, 22,
22, 22, 22, 22, 22, 22, 23, 23, 23, 23, 23, 23, 24, 24, 24, 24,
24, 24, 24, 25, 25, 25, 25, 25, 25, 25, 25, 26, 26, 26, 26, 26,
26, 26, 26, 27, 27, 27, 27, 27, 27, 27, 27, 27, 28, 28, 28, 28,
28, 28, 28, 28, 28, 28, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29,
29, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30,
31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31,
31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31,
][(c << 3) | (c >> 2)]
return (c << 3) | (c >> 2)
ch_bits = 5
ch_size = 2**ch_bits # 32
width_sq = 8
height_sq = 4
assert width_sq * height_sq == ch_size
width_px = width_sq * ch_size # 256
height_px = height_sq * ch_size # 128
rows = [[(0, 0, 0)] * width_px for _ in range(height_px)]
for r in range(32):
for g in range(32):
for b in range(32):
x = (r % width_sq) * ch_size + b
y = (r // width_sq) * ch_size + g
rows[y][x] = (up(r), up(g), up(b))
rows = [sum(row, ()) for row in rows]
writer = png.Writer(width_px, height_px, greyscale=False, bitdepth=8, compression=9)
with open(f'colors_{mode}.png', 'wb') as file:
writer.write(file, rows)
On that basis I've updated the PR to use rev2
.
from rgbds.
Hmm, so SameBoy's "Harsh reality" color correction, which is presumably the closest to real GBC hardware, does more than just map through that curve array. Here's the reduced code for CGB with GB_COLOR_CORRECTION_LOW_CONTRAST
:
static inline uint8_t scale_channel_with_curve(uint8_t x)
{
return inline_const(uint8_t[], {0,6,12,20,28,36,45,56,66,76,88,100,113,125,137,149,161,172,182,192,202,210,218,225,232,238,243,247,250,252,254,255})[x];
}
// given r,g,b in 0-31 range, update their values to be harshly realistic
r = scale_channel_with_curve(r);
g = scale_channel_with_curve(g);
b = scale_channel_with_curve(b);
if (g != b) {
g = round(pow((pow(g / 255.0, 2.2) * 3 + pow(b / 255.0, 2.2)) / 4, 1 / 2.2) * 255);
}
uint8_t new_r = r * 15 / 16 + ( g + b) / 32;
uint8_t new_g = g * 15 / 16 + (r + b) / 32;
uint8_t new_b = b * 15 / 16 + (r + g ) / 32;
r = new_r;
g = new_g;
b = new_b;
r = r * (162 - 45) / 255 + 45;
g = g * (167 - 41) / 255 + 41;
b = b * (157 - 38) / 255 + 38;
r >>= 3;
g >>= 3;
b >>= 3;
Maybe we should figure out a more complex reverse transformation than just a per-channel lookup table.
from rgbds.
This will print out all 32,768 raw->scaled colors. Ideally we'd want to reverse-map every color on the right to its original on the left.
#include <stdio.h>
#include <math.h>
int main() {
static int scale_channel_with_curve[32] = {
0,6,12,20,28,36,45,56,66,76,88,100,113,125,137,149,161,172,
182,192,202,210,218,225,232,238,243,247,250,252,254,255
};
for (int raw_r = 0; raw_r < 32; raw_r++) {
for (int raw_g = 0; raw_g < 32; raw_g++) {
for (int raw_b = 0; raw_b < 32; raw_b++) {
int scaled_r = scale_channel_with_curve[raw_r];
int scaled_g = scale_channel_with_curve[raw_g];
int scaled_b = scale_channel_with_curve[raw_b];
if (scaled_g != scaled_b) {
scaled_g = round(pow((pow(scaled_g / 255.0, 2.2) * 3 +
pow(scaled_b / 255.0, 2.2)) / 4, 1 / 2.2) * 255);
}
int new_r = scaled_r * 15 / 16 + (scaled_g + scaled_b) / 32;
int new_g = scaled_g * 15 / 16 + (scaled_r + scaled_b) / 32;
int new_b = scaled_b * 15 / 16 + (scaled_r + scaled_g) / 32;
new_r = new_r * (162 - 45) / 255 + 45;
new_g = new_g * (167 - 41) / 255 + 41;
new_b = new_b * (157 - 38) / 255 + 38;
new_r >>= 3;
new_g >>= 3;
new_b >>= 3;
printf("%02d,%02d,%02d -> %02d,%02d,%02d\n",
raw_r, raw_g, raw_b, new_r, new_g, new_b);
}
}
}
return 0;
}
from rgbds.
These are the ranges of the harsh-reality-scaled values:
min R: [05,05,06,06,07,07,08,08,09,09,10,10,11,12,12,13,14,14,15,15,16,16,17,17,18,18,18,18,19,19,19,19]
max R: [06,06,07,07,07,08,08,09,09,10,11,11,12,13,13,14,15,15,16,16,17,17,18,18,18,19,19,19,19,20,20,20]
min G: [05,05,05,06,06,06,07,07,08,08,09,10,10,11,12,12,13,13,14,14,15,15,16,16,16,17,17,17,17,17,18,18]
max G: [13,13,13,13,13,14,14,14,14,14,14,15,15,15,16,16,17,17,17,18,18,18,19,19,19,20,20,20,20,20,20,20]
min B: [04,05,05,05,06,06,07,07,08,08,09,10,10,11,12,12,13,14,14,15,15,16,16,17,17,17,18,18,18,18,18,18]
max B: [05,05,06,06,07,07,08,08,09,09,10,11,11,12,13,13,14,15,15,16,16,17,17,17,18,18,18,19,19,19,19,19]
The red and blue channels could use lookup tables and only be off by +/- 1, but green needs more complex logic.
from rgbds.
I honestly think it's better to use "Modern – Accurate" rather than Harsh Reality in this context. Reversing the "Harsh Reality" color transformation would cause way too much color clipping due to the harshly reduced contrast.
from rgbds.
Okay, the GB_COLOR_CORRECTION_MODERN_ACCURATE
transformation looks easier to just invert, since it doesn't have the step where each channel gets lerped with 1/16th of the others. Although there's still the way that green depends on blue in the gamma-based formula. But if we ignore that, then it really is just the inverted scale_channel_with_curve
table which I've already implemented.
uint8_t r = (color) & 0x1F;
uint8_t g = (color >> 5) & 0x1F;
uint8_t b = (color >> 10) & 0x1F;
r = scale_channel_with_curve(r);
g = scale_channel_with_curve(g);
b = scale_channel_with_curve(b);
uint8_t new_r = r;
uint8_t new_g = g != b ? round(pow((pow(g / 255.0, 2.2) * 3 + pow(b / 255.0, 2.2)) / 4, 1 / 2.2) * 255) : g;
uint8_t new_b = b;
r = new_r;
g = new_g;
b = new_b;
Edit: inverting the gamma step:
g = pow((pow(new_g / 31, 2.2) * 4 - pow(new_b / 31, 2.2)) / 3, 1 / 2.2) * 31;
from rgbds.
Related Issues (20)
- [Feature request] `SIZEOF` and `STARTOF` for section types
- Early local labels sort relative to local ones in the current scope HOT 1
- Use libplum for RGBGFX HOT 7
- Add tests to improve code coverage HOT 2
- Check code with `clang-format` and/or `clang-tidy`, not checkpatch.pl
- `-Wtruncation=1` warns on -$100, -$10000, etc.
- Feature request: RGBGFX auto-named output to a different directory than input HOT 2
- Rename the RGBGFX `--output-*` options to `--auto-*` HOT 5
- Allow RGBGFX to output SNES attribute maps HOT 2
- [Feature request] Allow negative alignment offsets HOT 2
- [Feature request] `rgbgfx -r` should encode the reverse image appropriately HOT 2
- Rewrite the linkerscript parser to use Bison HOT 1
- Add generic Linux x86_64 binaries to old releases HOT 6
- Abbreviate `s.begin(), s.end()` with a `RANGE(x)` macro
- Warn or error if linker script `ALIGN` is out of range
- Allow specifying align offsets in a linker script
- Add tests to improve RGBLINK code coverage
- Warning/error function refactoring HOT 2
- Update dates in man pages
Recommend Projects
-
React
A declarative, efficient, and flexible JavaScript library for building user interfaces.
-
Vue.js
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
-
Typescript
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
-
TensorFlow
An Open Source Machine Learning Framework for Everyone
-
Django
The Web framework for perfectionists with deadlines.
-
Laravel
A PHP framework for web artisans
-
D3
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
-
Recommend Topics
-
javascript
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
-
web
Some thing interesting about web. New door for the world.
-
server
A server is a program made to process requests and deliver data to clients.
-
Machine learning
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
-
Visualization
Some thing interesting about visualization, use data art
-
Game
Some thing interesting about game, make everyone happy.
Recommend Org
-
Facebook
We are working to build community through open source technology. NB: members must have two-factor auth.
-
Microsoft
Open source projects and samples from Microsoft.
-
Google
Google ❤️ Open Source for everyone.
-
Alibaba
Alibaba Open Source for everyone
-
D3
Data-Driven Documents codes.
-
Tencent
China tencent open source team.
from rgbds.