mirror of https://github.com/bsnes-emu/bsnes.git
103 lines
3.0 KiB
C++
103 lines
3.0 KiB
C++
#define Clip(x) (((x) & 0x2000) ? ((x) | ~0x03ff) : ((x) & 0x03ff))
|
|
|
|
auto PPU::Background::render_mode7() -> void {
|
|
int px, py;
|
|
int tx, ty, tile, palette;
|
|
|
|
int a = sclip<16>(self.regs.m7a);
|
|
int b = sclip<16>(self.regs.m7b);
|
|
int c = sclip<16>(self.regs.m7c);
|
|
int d = sclip<16>(self.regs.m7d);
|
|
|
|
int cx = sclip<13>(self.regs.m7x);
|
|
int cy = sclip<13>(self.regs.m7y);
|
|
int hofs = sclip<13>(self.regs.mode7_hoffset);
|
|
int vofs = sclip<13>(self.regs.mode7_voffset);
|
|
|
|
int y = (self.regs.mode7_vflip == false ? self.vcounter() : 255 - self.vcounter());
|
|
|
|
uint16* mosaic_x;
|
|
uint16* mosaic_y;
|
|
if(id == ID::BG1) {
|
|
mosaic_x = mosaic_table[self.bg1.regs.mosaic];
|
|
mosaic_y = mosaic_table[self.bg1.regs.mosaic];
|
|
} else {
|
|
mosaic_x = mosaic_table[self.bg2.regs.mosaic];
|
|
mosaic_y = mosaic_table[self.bg1.regs.mosaic];
|
|
}
|
|
|
|
uint priority0 = (priority0_enable ? regs.priority0 : 0);
|
|
uint priority1 = (priority1_enable ? regs.priority1 : 0);
|
|
if(priority0 + priority1 == 0) return;
|
|
|
|
int psx = ((a * Clip(hofs - cx)) & ~63) + ((b * Clip(vofs - cy)) & ~63) + ((b * mosaic_y[y]) & ~63) + (cx << 8);
|
|
int psy = ((c * Clip(hofs - cx)) & ~63) + ((d * Clip(vofs - cy)) & ~63) + ((d * mosaic_y[y]) & ~63) + (cy << 8);
|
|
for(int x = 0; x < 256; x++) {
|
|
px = (psx + (a * mosaic_x[x])) >> 8;
|
|
py = (psy + (c * mosaic_x[x])) >> 8;
|
|
|
|
switch(self.regs.mode7_repeat) {
|
|
case 0: case 1: {
|
|
px &= 1023;
|
|
py &= 1023;
|
|
tx = ((px >> 3) & 127);
|
|
ty = ((py >> 3) & 127);
|
|
tile = ppu.vram[(ty * 128 + tx) << 1];
|
|
palette = ppu.vram[(((tile << 6) + ((py & 7) << 3) + (px & 7)) << 1) + 1];
|
|
break;
|
|
}
|
|
|
|
case 2: {
|
|
if((px | py) & ~1023) {
|
|
palette = 0;
|
|
} else {
|
|
px &= 1023;
|
|
py &= 1023;
|
|
tx = ((px >> 3) & 127);
|
|
ty = ((py >> 3) & 127);
|
|
tile = ppu.vram[(ty * 128 + tx) << 1];
|
|
palette = ppu.vram[(((tile << 6) + ((py & 7) << 3) + (px & 7)) << 1) + 1];
|
|
}
|
|
break;
|
|
}
|
|
|
|
case 3: {
|
|
if((px | py) & ~1023) {
|
|
tile = 0;
|
|
} else {
|
|
px &= 1023;
|
|
py &= 1023;
|
|
tx = ((px >> 3) & 127);
|
|
ty = ((py >> 3) & 127);
|
|
tile = ppu.vram[(ty * 128 + tx) << 1];
|
|
}
|
|
palette = ppu.vram[(((tile << 6) + ((py & 7) << 3) + (px & 7)) << 1) + 1];
|
|
break;
|
|
}
|
|
}
|
|
|
|
uint priority;
|
|
if(id == ID::BG1) {
|
|
priority = priority0;
|
|
} else {
|
|
priority = (palette & 0x80 ? priority1 : priority0);
|
|
palette &= 0x7f;
|
|
}
|
|
|
|
if(palette == 0) continue;
|
|
uint plot_x = (self.regs.mode7_hflip == false ? x : 255 - x);
|
|
|
|
uint color;
|
|
if(self.screen.regs.direct_color && id == ID::BG1) {
|
|
color = self.screen.get_direct_color(0, palette);
|
|
} else {
|
|
color = self.screen.get_palette(palette);
|
|
}
|
|
|
|
if(regs.main_enable && !window.main[plot_x]) self.screen.output.plot_main(plot_x, color, priority, id);
|
|
if(regs.sub_enable && !window.sub[plot_x]) self.screen.output.plot_sub(plot_x, color, priority, id);
|
|
}
|
|
}
|
|
|
|
#undef Clip
|