Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
alexbevi
GitHub Repository: alexbevi/BizHawk
Path: blob/master/libsnes/bsnes/snes/ppu/background/mode7.cpp
2 views
1
#ifdef PPU_CPP
2
3
signed PPU::Background::clip(signed n) {
4
//13-bit sign extend: --s---nnnnnnnnnn -> ssssssnnnnnnnnnn
5
return n & 0x2000 ? (n | ~1023) : (n & 1023);
6
}
7
8
//H = 60
9
void PPU::Background::begin_mode7() {
10
cache.hoffset = self.regs.mode7_hoffset;
11
cache.voffset = self.regs.mode7_voffset;
12
}
13
14
void PPU::Background::run_mode7() {
15
signed a = sclip<16>(self.regs.m7a);
16
signed b = sclip<16>(self.regs.m7b);
17
signed c = sclip<16>(self.regs.m7c);
18
signed d = sclip<16>(self.regs.m7d);
19
20
signed cx = sclip<13>(self.regs.m7x);
21
signed cy = sclip<13>(self.regs.m7y);
22
signed hoffset = sclip<13>(cache.hoffset);
23
signed voffset = sclip<13>(cache.voffset);
24
25
if(Background::x++ & ~255) return;
26
unsigned x = mosaic.hoffset;
27
unsigned y = self.bg1.mosaic.voffset; //BG2 vertical mosaic uses BG1 mosaic size
28
29
if(--mosaic.hcounter == 0) {
30
mosaic.hcounter = regs.mosaic + 1;
31
mosaic.hoffset += regs.mosaic + 1;
32
}
33
34
if(self.regs.mode7_hflip) x = 255 - x;
35
if(self.regs.mode7_vflip) y = 255 - y;
36
37
signed psx = ((a * clip(hoffset - cx)) & ~63) + ((b * clip(voffset - cy)) & ~63) + ((b * y) & ~63) + (cx << 8);
38
signed psy = ((c * clip(hoffset - cx)) & ~63) + ((d * clip(voffset - cy)) & ~63) + ((d * y) & ~63) + (cy << 8);
39
40
signed px = psx + (a * x);
41
signed py = psy + (c * x);
42
43
//mask pseudo-FP bits
44
px >>= 8;
45
py >>= 8;
46
47
unsigned tile;
48
unsigned palette;
49
switch(self.regs.mode7_repeat) {
50
//screen repetition outside of screen area
51
case 0:
52
case 1: {
53
px &= 1023;
54
py &= 1023;
55
tile = ppu.vram[((py >> 3) * 128 + (px >> 3)) << 1];
56
palette = ppu.vram[(((tile << 6) + ((py & 7) << 3) + (px & 7)) << 1) + 1];
57
break;
58
}
59
60
//palette color 0 outside of screen area
61
case 2: {
62
if((px | py) & ~1023) {
63
palette = 0;
64
} else {
65
px &= 1023;
66
py &= 1023;
67
tile = ppu.vram[((py >> 3) * 128 + (px >> 3)) << 1];
68
palette = ppu.vram[(((tile << 6) + ((py & 7) << 3) + (px & 7)) << 1) + 1];
69
}
70
break;
71
}
72
73
//character 0 repetition outside of screen area
74
case 3: {
75
if((px | py) & ~1023) {
76
tile = 0;
77
} else {
78
px &= 1023;
79
py &= 1023;
80
tile = ppu.vram[((py >> 3) * 128 + (px >> 3)) << 1];
81
}
82
palette = ppu.vram[(((tile << 6) + ((py & 7) << 3) + (px & 7)) << 1) + 1];
83
break;
84
}
85
}
86
87
unsigned priority;
88
if(id == ID::BG1) {
89
priority = regs.priority0;
90
} else if(id == ID::BG2) {
91
priority = (palette & 0x80 ? regs.priority1 : regs.priority0);
92
palette &= 0x7f;
93
}
94
95
if(palette == 0) return;
96
97
if(regs.main_enable) {
98
output.main.palette = palette;
99
output.main.priority = priority;
100
output.main.tile = 0;
101
}
102
103
if(regs.sub_enable) {
104
output.sub.palette = palette;
105
output.sub.priority = priority;
106
output.sub.tile = 0;
107
}
108
}
109
110
#endif
111
112