RetroArch/screenshot.c

135 lines
3.8 KiB
C
Raw Normal View History

2012-04-21 21:13:50 +00:00
/* RetroArch - A frontend for libretro.
2012-01-08 00:08:18 +00:00
* Copyright (C) 2010-2012 - Hans-Kristian Arntzen
2011-05-15 14:54:43 +00:00
*
2012-04-21 21:13:50 +00:00
* RetroArch is free software: you can redistribute it and/or modify it under the terms
2011-05-15 14:54:43 +00:00
* of the GNU General Public License as published by the Free Software Found-
* ation, either version 3 of the License, or (at your option) any later version.
*
2012-04-21 21:13:50 +00:00
* RetroArch is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
2011-05-15 14:54:43 +00:00
* without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
* PURPOSE. See the GNU General Public License for more details.
*
2012-04-21 21:31:57 +00:00
* You should have received a copy of the GNU General Public License along with RetroArch.
2011-05-15 14:54:43 +00:00
* If not, see <http://www.gnu.org/licenses/>.
*/
#include "screenshot.h"
2012-03-16 22:26:57 +00:00
#include "compat/strl.h"
2011-05-15 14:54:43 +00:00
#include <stdio.h>
#include <time.h>
2011-12-24 12:46:12 +00:00
#include "boolean.h"
2011-05-15 14:54:43 +00:00
#include <stdint.h>
#include <string.h>
#include "general.h"
// Simple 24bpp .BMP writer.
static void write_header(FILE *file, unsigned width, unsigned height)
{
unsigned line_size = (width * 3 + 3) & ~3;
unsigned size = line_size * height + 54;
unsigned size_array = line_size * height;
// Generic BMP stuff.
const uint8_t header[] = {
'B', 'M',
2011-12-24 12:46:12 +00:00
(uint8_t)(size >> 0), (uint8_t)(size >> 8), (uint8_t)(size >> 16), (uint8_t)(size >> 24),
2011-05-15 14:54:43 +00:00
0, 0, 0, 0,
54, 0, 0, 0,
40, 0, 0, 0,
2011-12-24 12:46:12 +00:00
(uint8_t)(width >> 0), (uint8_t)(width >> 8), (uint8_t)(width >> 16), (uint8_t)(width >> 24),
(uint8_t)(height >> 0), (uint8_t)(height >> 8), (uint8_t)(height >> 16), (uint8_t)(height >> 24),
2011-05-15 14:54:43 +00:00
1, 0,
24, 0,
0, 0, 0, 0,
2011-12-24 12:46:12 +00:00
(uint8_t)(size_array >> 0), (uint8_t)(size_array >> 8), (uint8_t)(size_array >> 16), (uint8_t)(size_array >> 24),
2011-05-15 14:54:43 +00:00
19, 11, 0, 0,
19, 11, 0, 0,
0, 0, 0, 0,
0, 0, 0, 0
};
fwrite(header, 1, sizeof(header), file);
}
static void dump_line_bgr(uint8_t *line, const uint8_t *src, unsigned width)
2011-05-15 14:54:43 +00:00
{
memcpy(line, src, width * 3);
}
static void dump_line_16(uint8_t *line, const uint16_t *src, unsigned width)
{
for (unsigned i = 0; i < width; i++)
{
uint16_t pixel = *src++;
uint8_t b = (pixel >> 0) & 0x1f;
uint8_t g = (pixel >> 5) & 0x1f;
uint8_t r = (pixel >> 10) & 0x1f;
*line++ = (b << 3) | (b >> 2);
*line++ = (g << 3) | (g >> 2);
*line++ = (r << 3) | (r >> 2);
}
}
static void dump_content(FILE *file, const void *frame,
int width, int height, int pitch, bool bgr24)
{
const uint8_t *frame_bgr = (const uint8_t*)frame;
const uint16_t *frame16 = (const uint16_t*)frame;
if (!bgr24)
pitch /= 2;
2011-05-15 14:54:43 +00:00
unsigned line_size = (width * 3 + 3) & ~3;
2011-12-24 12:46:12 +00:00
uint8_t *line = (uint8_t*)calloc(1, line_size);
if (!line)
return;
2011-05-15 14:54:43 +00:00
if (bgr24) // BGR24 byte order. Can directly copy.
2011-05-15 14:54:43 +00:00
{
for (int j = 0; j < height; j++, frame_bgr += pitch)
2011-05-15 14:54:43 +00:00
{
dump_line_bgr(line, frame_bgr, width);
fwrite(line, 1, line_size, file);
}
}
else // ARGB1555
{
for (int j = 0; j < height; j++, frame16 += pitch)
{
dump_line_16(line, frame16, width);
fwrite(line, 1, line_size, file);
2011-05-15 14:54:43 +00:00
}
}
2011-12-24 12:46:12 +00:00
free(line);
2011-05-15 14:54:43 +00:00
}
bool screenshot_dump(const char *folder, const void *frame,
unsigned width, unsigned height, int pitch, bool bgr24)
2011-05-15 14:54:43 +00:00
{
time_t cur_time;
time(&cur_time);
2011-05-19 20:51:23 +00:00
char timefmt[128];
strftime(timefmt, sizeof(timefmt), "RetroArch-%m%d-%H%M%S.bmp", localtime(&cur_time));
2011-05-15 14:54:43 +00:00
char filename[PATH_MAX];
snprintf(filename, sizeof(filename), "%s/%s", folder, timefmt);
2011-05-15 14:54:43 +00:00
FILE *file = fopen(filename, "wb");
if (!file)
{
2012-04-21 21:25:32 +00:00
RARCH_ERR("Failed to open file \"%s\" for screenshot.\n", filename);
2011-05-15 14:54:43 +00:00
return false;
}
write_header(file, width, height);
dump_content(file, frame, width, height, pitch, bgr24);
2011-05-15 14:54:43 +00:00
fclose(file);
return true;
}