Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
alexbevi
GitHub Repository: alexbevi/BizHawk
Path: blob/master/libsnes/bsnes/snes/system/video.cpp
2 views
1
#ifdef SYSTEM_CPP
2
3
Video video;
4
5
unsigned Video::palette30(unsigned color) {
6
unsigned l = (color >> 15) & 15;
7
unsigned b = (color >> 10) & 31;
8
unsigned g = (color >> 5) & 31;
9
unsigned r = (color >> 0) & 31;
10
11
double L = (1.0 + l) / 16.0;
12
if(l == 0) L *= 0.5;
13
unsigned R = L * ((r << 5) + (r << 0));
14
unsigned G = L * ((g << 5) + (g << 0));
15
unsigned B = L * ((b << 5) + (b << 0));
16
17
return (R << 20) + (G << 10) + (B << 0);
18
}
19
20
void Video::generate(Format format) {
21
for(unsigned n = 0; n < (1 << 19); n++) palette[n] = palette30(n);
22
23
if(format == Format::RGB24) {
24
for(unsigned n = 0; n < (1 << 19); n++) {
25
unsigned color = palette[n];
26
palette[n] = ((color >> 6) & 0xff0000) + ((color >> 4) & 0x00ff00) + ((color >> 2) & 0x0000ff);
27
}
28
}
29
30
if(format == Format::RGB16) {
31
for(unsigned n = 0; n < (1 << 19); n++) {
32
unsigned color = palette[n];
33
palette[n] = ((color >> 14) & 0xf800) + ((color >> 9) & 0x07e0) + ((color >> 5) & 0x001f);
34
}
35
}
36
37
if(format == Format::RGB15) {
38
for(unsigned n = 0; n < (1 << 19); n++) {
39
unsigned color = palette[n];
40
palette[n] = ((color >> 15) & 0x7c00) + ((color >> 10) & 0x03e0) + ((color >> 5) & 0x001f);
41
}
42
}
43
}
44
45
Video::Video() {
46
palette = new unsigned[1 << 19];
47
}
48
49
Video::~Video() {
50
delete[] palette;
51
}
52
53
//internal
54
55
const uint8_t Video::cursor[15 * 15] = {
56
0,0,0,0,0,0,1,1,1,0,0,0,0,0,0,
57
0,0,0,0,1,1,2,2,2,1,1,0,0,0,0,
58
0,0,0,1,2,2,1,2,1,2,2,1,0,0,0,
59
0,0,1,2,1,1,0,1,0,1,1,2,1,0,0,
60
0,1,2,1,0,0,0,1,0,0,0,1,2,1,0,
61
0,1,2,1,0,0,1,2,1,0,0,1,2,1,0,
62
1,2,1,0,0,1,1,2,1,1,0,0,1,2,1,
63
1,2,2,1,1,2,2,2,2,2,1,1,2,2,1,
64
1,2,1,0,0,1,1,2,1,1,0,0,1,2,1,
65
0,1,2,1,0,0,1,2,1,0,0,1,2,1,0,
66
0,1,2,1,0,0,0,1,0,0,0,1,2,1,0,
67
0,0,1,2,1,1,0,1,0,1,1,2,1,0,0,
68
0,0,0,1,2,2,1,2,1,2,2,1,0,0,0,
69
0,0,0,0,1,1,2,2,2,1,1,0,0,0,0,
70
0,0,0,0,0,0,1,1,1,0,0,0,0,0,0,
71
};
72
73
void Video::draw_cursor(uint16_t color, int x, int y) {
74
uint32_t *data = (uint32_t*)ppu.output;
75
if(ppu.interlace() && ppu.field()) data += 512;
76
77
for(int cy = 0; cy < 15; cy++) {
78
int vy = y + cy - 7;
79
if(vy <= 0 || vy >= 240) continue; //do not draw offscreen
80
81
bool hires = (line_width[vy] == 512);
82
for(int cx = 0; cx < 15; cx++) {
83
int vx = x + cx - 7;
84
if(vx < 0 || vx >= 256) continue; //do not draw offscreen
85
uint8_t pixel = cursor[cy * 15 + cx];
86
if(pixel == 0) continue;
87
uint32_t pixelcolor = (15 << 15) | ((pixel == 1) ? 0 : color);
88
89
if(hires == false) {
90
*((uint32_t*)data + vy * 1024 + vx) = pixelcolor;
91
} else {
92
*((uint32_t*)data + vy * 1024 + vx * 2 + 0) = pixelcolor;
93
*((uint32_t*)data + vy * 1024 + vx * 2 + 1) = pixelcolor;
94
}
95
}
96
}
97
}
98
99
void Video::update() {
100
switch(config.controller_port2) {
101
case Input::Device::SuperScope:
102
if(dynamic_cast<SuperScope*>(input.port2)) {
103
SuperScope &device = (SuperScope&)*input.port2;
104
draw_cursor(0x7c00, device.x, device.y);
105
}
106
break;
107
case Input::Device::Justifier:
108
case Input::Device::Justifiers:
109
if(dynamic_cast<Justifier*>(input.port2)) {
110
Justifier &device = (Justifier&)*input.port2;
111
draw_cursor(0x001f, device.player1.x, device.player1.y);
112
if(device.chained == false) break;
113
draw_cursor(0x02e0, device.player2.x, device.player2.y);
114
}
115
break;
116
}
117
118
uint32_t *data = (uint32_t*)ppu.output;
119
if(ppu.interlace() && ppu.field()) data += 512;
120
121
if(hires) {
122
//normalize line widths
123
for(unsigned y = 0; y < 240; y++) {
124
if(line_width[y] == 512) continue;
125
uint32_t *buffer = data + y * 1024;
126
for(signed x = 255; x >= 0; x--) {
127
buffer[(x * 2) + 0] = buffer[(x * 2) + 1] = buffer[x];
128
}
129
}
130
}
131
132
interface()->videoRefresh(ppu.surface, hires, ppu.interlace(), ppu.overscan());
133
134
hires = false;
135
}
136
137
void Video::scanline() {
138
unsigned y = cpu.vcounter();
139
if(y >= 240) return;
140
141
hires |= ppu.hires();
142
unsigned width = (ppu.hires() == false ? 256 : 512);
143
line_width[y] = width;
144
}
145
146
void Video::init() {
147
hires = false;
148
for(auto &n : line_width) n = 256;
149
}
150
151
#endif
152
153