Path: blob/master/libsnes/bsnes/snes/alt/ppu-performance/screen/screen.cpp
2 views
#ifdef PPU_CPP12unsigned PPU::Screen::get_palette(unsigned color) {3#if defined(ARCH_LSB)4return ((uint16*)ppu.cgram)[color];5#else6color <<= 1;7return (ppu.cgram[color + 0] << 0) + (ppu.cgram[color + 1] << 8);8#endif9}1011unsigned PPU::Screen::get_direct_color(unsigned p, unsigned t) {12return ((t & 7) << 2) | ((p & 1) << 1) |13(((t >> 3) & 7) << 7) | (((p >> 1) & 1) << 6) |14((t >> 6) << 13) | ((p >> 2) << 12);15}1617uint16 PPU::Screen::addsub(unsigned x, unsigned y, bool halve) {18if(!regs.color_mode) {19if(!halve) {20unsigned sum = x + y;21unsigned carry = (sum - ((x ^ y) & 0x0421)) & 0x8420;22return (sum - carry) | (carry - (carry >> 5));23} else {24return (x + y - ((x ^ y) & 0x0421)) >> 1;25}26} else {27unsigned diff = x - y + 0x8420;28unsigned borrow = (diff - ((x ^ y) & 0x8420)) & 0x8420;29if(!halve) {30return (diff - borrow) & (borrow - (borrow >> 5));31} else {32return (((diff - borrow) & (borrow - (borrow >> 5))) & 0x7bde) >> 1;33}34}35}3637void PPU::Screen::scanline() {38unsigned main_color = get_palette(0);39unsigned sub_color = (self.regs.pseudo_hires == false && self.regs.bgmode != 5 && self.regs.bgmode != 6)40? regs.color : main_color;4142for(unsigned x = 0; x < 256; x++) {43output.main[x].color = main_color;44output.main[x].priority = 0;45output.main[x].source = 6;4647output.sub[x].color = sub_color;48output.sub[x].priority = 0;49output.sub[x].source = 6;50}5152window.render(0);53window.render(1);54}5556void PPU::Screen::render_black() {57uint32 *data = self.output + self.vcounter() * 1024;58if(self.interlace() && self.field()) data += 512;59memset(data, 0, self.display.width << 2);60}6162uint16 PPU::Screen::get_pixel_main(unsigned x) {63auto main = output.main[x];64auto sub = output.sub[x];6566if(!regs.addsub_mode) {67sub.source = 6;68sub.color = regs.color;69}7071if(!window.main[x]) {72if(!window.sub[x]) {73return 0x0000;74}75main.color = 0x0000;76}7778if(main.source != 5 && regs.color_enable[main.source] && window.sub[x]) {79bool halve = false;80if(regs.color_halve && window.main[x]) {81if(!regs.addsub_mode || sub.source != 6) halve = true;82}83return addsub(main.color, sub.color, halve);84}8586return main.color;87}8889uint16 PPU::Screen::get_pixel_sub(unsigned x) {90auto main = output.sub[x];91auto sub = output.main[x];9293if(!regs.addsub_mode) {94sub.source = 6;95sub.color = regs.color;96}9798if(!window.main[x]) {99if(!window.sub[x]) {100return 0x0000;101}102main.color = 0x0000;103}104105if(main.source != 5 && regs.color_enable[main.source] && window.sub[x]) {106bool halve = false;107if(regs.color_halve && window.main[x]) {108if(!regs.addsub_mode || sub.source != 6) halve = true;109}110return addsub(main.color, sub.color, halve);111}112113return main.color;114}115116void PPU::Screen::render() {117uint32 *data = self.output + self.vcounter() * 1024;118if(self.interlace() && self.field()) data += 512;119120if(!self.regs.pseudo_hires && self.regs.bgmode != 5 && self.regs.bgmode != 6) {121for(unsigned i = 0; i < 256; i++) {122data[i] = (self.regs.display_brightness << 15) | get_pixel_main(i);123}124} else {125for(unsigned i = 0; i < 256; i++) {126*data++ = (self.regs.display_brightness << 15) | get_pixel_sub(i);127*data++ = (self.regs.display_brightness << 15) | get_pixel_main(i);128}129}130}131132PPU::Screen::Screen(PPU &self) : self(self) {133}134135PPU::Screen::~Screen() {136}137138void PPU::Screen::Output::plot_main(unsigned x, unsigned color, unsigned priority, unsigned source) {139if(priority > main[x].priority) {140main[x].color = color;141main[x].priority = priority;142main[x].source = source;143}144}145146void PPU::Screen::Output::plot_sub(unsigned x, unsigned color, unsigned priority, unsigned source) {147if(priority > sub[x].priority) {148sub[x].color = color;149sub[x].priority = priority;150sub[x].source = source;151}152}153154#endif155156157