Path: blob/master/libsnes/bsnes/snes/ppu/background/mode7.cpp
2 views
#ifdef PPU_CPP12signed PPU::Background::clip(signed n) {3//13-bit sign extend: --s---nnnnnnnnnn -> ssssssnnnnnnnnnn4return n & 0x2000 ? (n | ~1023) : (n & 1023);5}67//H = 608void PPU::Background::begin_mode7() {9cache.hoffset = self.regs.mode7_hoffset;10cache.voffset = self.regs.mode7_voffset;11}1213void PPU::Background::run_mode7() {14signed a = sclip<16>(self.regs.m7a);15signed b = sclip<16>(self.regs.m7b);16signed c = sclip<16>(self.regs.m7c);17signed d = sclip<16>(self.regs.m7d);1819signed cx = sclip<13>(self.regs.m7x);20signed cy = sclip<13>(self.regs.m7y);21signed hoffset = sclip<13>(cache.hoffset);22signed voffset = sclip<13>(cache.voffset);2324if(Background::x++ & ~255) return;25unsigned x = mosaic.hoffset;26unsigned y = self.bg1.mosaic.voffset; //BG2 vertical mosaic uses BG1 mosaic size2728if(--mosaic.hcounter == 0) {29mosaic.hcounter = regs.mosaic + 1;30mosaic.hoffset += regs.mosaic + 1;31}3233if(self.regs.mode7_hflip) x = 255 - x;34if(self.regs.mode7_vflip) y = 255 - y;3536signed psx = ((a * clip(hoffset - cx)) & ~63) + ((b * clip(voffset - cy)) & ~63) + ((b * y) & ~63) + (cx << 8);37signed psy = ((c * clip(hoffset - cx)) & ~63) + ((d * clip(voffset - cy)) & ~63) + ((d * y) & ~63) + (cy << 8);3839signed px = psx + (a * x);40signed py = psy + (c * x);4142//mask pseudo-FP bits43px >>= 8;44py >>= 8;4546unsigned tile;47unsigned palette;48switch(self.regs.mode7_repeat) {49//screen repetition outside of screen area50case 0:51case 1: {52px &= 1023;53py &= 1023;54tile = ppu.vram[((py >> 3) * 128 + (px >> 3)) << 1];55palette = ppu.vram[(((tile << 6) + ((py & 7) << 3) + (px & 7)) << 1) + 1];56break;57}5859//palette color 0 outside of screen area60case 2: {61if((px | py) & ~1023) {62palette = 0;63} else {64px &= 1023;65py &= 1023;66tile = ppu.vram[((py >> 3) * 128 + (px >> 3)) << 1];67palette = ppu.vram[(((tile << 6) + ((py & 7) << 3) + (px & 7)) << 1) + 1];68}69break;70}7172//character 0 repetition outside of screen area73case 3: {74if((px | py) & ~1023) {75tile = 0;76} else {77px &= 1023;78py &= 1023;79tile = ppu.vram[((py >> 3) * 128 + (px >> 3)) << 1];80}81palette = ppu.vram[(((tile << 6) + ((py & 7) << 3) + (px & 7)) << 1) + 1];82break;83}84}8586unsigned priority;87if(id == ID::BG1) {88priority = regs.priority0;89} else if(id == ID::BG2) {90priority = (palette & 0x80 ? regs.priority1 : regs.priority0);91palette &= 0x7f;92}9394if(palette == 0) return;9596if(regs.main_enable) {97output.main.palette = palette;98output.main.priority = priority;99output.main.tile = 0;100}101102if(regs.sub_enable) {103output.sub.palette = palette;104output.sub.priority = priority;105output.sub.tile = 0;106}107}108109#endif110111112