kopia lustrzana https://github.com/hoglet67/RGBtoHDMI
Add 16BPP screen capture
rodzic
03709bbb80
commit
a6764f1332
138
src/filesystem.c
138
src/filesystem.c
|
@ -32,11 +32,28 @@ static int generate_png(capture_info_t *capinfo, uint8_t **png, unsigned int *pn
|
||||||
|
|
||||||
LodePNGState state;
|
LodePNGState state;
|
||||||
lodepng_state_init(&state);
|
lodepng_state_init(&state);
|
||||||
state.info_raw.colortype = LCT_PALETTE;
|
if (capinfo->bpp < 16) {
|
||||||
state.info_raw.bitdepth = 8;
|
state.info_raw.colortype = LCT_PALETTE;
|
||||||
state.info_png.color.colortype = LCT_PALETTE;
|
state.info_raw.bitdepth = 8;
|
||||||
state.info_png.color.bitdepth = 8;
|
state.info_png.color.colortype = LCT_PALETTE;
|
||||||
|
state.info_png.color.bitdepth = 8;
|
||||||
|
for (int i = 0; i < (1 << capinfo->bpp); i++) {
|
||||||
|
int triplet = osd_get_palette(i);
|
||||||
|
int r = triplet & 0xff;
|
||||||
|
int g = (triplet >> 8) & 0xff;
|
||||||
|
int b = (triplet >> 16) & 0xff;
|
||||||
|
lodepng_palette_add(&state.info_png.color, r, g, b, 255);
|
||||||
|
lodepng_palette_add(&state.info_raw, r, g, b, 255);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
state.info_raw.colortype = LCT_RGB;
|
||||||
|
state.info_raw.bitdepth = 8;
|
||||||
|
state.info_png.color.colortype = LCT_RGB;
|
||||||
|
state.info_png.color.bitdepth = 8;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
int width = capinfo->width;
|
int width = capinfo->width;
|
||||||
int width43 = width;
|
int width43 = width;
|
||||||
int height = capinfo->height;
|
int height = capinfo->height;
|
||||||
|
@ -57,14 +74,7 @@ static int generate_png(capture_info_t *capinfo, uint8_t **png, unsigned int *pn
|
||||||
int leftclip = (width - width43) / 2;
|
int leftclip = (width - width43) / 2;
|
||||||
int rightclip = leftclip + width43;
|
int rightclip = leftclip + width43;
|
||||||
|
|
||||||
for (int i = 0; i < (1 << capinfo->bpp); i++) {
|
|
||||||
int triplet = osd_get_palette(i);
|
|
||||||
int r = triplet & 0xff;
|
|
||||||
int g = (triplet >> 8) & 0xff;
|
|
||||||
int b = (triplet >> 16) & 0xff;
|
|
||||||
lodepng_palette_add(&state.info_png.color, r, g, b, 255);
|
|
||||||
lodepng_palette_add(&state.info_raw, r, g, b, 255);
|
|
||||||
}
|
|
||||||
|
|
||||||
int hscale = get_hscale();
|
int hscale = get_hscale();
|
||||||
int vscale = get_vscale();
|
int vscale = get_vscale();
|
||||||
|
@ -84,39 +94,65 @@ static int generate_png(capture_info_t *capinfo, uint8_t **png, unsigned int *pn
|
||||||
width43 = (width >> hdouble) << hdouble;
|
width43 = (width >> hdouble) << hdouble;
|
||||||
height = (height >> vdouble) << vdouble;
|
height = (height >> vdouble) << vdouble;
|
||||||
|
|
||||||
uint8_t png_buffer[png_width * png_height];
|
|
||||||
uint8_t *pp = png_buffer;
|
|
||||||
|
|
||||||
if (capinfo->bpp == 8) {
|
if (capinfo->bpp == 16) {
|
||||||
for (int y = 0; y < height; y += (vdouble + 1)) {
|
uint8_t png_buffer[png_width*3 * png_height];
|
||||||
for (int sy = 0; sy < vscale; sy++) {
|
uint8_t *pp = png_buffer;
|
||||||
uint8_t *fp = capinfo->fb + capinfo->pitch * y;
|
for (int y = 0; y < height; y += (vdouble + 1)) {
|
||||||
for (int x = 0; x < width; x += (hdouble + 1)) {
|
for (int sy = 0; sy < vscale; sy++) {
|
||||||
uint8_t single_pixel = *fp++;
|
uint8_t *fp = capinfo->fb + capinfo->pitch * y;
|
||||||
if (hdouble) fp++;
|
for (int x = 0; x < width; x += (hdouble + 1)) {
|
||||||
if (x >= leftclip && x < rightclip) {
|
uint8_t single_pixel_lo = *fp++;
|
||||||
for (int sx = 0; sx < hscale; sx++) {
|
uint8_t single_pixel_hi = *fp++;
|
||||||
*pp++ = single_pixel;
|
int single_pixel = single_pixel_lo | (single_pixel_hi << 8);
|
||||||
|
uint8_t single_pixel_R = single_pixel >> 12;
|
||||||
|
uint8_t single_pixel_G = (single_pixel >> 7) & 0x0f;
|
||||||
|
uint8_t single_pixel_B = (single_pixel >> 1) & 0x0f;
|
||||||
|
single_pixel_R |= (single_pixel_R << 4);
|
||||||
|
single_pixel_G |= (single_pixel_G << 4);
|
||||||
|
single_pixel_B |= (single_pixel_B << 4);
|
||||||
|
if (hdouble) fp += 2;
|
||||||
|
if (x >= leftclip && x < rightclip) {
|
||||||
|
for (int sx = 0; sx < hscale; sx++) {
|
||||||
|
*pp++ = single_pixel_R;
|
||||||
|
*pp++ = single_pixel_G;
|
||||||
|
*pp++ = single_pixel_B;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
unsigned int result = lodepng_encode(png, png_len, png_buffer, png_width, png_height, &state);
|
||||||
|
if (result) {
|
||||||
|
log_warn("lodepng_encode32 failed (result = %d)", result);
|
||||||
|
return 1;
|
||||||
}
|
}
|
||||||
|
return 0;
|
||||||
} else {
|
} else {
|
||||||
for (int y = 0; y < height; y += (vdouble + 1)) {
|
uint8_t png_buffer[png_width * png_height];
|
||||||
for (int sy = 0; sy < vscale; sy++) {
|
uint8_t *pp = png_buffer;
|
||||||
uint8_t *fp = capinfo->fb + capinfo->pitch * y;
|
if (capinfo->bpp == 8) {
|
||||||
uint8_t single_pixel = 0;
|
for (int y = 0; y < height; y += (vdouble + 1)) {
|
||||||
for (int x = 0; x < width; x += (hdouble + 1)) {
|
for (int sy = 0; sy < vscale; sy++) {
|
||||||
if (hdouble) {
|
uint8_t *fp = capinfo->fb + capinfo->pitch * y;
|
||||||
single_pixel = *fp++;
|
for (int x = 0; x < width; x += (hdouble + 1)) {
|
||||||
|
uint8_t single_pixel = *fp++;
|
||||||
|
if (hdouble) fp++;
|
||||||
if (x >= leftclip && x < rightclip) {
|
if (x >= leftclip && x < rightclip) {
|
||||||
for (int sx = 0; sx < hscale; sx++) {
|
for (int sx = 0; sx < hscale; sx++) {
|
||||||
*pp++ = single_pixel >> 4;
|
*pp++ = single_pixel;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else {
|
}
|
||||||
if ((x & 1) == 0) {
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
for (int y = 0; y < height; y += (vdouble + 1)) {
|
||||||
|
for (int sy = 0; sy < vscale; sy++) {
|
||||||
|
uint8_t *fp = capinfo->fb + capinfo->pitch * y;
|
||||||
|
uint8_t single_pixel = 0;
|
||||||
|
for (int x = 0; x < width; x += (hdouble + 1)) {
|
||||||
|
if (hdouble) {
|
||||||
single_pixel = *fp++;
|
single_pixel = *fp++;
|
||||||
if (x >= leftclip && x < rightclip) {
|
if (x >= leftclip && x < rightclip) {
|
||||||
for (int sx = 0; sx < hscale; sx++) {
|
for (int sx = 0; sx < hscale; sx++) {
|
||||||
|
@ -124,23 +160,33 @@ static int generate_png(capture_info_t *capinfo, uint8_t **png, unsigned int *pn
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
if (x >= leftclip && x < rightclip) {
|
if ((x & 1) == 0) {
|
||||||
for (int sx = 0; sx < hscale; sx++) {
|
single_pixel = *fp++;
|
||||||
*pp++ = single_pixel & 0x0f;
|
if (x >= leftclip && x < rightclip) {
|
||||||
|
for (int sx = 0; sx < hscale; sx++) {
|
||||||
|
*pp++ = single_pixel >> 4;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if (x >= leftclip && x < rightclip) {
|
||||||
|
for (int sx = 0; sx < hscale; sx++) {
|
||||||
|
*pp++ = single_pixel & 0x0f;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
unsigned int result = lodepng_encode(png, png_len, png_buffer, png_width, png_height, &state);
|
||||||
|
if (result) {
|
||||||
|
log_warn("lodepng_encode32 failed (result = %d)", result);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
}
|
}
|
||||||
unsigned int result = lodepng_encode(png, png_len, png_buffer, png_width, png_height, &state);
|
|
||||||
if (result) {
|
|
||||||
log_warn("lodepng_encode32 failed (result = %d)", result);
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
return 0;
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
13
src/osd.c
13
src/osd.c
|
@ -65,9 +65,10 @@ typedef enum {
|
||||||
A7_SPARE, // Action 7: Spare
|
A7_SPARE, // Action 7: Spare
|
||||||
|
|
||||||
MAX_ACTION, // Marker state, never actually used
|
MAX_ACTION, // Marker state, never actually used
|
||||||
|
A1_CAPTURE_SUB, // Action 1: Screen capture
|
||||||
CLOCK_CAL0, // Intermediate state in clock calibration
|
CLOCK_CAL0, // Intermediate state in clock calibration
|
||||||
CLOCK_CAL1, // Intermediate state in clock calibration
|
CLOCK_CAL1, // Intermediate state in clock calibration
|
||||||
|
|
||||||
NTSC_MESSAGE,
|
NTSC_MESSAGE,
|
||||||
MENU, // Browsing a menu
|
MENU, // Browsing a menu
|
||||||
PARAM, // Changing the value of a menu item
|
PARAM, // Changing the value of a menu item
|
||||||
|
@ -3551,6 +3552,12 @@ int osd_key(int key) {
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case A1_CAPTURE:
|
case A1_CAPTURE:
|
||||||
|
// Capture screen shot
|
||||||
|
ret = 4;
|
||||||
|
osd_state = A1_CAPTURE_SUB;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case A1_CAPTURE_SUB:
|
||||||
// Capture screen shot
|
// Capture screen shot
|
||||||
osd_clear();
|
osd_clear();
|
||||||
capture_screenshot(capinfo, profile_names[get_feature(F_PROFILE)]);
|
capture_screenshot(capinfo, profile_names[get_feature(F_PROFILE)]);
|
||||||
|
@ -4338,8 +4345,8 @@ void osd_update(uint32_t *osd_base, int bytes_per_line) {
|
||||||
if (capinfo->bpp == 16) {
|
if (capinfo->bpp == 16) {
|
||||||
if (capinfo->video_type == VIDEO_INTERLACED && (capinfo->sync_type & SYNC_BIT_INTERLACED) && get_deinterlace() == DEINTERLACE_NONE) {
|
if (capinfo->video_type == VIDEO_INTERLACED && (capinfo->sync_type & SYNC_BIT_INTERLACED) && get_deinterlace() == DEINTERLACE_NONE) {
|
||||||
clear_full_screen();
|
clear_full_screen();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// SAA5050 character data is 12x20
|
// SAA5050 character data is 12x20
|
||||||
int bufferCharWidth = (capinfo->chars_per_line << 3) / 12; // SAA5050 character data is 12x20
|
int bufferCharWidth = (capinfo->chars_per_line << 3) / 12; // SAA5050 character data is 12x20
|
||||||
|
|
Ładowanie…
Reference in New Issue