1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
|
#include "video.h"
#include "main.h"
#include "plat.h"
static struct {
unsigned max_width;
unsigned max_height;
enum retro_pixel_format pixel_format;
uint16_t *buffer;
} screen_def;
static void video_alloc_convert_buffer(
unsigned new_width,
unsigned new_height,
enum retro_pixel_format new_format
) {
if (new_width == screen_def.max_width &&
new_height == screen_def.max_height &&
new_format == screen_def.pixel_format)
return;
if (screen_def.buffer) {
free(screen_def.buffer);
screen_def.buffer = NULL;
}
if ((new_width > 0 || new_height > 0) && new_format == RETRO_PIXEL_FORMAT_XRGB8888) {
screen_def.buffer = malloc(new_width * new_height * sizeof(uint16_t));
if (!screen_def.buffer)
PA_FATAL("Can't allocate buffer for color format conversion\n");
}
}
void video_set_geometry(struct retro_game_geometry *geometry) {
video_alloc_convert_buffer(geometry->max_width,
geometry->max_height,
screen_def.pixel_format);
screen_def.max_width = geometry->max_width;
screen_def.max_height = geometry->max_height;
}
void video_set_pixel_format(enum retro_pixel_format format) {
video_alloc_convert_buffer(screen_def.max_width,
screen_def.max_height,
format);
screen_def.pixel_format = format;
}
void video_process(const void *data, unsigned width, unsigned height, size_t pitch) {
const uint32_t *input = data;
uint16_t *output = screen_def.buffer;
size_t extra = pitch / sizeof(uint32_t) - width;
if (screen_def.pixel_format != RETRO_PIXEL_FORMAT_XRGB8888)
return plat_video_process(data, width, height, pitch);
for (int y = 0; y < height; y++) {
for (int x = 0; x < width; x++) {
*output = (*input & 0xF80000) >> 8;
*output |= (*input & 0xFC00) >> 5;
*output |= (*input & 0xF8) >> 3;
input++;
output++;
}
input += extra;
}
plat_video_process(screen_def.buffer, width, height, width * sizeof(uint16_t));
}
void video_deinit(void) {
free(screen_def.buffer);
screen_def.buffer = NULL;
}
|