Update to bsnes v013r02 release.

[No changelog available]
This commit is contained in:
byuu 2005-10-25 23:25:28 +00:00
parent c6c5f4669c
commit f288280ceb
15 changed files with 228 additions and 289 deletions

BIN
bsnes.exe

Binary file not shown.

View File

@ -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;
}
}
}

View File

@ -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);

View File

@ -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"

View File

@ -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();

View File

@ -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;

View File

@ -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;

View File

@ -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

View File

@ -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<line.width;x++) {
hoffset = x + hscroll;
voffset = y + vscroll;
hoffset = hscroll;
voffset = vscroll;
if(is_opt_mode) {
opt_x = (x + (hscroll & 7));
//tile 0 is unaffected by OPT mode...
if(tile_x != 0) {
//multiply by two to index into 16-bit table entries
tile_x = ((tile_x - 1) & 31) << 1;
if(opt_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;
}
}
}
}
}

View File

@ -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));
}

View File

@ -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);

View File

@ -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;

View File

@ -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<tile_width;i++) {
z = x;
z += (i << ((_screen_width == 512)?4:3));
z += (i << ((line.width == 512) ? 4 : 3));
z &= 511;
//ignore sprites that are offscreen
//sprites at 256 are still counted, even though they aren't visible onscreen
if(z >= 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<line.width;x++) {
if(oam_line_pri[x] == OAM_PRI_NONE)continue;
switch(oam_line_pri[x]) {

View File

@ -9,11 +9,11 @@ uint8 *wtbl;
if(bg != COL) {
if(mainscreen == true && regs.window_enabled[bg] == false) {
memset(wtbl, 0, _screen_width);
memset(wtbl, 0, line.width);
return;
}
if(mainscreen == false && regs.sub_window_enabled[bg] == false) {
memset(wtbl, 0, _screen_width);
memset(wtbl, 0, line.width);
return;
}
} else {
@ -26,13 +26,13 @@ uint8 *wtbl;
if(mask == 0) {
//always
memset(wtbl, 1, _screen_width);
memset(wtbl, 1, line.width);
return;
}
if(mask == 3) {
//never
memset(wtbl, 0, _screen_width);
memset(wtbl, 0, line.width);
return;
}
@ -56,7 +56,7 @@ bool r;
window2_left = regs.window2_left;
window2_right = regs.window2_right;
if(_screen_width == 512) {
if(line.width == 512) {
window1_left <<= 1;
window1_right <<= 1;
window2_left <<= 1;
@ -64,29 +64,29 @@ bool r;
}
if(regs.window1_enabled[bg] == false && regs.window2_enabled[bg] == false) {
memset(wtbl, clr, _screen_width);
memset(wtbl, clr, line.width);
} else if(regs.window1_enabled[bg] == true && regs.window2_enabled[bg] == false) {
if(regs.window1_invert[bg] == false) {
for(x=0;x<_screen_width;x++) {
for(x=0;x<line.width;x++) {
wtbl[x] = (x >= window1_left && x <= window1_right) ? set : clr;
}
} else {
for(x=0;x<_screen_width;x++) {
for(x=0;x<line.width;x++) {
wtbl[x] = (x < window1_left || 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<line.width;x++) {
wtbl[x] = (x >= window2_left && x <= window2_right) ? set : clr;
}
} else {
for(x=0;x<_screen_width;x++) {
for(x=0;x<line.width;x++) {
wtbl[x] = (x < window2_left || 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<line.width;x++) {
if(regs.window1_invert[bg] == false) {
w1_mask = (x >= window1_left && x <= window1_right);
} else {

View File

@ -21,7 +21,6 @@ uint8 ppu1_version;
//* reported by $213f
uint8 ppu2_version;
int _y;
MMIO *mmio;
struct scanline_info {