diff --git a/bsnes.exe b/bsnes.exe index e74488f3..1fe6a58a 100644 Binary files a/bsnes.exe and b/bsnes.exe differ diff --git a/src/cpu/bcpu/bcpu.cpp b/src/cpu/bcpu/bcpu.cpp index 2ce1cc9c..3d92c2aa 100644 --- a/src/cpu/bcpu/bcpu.cpp +++ b/src/cpu/bcpu/bcpu.cpp @@ -28,29 +28,18 @@ void bCPU::run() { return; } - if(run_state.irq) { - irq_run(); - return; - } - - if(run_state.stp) { - exec_cycle(); - return; - } - if(status.cycle_pos == 0) { //interrupts only trigger on opcode edges - if(time.nmi_pending == true) { - time.nmi_pending = false; - aa.w = 0xffea; - run_state.irq = true; - return; - } - if(time.irq_pending == true) { - time.irq_pending = false; - aa.w = 0xffee; - run_state.irq = true; - return; + if(!run_state.irq && !run_state.stp) { + if(time.nmi_pending == true) { + time.nmi_pending = false; + aa.w = 0xffea; + run_state.irq = true; + } else if(time.irq_pending == true) { + time.irq_pending = false; + aa.w = 0xffee; + run_state.irq = true; + } } } diff --git a/src/cpu/bcpu/bcpu_exec.cpp b/src/cpu/bcpu/bcpu_exec.cpp index 8a242245..e0eb9b40 100644 --- a/src/cpu/bcpu/bcpu_exec.cpp +++ b/src/cpu/bcpu/bcpu_exec.cpp @@ -141,6 +141,12 @@ static int z; } void bCPU::exec_cycle() { +//irq active? run one bus cycle of the irq event and return + if(run_state.irq) { + irq_run(); + return; + } + //on first cycle? if(status.cycle_pos == 0) { snes->notify(SNES::CPU_EXEC_OPCODE_BEGIN); diff --git a/src/interface.h b/src/interface.h index e25ba73f..b8729189 100644 --- a/src/interface.h +++ b/src/interface.h @@ -1,4 +1,4 @@ -#define BSNES_VERSION "0.013" +#define BSNES_VERSION "0.013 wip2" #define BSNES_TITLE "bsnes v" BSNES_VERSION #include "reader/reader.h" diff --git a/src/ppu/bppu/bppu.cpp b/src/ppu/bppu/bppu.cpp index cc0f86ee..e67a663f 100644 --- a/src/ppu/bppu/bppu.cpp +++ b/src/ppu/bppu/bppu.cpp @@ -5,18 +5,19 @@ void bPPU::run() {} void bPPU::scanline() { - _y = cpu->vcounter(); - _screen_width = (regs.bg_mode == 5 || regs.bg_mode == 6) ? 512 : 256; - _interlace = cpu->interlace(); - _interlace_field = cpu->interlace_field(); + line.y = cpu->vcounter(); + line.width = (regs.bg_mode == 5 || regs.bg_mode == 6) ? 512 : 256; + line.hires = (regs.bg_mode == 5 || regs.bg_mode == 6); + line.interlace = cpu->interlace(); + line.interlace_field = cpu->interlace_field(); - if(_y == 0) { + if(line.y == 0) { //RTO flag reset regs.time_over = false; regs.range_over = false; } - if(_y == 1) { + if(line.y == 1) { //OAM FirstSprite priority set if(regs.oam_priority == true) { regs.oam_firstsprite = (regs.oam_addr & 0xfe) >> 1; @@ -25,7 +26,7 @@ void bPPU::scanline() { } } - if(_y == (cpu->overscan() ? 239 : 224) && regs.display_disabled == false) { + if(line.y == (cpu->overscan() ? 239 : 224) && regs.display_disabled == false) { //OAM address reset regs.oam_addr = ((regs.oam_addrh << 8) | regs.oam_addrl) << 1; } @@ -34,7 +35,7 @@ void bPPU::scanline() { void bPPU::render_scanline() { if(status.render_output == false)return; - if(_y > 0 && _y < (cpu->overscan() ? 239 : 224)) { + if(line.y > 0 && line.y < (cpu->overscan() ? 239 : 224)) { render_line(); } } @@ -252,7 +253,7 @@ void bPPU::reset() { regs.time_over = false; regs.range_over = false; - _screen_width = 256; //needed for clear_window_cache() + line.width = 256; //needed for clear_window_cache() update_sprite_list_sizes(); clear_tiledata_cache(); clear_window_cache(); diff --git a/src/ppu/bppu/bppu.h b/src/ppu/bppu/bppu.h index 406fd8a6..ce4956c3 100644 --- a/src/ppu/bppu/bppu.h +++ b/src/ppu/bppu/bppu.h @@ -15,7 +15,15 @@ uint8 region; enum { NTSC = 0, PAL = 1 }; enum { BG1 = 0, BG2 = 1, BG3 = 2, BG4 = 3, OAM = 4, BACK = 5, COL = 5 }; -enum { SC_32x32 = 0, SC_32x64 = 1, SC_64x32 = 2, SC_64x64 = 3 }; +enum { SC_32x32 = 0, SC_64x32 = 1, SC_32x64 = 2, SC_64x64 = 3 }; + +struct { + uint32 y; + uint32 width; + bool hires; + bool interlace; + bool interlace_field; +} line; struct sprite_item { uint8 width, height; diff --git a/src/ppu/bppu/bppu_render.cpp b/src/ppu/bppu/bppu_render.cpp index 9a156c02..05618f3f 100644 --- a/src/ppu/bppu/bppu_render.cpp +++ b/src/ppu/bppu/bppu_render.cpp @@ -127,6 +127,7 @@ void bPPU::render_line() { clear_pixel_cache(); build_window_tables(COL); + update_bg_info(); switch(regs.bg_mode) { case 0:render_line_mode0();break; diff --git a/src/ppu/bppu/bppu_render.h b/src/ppu/bppu/bppu_render.h index 13be3f0c..5143f21d 100644 --- a/src/ppu/bppu/bppu_render.h +++ b/src/ppu/bppu/bppu_render.h @@ -1,8 +1,4 @@ //bppu_render.cpp -int _screen_width; -bool _interlace; -int _interlace_field; - inline void render_line_mode0(); inline void render_line_mode1(); inline void render_line_mode2(); @@ -49,6 +45,13 @@ void build_window_tables(uint8 bg); inline void clear_window_cache(); //bppu_render_bg.cpp +struct { + uint16 tw, th; //tile width, height + uint16 mx, my; //screen mask x, y +} bg_info[4]; + +inline void update_bg_info(); +inline uint16 bg_get_tile(uint8 bg, uint16 x, uint16 y); void render_line_bg(uint8 bg, uint8 color_depth, uint8 pri0_pos, uint8 pri1_pos); //bppu_render_oam.cpp diff --git a/src/ppu/bppu/bppu_render_bg.cpp b/src/ppu/bppu/bppu_render_bg.cpp index bd29d0e4..87c54b5c 100644 --- a/src/ppu/bppu/bppu_render_bg.cpp +++ b/src/ppu/bppu/bppu_render_bg.cpp @@ -1,263 +1,189 @@ +//called once at the start of every rendered scanline +void bPPU::update_bg_info() { + for(int bg=0;bg<4;bg++) { + bg_info[bg].th = (regs.bg_tilesize[bg]) ? 4 : 3; + bg_info[bg].tw = (line.hires) ? 4 : bg_info[bg].th; + bg_info[bg].mx = (bg_info[bg].th == 4) ? (line.width << 1) : line.width; + bg_info[bg].my = bg_info[bg].mx; + if(regs.bg_scsize[bg] & 0x01)bg_info[bg].mx <<= 1; + if(regs.bg_scsize[bg] & 0x02)bg_info[bg].my <<= 1; + bg_info[bg].mx--; + bg_info[bg].my--; + } +} + +uint16 bPPU::bg_get_tile(uint8 bg, uint16 x, uint16 y) { +uint16 map_index, pos; + x &= bg_info[bg].mx; + y &= bg_info[bg].my; + +//32 = SC width, height; tilemap data is stored as uint16 +//width(32) * height(32) * sizeof(uint16) = 2048 + switch(regs.bg_scsize[bg]) { + case SC_32x32:map_index = 0; break; + case SC_64x32:map_index = ((x >> bg_info[bg].th) / 32) * 2048; break; + case SC_32x64:map_index = ((y >> bg_info[bg].th) / 32) * 2048; break; + case SC_64x64:map_index = ((x >> bg_info[bg].th) / 32) * 2048 + + ((y >> bg_info[bg].th) / 32) * 4096; break; + } + + pos = ((((y >> bg_info[bg].th) & 31) * 32) + ((x >> bg_info[bg].tw) & 31)) << 1; + return read16(vram, regs.bg_scaddr[bg] + map_index + pos); +} + void bPPU::render_line_bg(uint8 bg, uint8 color_depth, uint8 pri0_pos, uint8 pri1_pos) { if(regs.bg_enabled[bg] == false && regs.bgsub_enabled[bg] == false) { return; } -int x; -int _scaddr = regs.bg_scaddr[bg]; -int _tdaddr = regs.bg_tdaddr[bg]; -bool _bg_enabled = regs.bg_enabled[bg]; -bool _bgsub_enabled = regs.bgsub_enabled[bg]; +bool bg_enabled = regs.bg_enabled[bg]; +bool bgsub_enabled = regs.bgsub_enabled[bg]; -uint16 opt_valid_bit; //offset-per-tile valid flag bit - if(bg == BG1) { - opt_valid_bit = 0x2000; - } else if(bg == BG2) { - opt_valid_bit = 0x4000; - } else { - opt_valid_bit = 0x0000; +uint16 opt_valid_bit = (bg == BG1) ? 0x2000 : ((bg == BG2) ? 0x4000 : 0x0000); +uint8 bgpal_index = (regs.bg_mode == 0) ? (bg << 5) : 0; + +uint8 pal_size = (color_depth == 2) ? 256 : ((color_depth == 1) ? 16 : 4); +//4 + color_depth = >>(4-6) -- / {16, 32, 64 } bytes/tile +//index is a tile number count to add to base tile number +uint tiledata_index = regs.bg_tdaddr[bg] >> (4 + color_depth); + +uint8 *bg_td = (uint8*)bg_tiledata[color_depth]; +uint8 *bg_td_state = (uint8*)bg_tiledata_state[color_depth]; + +uint8 tile_width = bg_info[bg].tw; +uint8 tile_height = bg_info[bg].th; +uint16 mask_x = bg_info[bg].mx; //screen width mask +uint16 mask_y = bg_info[bg].my; //screen height mask + +uint x = 0; +uint y = line.y; + if(line.interlace && line.hires) { + y = (y << 1) + line.interlace_field; } -//Mode 0 uses a special palette-indexing mode. -//Since there are 8 selectable palettes per tile, -//and there are 4 colors per palette on all four -//BGs for Mode 0, each BG has a unique palette -//entry point. This allows all 256 palette colors -//to be used, instead of just the first 32. -//entry = bg * 32, where 32 is from 8 * 4 -uint8 bgpal_index = (regs.bg_mode == 0) ? (bg << 5) : 0; +uint16 hscroll = (line.hires) ? (regs.bg_hofs[bg] << 1) : regs.bg_hofs[bg]; +uint16 vscroll = (line.interlace && line.hires) ? (regs.bg_vofs[bg] << 1) : regs.bg_vofs[bg]; + hscroll &= mask_x; + vscroll &= mask_y; -uint8 pal_size, tiledata_size; - switch(color_depth) { - case COLORDEPTH_4: - pal_size = 4; - tiledata_size = 4; //<<4=*16 - break; - case COLORDEPTH_16: - pal_size = 16; - tiledata_size = 5; //<<5=*32 - break; - case COLORDEPTH_256: - pal_size = 256; - tiledata_size = 6; //<<6=*64 - break; - } +uint16 *mtable = (uint16*)mosaic_table[(regs.mosaic_enabled[bg]) ? regs.mosaic_size : 0]; +uint16 mosaic_x; +uint16 mosaic_y; -uint8 *bg_td, *bg_td_state; - bg_td = (uint8*)bg_tiledata[color_depth]; - bg_td_state = (uint8*)bg_tiledata_state[color_depth]; - -uint16 screen_width, screen_height; - screen_width = _screen_width; - screen_height = _screen_width; //this is correct -- ppu tilemap is a perfect square - -uint8 tile_size, tile_width, tile_height; - tile_size = (regs.bg_tilesize[bg])?4:3; //<<4=*16, <<3=*8 - tile_width = tile_size; - tile_height = tile_size; - -int screen_x, screen_y; - if(_interlace == true && _screen_width == 512) { - screen_y = (_y << 1) + _interlace_field; - } else { - screen_y = _y; - } - -//Modes 5 and 6 seem to force 16-width tiles due to having twice the resolution. -//The tile size attribute in $2105 has no effect on tile width. - if(_screen_width == 512) { - tile_width = 4; //<<4=*16 - } - - if(tile_size == 4) { //16x16 tile size - screen_width <<= 1; - screen_height <<= 1; - } - - if(regs.bg_scsize[bg] & 0x01)screen_width <<= 1; - if(regs.bg_scsize[bg] & 0x02)screen_height <<= 1; - -uint16 screen_width_mask, screen_height_mask; - screen_width_mask = screen_width - 1; - screen_height_mask = screen_height - 1; - -int bg_x, bg_y; -uint16 vscroll, hscroll; - if(_screen_width == 512) { - hscroll = (regs.bg_hofs[bg] << 1) & screen_width_mask; - } else { - hscroll = regs.bg_hofs[bg] & screen_width_mask; - } - bg_x = hscroll; - - if(_screen_width == 512 && _interlace == true) { - vscroll = (regs.bg_vofs[bg] << 1) & screen_height_mask; - } else { - vscroll = regs.bg_vofs[bg] & screen_height_mask; - } - bg_y = (screen_y + vscroll) & screen_height_mask; - -uint16 *mtable; -int mosaic_x, mosaic_y; - if(regs.mosaic_enabled[bg] == true) { - mtable = (uint16*)mosaic_table[regs.mosaic_size]; - } else { - mtable = (uint16*)mosaic_table[0]; - } - - mosaic_x = mtable[bg_x]; - mosaic_y = mtable[bg_y]; - -uint8 tile_x; -uint16 t, base_xpos, base_pos, pos; -uint16 tile_num; -int mirror_x, mirror_y; +uint16 hval, vval; +uint16 t, tile_pri, tile_num; uint8 pal_index, pal_num; uint8 *tile_ptr; -int xpos, ypos; -uint16 map_index, hoffset, voffset, col; +uint xpos, ypos; +uint16 hoffset, voffset, opt_x, col; +bool mirror_x, mirror_y; +bool is_opt_mode = (regs.bg_mode == 2 || regs.bg_mode == 4 || regs.bg_mode == 6); build_window_tables(bg); uint8 *wt_main = window_cache[bg].main; uint8 *wt_sub = window_cache[bg].sub; - screen_x = 0; - do { //for(screen_x=0;screen_x<_screen_width;screen_x++) { - if(regs.bg_mode == 2 || regs.bg_mode == 4 || regs.bg_mode == 6) { - if(regs.bg_mode == 6) { - //hires adjust - tile_x = (mtable[screen_x + (hscroll & 15)] >> 4); - } else { - tile_x = (mtable[screen_x + (hscroll & 7)] >> 3); - } +int32 prev_x = -1, prev_y = -1; + for(x=0;x= 8) { + hval = bg_get_tile(BG3, + (opt_x - 8) + (regs.bg_hofs[BG3] & ~7), + regs.bg_vofs[BG3]); + + vval = bg_get_tile(BG3, + (opt_x - 8) + (regs.bg_hofs[BG3] & ~7), + regs.bg_vofs[BG3] + 8); if(regs.bg_mode == 4) { - pos = regs.bg_scaddr[BG3] + tile_x; - t = read16(vram, pos); - if(t & opt_valid_bit) { - if(!(t & 0x8000)) { - hoffset = ((t & 0x1ff8) | (hscroll & 7)) & screen_width_mask; + if(hval & opt_valid_bit) { + if(!(hval & 0x8000)) { + hoffset = opt_x + (hval & ~7); } else { - voffset = (t & 0x1fff) & screen_height_mask; + voffset = y + hval; } } } else { - pos = regs.bg_scaddr[BG3] + tile_x; - t = read16(vram, pos); - if(t & opt_valid_bit) { - hoffset = ((t & 0x1ff8) | (hscroll & 7)) & screen_width_mask; + if(hval & opt_valid_bit) { + hoffset = opt_x + (hval & ~7); } - pos = regs.bg_scaddr[BG3] + 64 + tile_x; - t = read16(vram, pos); - if(t & opt_valid_bit) { - voffset = (t & 0x1fff) & screen_height_mask; + if(vval & opt_valid_bit) { + voffset = y + vval; } } } - - mosaic_x = mtable[(screen_x + hoffset) & screen_width_mask ]; - mosaic_y = mtable[(screen_y + voffset) & screen_height_mask]; } - switch(regs.bg_scsize[bg]) { - case 0: - map_index = 0; - break; - case 1: - map_index = ((mosaic_x >> tile_size) >> 5) << 11; - break; - case 2: - map_index = ((mosaic_y >> tile_size) >> 5) << 11; - break; - case 3: - map_index = ((mosaic_x >> tile_size) >> 5) << 11 | - ((mosaic_y >> tile_size) >> 5) << 12; - break; - } + mosaic_x = mtable[hoffset & mask_x]; + mosaic_y = mtable[voffset & mask_y]; - base_xpos = ((mosaic_x >> 3) & 31); - base_pos = (((mosaic_y >> tile_height) & 31) << 5) + ((mosaic_x >> tile_width) & 31); - pos = _scaddr + map_index + (base_pos << 1); - t = read16(vram, pos); - mirror_y = !!(t & 0x8000); - mirror_x = !!(t & 0x4000); + if((mosaic_x >> 3) != prev_x || (mosaic_y >> 3) != prev_y) { + prev_x = (mosaic_x >> 3); + prev_y = (mosaic_y >> 3); -int _pri; - _pri = (t & 0x2000) ? pri1_pos : pri0_pos; + t = bg_get_tile(bg, mosaic_x, mosaic_y); - tile_num = t & 0x03ff; + mirror_y = !!(t & 0x8000); + mirror_x = !!(t & 0x4000); - //16x16 horizontal tile mirroring - if(tile_width == 4) { - if(((mosaic_x & 15) >= 8 && !mirror_x) || - ((mosaic_x & 15) < 8 && mirror_x))tile_num++; - tile_num &= 0x03ff; - } + tile_pri = (t & 0x2000) ? pri1_pos : pri0_pos; + tile_num = t; - //16x16 vertical tile mirroring - if(tile_height == 4) { - if(((mosaic_y & 15) >= 8 && !mirror_y) || - ((mosaic_y & 15) < 8 && mirror_y))tile_num += 16; - tile_num &= 0x03ff; - } - - tile_num += (_tdaddr >> tiledata_size); - - if(bg_td_state[tile_num] == 1) { - render_bg_tile(color_depth, tile_num); - } - - pal_num = ((t >> 10) & 7); - pal_index = pal_num * pal_size + bgpal_index; - - if(mirror_y) { ypos = (7 - (mosaic_y & 7)); } - else { ypos = ( (mosaic_y & 7)); } - -//loop while we are rendering from the same tile, as there's no need to do all of the above work -//unless we have rendered all of the visible tile, taking mosaic into account. - tile_ptr = (uint8*)bg_td + (tile_num << 6) + (ypos << 3); - do { - if(mirror_x) { xpos = (7 - (mosaic_x & 7)); } - else { xpos = ( (mosaic_x & 7)); } - col = *(tile_ptr + xpos); - if(col && window_cache[COL].main[screen_x]) { - if(regs.direct_color == true && bg == BG1 && (regs.bg_mode == 3 || regs.bg_mode == 4)) { - col = get_direct_color(pal_num, col); - } else { - col = get_palette(col + pal_index); - } - - if(_bg_enabled == true && !wt_main[screen_x]) { - if(pixel_cache[screen_x].pri_main < _pri) { - pixel_cache[screen_x].pri_main = _pri; - pixel_cache[screen_x].bg_main = 0x80 | bg; - pixel_cache[screen_x].src_main = col; - pixel_cache[screen_x].color_exempt = false; - } - } - if(_bgsub_enabled == true && !wt_sub[screen_x]) { - if(pixel_cache[screen_x].pri_sub < _pri) { - pixel_cache[screen_x].pri_sub = _pri; - pixel_cache[screen_x].bg_sub = 0x80 | bg; - pixel_cache[screen_x].src_sub = col; - } - } + if(tile_width == 4) { //16x16 horizontal tile mirroring + if(!!(mosaic_x & 8) != mirror_x)tile_num++; } - bg_x++; - bg_x &= screen_width_mask; - mosaic_x = mtable[bg_x]; + if(tile_height == 4) { //16x16 vertical tile mirroring + if(!!(mosaic_y & 8) != mirror_y)tile_num += 16; + } - if(base_xpos != ((mosaic_x >> 3) & 31))break; - if(++screen_x >= _screen_width)break; - } while(1); - } while(++screen_x < _screen_width); + tile_num &= 0x03ff; + tile_num += tiledata_index; + + if(bg_td_state[tile_num] == 1) { + render_bg_tile(color_depth, tile_num); + } + + pal_num = ((t >> 10) & 7); + pal_index = (pal_num * pal_size) + bgpal_index; + + ypos = mosaic_y & 7; + if(mirror_y)ypos ^= 7; //invert y tile pos + + tile_ptr = (uint8*)bg_td + (tile_num * 64) + (ypos * 8); + } + + xpos = mosaic_x & 7; + if(mirror_x)xpos ^= 7; //invert x tile pos + col = *(tile_ptr + xpos); + if(col && window_cache[COL].main[x]) { + if(regs.direct_color == true && bg == BG1 && (regs.bg_mode == 3 || regs.bg_mode == 4)) { + col = get_direct_color(pal_num, col); + } else { + col = get_palette(col + pal_index); + } + + if(bg_enabled == true && !wt_main[x]) { + if(pixel_cache[x].pri_main < tile_pri) { + pixel_cache[x].pri_main = tile_pri; + pixel_cache[x].bg_main = 0x80 | bg; + pixel_cache[x].src_main = col; + pixel_cache[x].color_exempt = false; + } + } + if(bgsub_enabled == true && !wt_sub[x]) { + if(pixel_cache[x].pri_sub < tile_pri) { + pixel_cache[x].pri_sub = tile_pri; + pixel_cache[x].bg_sub = 0x80 | bg; + pixel_cache[x].src_sub = col; + } + } + } + } } diff --git a/src/ppu/bppu/bppu_render_cache.cpp b/src/ppu/bppu/bppu_render_cache.cpp index 28bc5ae9..aa57f3cf 100644 --- a/src/ppu/bppu/bppu_render_cache.cpp +++ b/src/ppu/bppu/bppu_render_cache.cpp @@ -3,6 +3,7 @@ if(d0 & __m)col += 1; \ if(d1 & __m)col += 2; \ *dest++ = col + #define render_bg_tile_line_16(__m) \ col = 0; \ if(d0 & __m)col += 1; \ @@ -10,6 +11,7 @@ if(d2 & __m)col += 4; \ if(d3 & __m)col += 8; \ *dest++ = col + #define render_bg_tile_line_256(__m) \ col = 0; \ if(d0 & __m)col += 1; \ @@ -96,6 +98,10 @@ uint8 *dest; } } +#undef render_bg_tile_line_4 +#undef render_bg_tile_line_16 +#undef render_bg_tile_line_256 + inline void bPPU::clear_pixel_cache() { memset(pixel_cache, 0, sizeof(pixel_cache)); } diff --git a/src/ppu/bppu/bppu_render_line.cpp b/src/ppu/bppu/bppu_render_line.cpp index ac8565d5..6293c76c 100644 --- a/src/ppu/bppu/bppu_render_line.cpp +++ b/src/ppu/bppu/bppu_render_line.cpp @@ -67,7 +67,7 @@ uint16 *ptr; uint16 *ltable; ltable = (uint16*)light_table + (regs.display_brightness << 15); - if(_screen_width == 256) { + if(line.width == 256) { for(x=0;x<256;x++) { _r = get_pixel(x); *ptr++ = *(ltable + _r); diff --git a/src/ppu/bppu/bppu_render_mode7.cpp b/src/ppu/bppu/bppu_render_mode7.cpp index 85e06c1c..4c9f7d2a 100644 --- a/src/ppu/bppu/bppu_render_mode7.cpp +++ b/src/ppu/bppu/bppu_render_mode7.cpp @@ -43,9 +43,9 @@ uint8 *wt_main = window_cache[bg].main; uint8 *wt_sub = window_cache[bg].sub; if(regs.mode7_vflip == true) { - y = 255 - _y; + y = 255 - line.y; } else { - y = _y; + y = line.y; } uint16 *mtable_x, *mtable_y; diff --git a/src/ppu/bppu/bppu_render_oam.cpp b/src/ppu/bppu/bppu_render_oam.cpp index e1ba3771..e6a3b0db 100644 --- a/src/ppu/bppu/bppu_render_oam.cpp +++ b/src/ppu/bppu/bppu_render_oam.cpp @@ -90,18 +90,18 @@ uint16 addr = 0x0200; bool bPPU::is_sprite_on_scanline() { //if sprite is entirely offscreen and doesn't wrap around to the left side of the screen, //then it is not counted. 256 is correct, and not 255 -- as one might first expect - if(spr->x > 256 && (spr->x + spr->width) < 512 && _screen_width != 512)return false; + if(spr->x > 256 && (spr->x + spr->width) < 512 && line.width != 512)return false; if(regs.oam_halve == false) { - if(_y >= spr->y && _y < (spr->y + spr->height)) { + if(line.y >= spr->y && line.y < (spr->y + spr->height)) { return true; - } else if((spr->y + spr->height) >= 256 && _y < ((spr->y + spr->height) & 255)) { + } else if((spr->y + spr->height) >= 256 && line.y < ((spr->y + spr->height) & 255)) { return true; } } else { - if(_y >= spr->y && _y < (spr->y + (spr->height >> 1))) { + if(line.y >= spr->y && line.y < (spr->y + (spr->height >> 1))) { return true; - } else if((spr->y + (spr->height >> 1)) >= 256 && _y < ((spr->y + (spr->height >> 1)) & 255)) { + } else if((spr->y + (spr->height >> 1)) >= 256 && line.y < ((spr->y + (spr->height >> 1)) & 255)) { return true; } } @@ -115,21 +115,21 @@ uint16 tile_width; int x, y, chr, nameselect_index; x = spr->x; - if(_screen_width == 512)x <<= 1; + if(line.width == 512)x <<= 1; x &= 511; if(spr->vflip) { - y = ((spr->height - 1) - (_y - spr->y)); + y = ((spr->height - 1) - (line.y - spr->y)); } else { - y = (_y - spr->y); + y = (line.y - spr->y); } //todo: double-check code below. seems that interlace_field //should be added to hires 512x448 sprites as well, and not //just when oam_halve is enabled... if(regs.oam_halve == true) { y <<= 1; - if(_interlace == true && _screen_width == 512) { - y += _interlace_field; + if(line.interlace && line.width == 512) { + y += line.interlace_field; } } y &= 255; @@ -146,11 +146,11 @@ int x, y, chr, nameselect_index; int i, n, mx, pos, z; for(i=0;i= 257 && (z + 7) < 512 && _screen_width != 512)continue; + if(z >= 257 && (z + 7) < 512 && line.width != 512)continue; if(regs.oam_tilecount++ > 34)break; n = regs.oam_tilecount - 1; @@ -186,19 +186,19 @@ int x, sx, col; tile_ptr = (uint8*)oam_td + (t->tile << 6) + ((t->y & 7) << 3); for(x=0;x<8;x++) { sx &= 511; - if(sx < _screen_width) { + if(sx < line.width) { col = *(tile_ptr + ((t->hflip)?7-x:x)); if(col) { col += t->pal; oam_line_pal[sx] = col; oam_line_pri[sx] = t->pri; - if(_screen_width == 512) { + if(line.width == 512) { oam_line_pal[sx + 1] = col; oam_line_pri[sx + 1] = t->pri; } } } - sx += (_screen_width == 512)?2:1; + sx += (line.width == 512) ? 2 : 1; } } @@ -242,7 +242,7 @@ uint8 *wt_sub = window_cache[OAM].sub; if(_bg_enabled == false && _bgsub_enabled == false)return; int _pri; - for(x=0;x<_screen_width;x++) { + for(x=0;x= window1_left && x <= window1_right) ? set : clr; } } else { - for(x=0;x<_screen_width;x++) { + for(x=0;x window1_right) ? set : clr; } } } else if(regs.window1_enabled[bg] == false && regs.window2_enabled[bg] == true) { if(regs.window2_invert[bg] == false) { - for(x=0;x<_screen_width;x++) { + for(x=0;x= window2_left && x <= window2_right) ? set : clr; } } else { - for(x=0;x<_screen_width;x++) { + for(x=0;x window2_right) ? set : clr; } } } else { //if(regs.window1_enabled[bg] == true && regs.window2_enabled[bg] == true) { - for(x=0;x<_screen_width;x++) { + for(x=0;x= window1_left && x <= window1_right); } else { diff --git a/src/ppu/ppu.h b/src/ppu/ppu.h index 6cdc6843..7065473d 100644 --- a/src/ppu/ppu.h +++ b/src/ppu/ppu.h @@ -21,7 +21,6 @@ uint8 ppu1_version; //* reported by $213f uint8 ppu2_version; -int _y; MMIO *mmio; struct scanline_info {