Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
alexbevi
GitHub Repository: alexbevi/BizHawk
Path: blob/master/libsnes/bsnes/snes/alt/ppu-compatibility/render/mode7.cpp
2 views
1
#ifdef PPU_CPP
2
3
//bsnes mode7 renderer
4
//
5
//base algorithm written by anomie
6
//bsnes implementation written by byuu
7
//
8
//supports mode 7 + extbg + rotate + zoom + direct color + scrolling + m7sel + windowing + mosaic
9
//interlace and pseudo-hires support are automatic via main rendering routine
10
11
//13-bit sign extend
12
//--s---vvvvvvvvvv -> ssssssvvvvvvvvvv
13
#define CLIP(x) ( ((x) & 0x2000) ? ( (x) | ~0x03ff) : ((x) & 0x03ff) )
14
15
template<unsigned bg>
16
void PPU::render_line_mode7(uint8 pri0_pos, uint8 pri1_pos) {
17
if(layer_enabled[bg][0] == false) pri0_pos = 0;
18
if(layer_enabled[bg][1] == false) pri1_pos = 0;
19
if(pri0_pos + pri1_pos == 0) return;
20
21
if(regs.bg_enabled[bg] == false && regs.bgsub_enabled[bg] == false) return;
22
23
int32 px, py;
24
int32 tx, ty, tile, palette;
25
26
int32 a = sclip<16>(cache.m7a);
27
int32 b = sclip<16>(cache.m7b);
28
int32 c = sclip<16>(cache.m7c);
29
int32 d = sclip<16>(cache.m7d);
30
31
int32 cx = sclip<13>(cache.m7x);
32
int32 cy = sclip<13>(cache.m7y);
33
int32 hofs = sclip<13>(cache.m7_hofs);
34
int32 vofs = sclip<13>(cache.m7_vofs);
35
36
int _pri, _x;
37
bool _bg_enabled = regs.bg_enabled[bg];
38
bool _bgsub_enabled = regs.bgsub_enabled[bg];
39
40
build_window_tables(bg);
41
uint8 *wt_main = window[bg].main;
42
uint8 *wt_sub = window[bg].sub;
43
44
int32 y = (regs.mode7_vflip == false ? line : 255 - line);
45
46
uint16 *mtable_x, *mtable_y;
47
if(bg == BG1) {
48
mtable_x = (uint16*)mosaic_table[(regs.mosaic_enabled[BG1] == true) ? regs.mosaic_size : 0];
49
mtable_y = (uint16*)mosaic_table[(regs.mosaic_enabled[BG1] == true) ? regs.mosaic_size : 0];
50
} else { //bg == BG2
51
//Mode7 EXTBG BG2 uses BG1 mosaic enable to control vertical mosaic,
52
//and BG2 mosaic enable to control horizontal mosaic...
53
mtable_x = (uint16*)mosaic_table[(regs.mosaic_enabled[BG2] == true) ? regs.mosaic_size : 0];
54
mtable_y = (uint16*)mosaic_table[(regs.mosaic_enabled[BG1] == true) ? regs.mosaic_size : 0];
55
}
56
57
int32 psx = ((a * CLIP(hofs - cx)) & ~63) + ((b * CLIP(vofs - cy)) & ~63) + ((b * mtable_y[y]) & ~63) + (cx << 8);
58
int32 psy = ((c * CLIP(hofs - cx)) & ~63) + ((d * CLIP(vofs - cy)) & ~63) + ((d * mtable_y[y]) & ~63) + (cy << 8);
59
for(int32 x = 0; x < 256; x++) {
60
px = psx + (a * mtable_x[x]);
61
py = psy + (c * mtable_x[x]);
62
63
//mask floating-point bits (low 8 bits)
64
px >>= 8;
65
py >>= 8;
66
67
switch(regs.mode7_repeat) {
68
case 0: //screen repetition outside of screen area
69
case 1: { //same as case 0
70
px &= 1023;
71
py &= 1023;
72
tx = ((px >> 3) & 127);
73
ty = ((py >> 3) & 127);
74
tile = vram[(ty * 128 + tx) << 1];
75
palette = vram[(((tile << 6) + ((py & 7) << 3) + (px & 7)) << 1) + 1];
76
} break;
77
case 2: { //palette color 0 outside of screen area
78
if((px | py) & ~1023) {
79
palette = 0;
80
} else {
81
px &= 1023;
82
py &= 1023;
83
tx = ((px >> 3) & 127);
84
ty = ((py >> 3) & 127);
85
tile = vram[(ty * 128 + tx) << 1];
86
palette = vram[(((tile << 6) + ((py & 7) << 3) + (px & 7)) << 1) + 1];
87
}
88
} break;
89
case 3: { //character 0 repetition outside of screen area
90
if((px | py) & ~1023) {
91
tile = 0;
92
} else {
93
px &= 1023;
94
py &= 1023;
95
tx = ((px >> 3) & 127);
96
ty = ((py >> 3) & 127);
97
tile = vram[(ty * 128 + tx) << 1];
98
}
99
palette = vram[(((tile << 6) + ((py & 7) << 3) + (px & 7)) << 1) + 1];
100
} break;
101
}
102
103
if(bg == BG1) {
104
_pri = pri0_pos;
105
} else {
106
_pri = (palette >> 7) ? pri1_pos : pri0_pos;
107
palette &= 0x7f;
108
}
109
110
if(!palette) continue;
111
112
_x = (regs.mode7_hflip == false) ? (x) : (255 - x);
113
114
uint32 col;
115
if(regs.direct_color == true && bg == BG1) {
116
//direct color mode does not apply to bg2, as it is only 128 colors...
117
col = get_direct_color(0, palette);
118
} else {
119
col = get_palette(palette);
120
}
121
122
if(regs.bg_enabled[bg] == true && !wt_main[_x]) {
123
if(pixel_cache[_x].pri_main < _pri) {
124
pixel_cache[_x].pri_main = _pri;
125
pixel_cache[_x].bg_main = bg;
126
pixel_cache[_x].src_main = col;
127
pixel_cache[_x].ce_main = false;
128
}
129
}
130
if(regs.bgsub_enabled[bg] == true && !wt_sub[_x]) {
131
if(pixel_cache[_x].pri_sub < _pri) {
132
pixel_cache[_x].pri_sub = _pri;
133
pixel_cache[_x].bg_sub = bg;
134
pixel_cache[_x].src_sub = col;
135
pixel_cache[_x].ce_sub = false;
136
}
137
}
138
}
139
}
140
141
#undef CLIP
142
143
#endif
144
145