libgambatte: misc non-functional
This commit is contained in:
parent
2195c64b0e
commit
f1ec850332
@ -24,16 +24,11 @@ using namespace gambatte;
|
||||
namespace {
|
||||
|
||||
template <OamDmaSrc src, bool cgb> struct OamDmaConflictMap;
|
||||
template <> struct OamDmaConflictMap<oam_dma_src_rom, true> { enum { r = 0xFCFF }; };
|
||||
template <> struct OamDmaConflictMap<oam_dma_src_sram, true> { enum { r = 0xFCFF }; };
|
||||
template <> struct OamDmaConflictMap<oam_dma_src_vram, true> { enum { r = 0x0300 }; };
|
||||
template <> struct OamDmaConflictMap<oam_dma_src_wram, true> { enum { r = 0xF000 }; };
|
||||
template <> struct OamDmaConflictMap<oam_dma_src_invalid, true> { enum { r = 0xFCFF }; };
|
||||
template <> struct OamDmaConflictMap<oam_dma_src_rom, false> { enum { r = 0xFCFF }; };
|
||||
template <> struct OamDmaConflictMap<oam_dma_src_sram, false> { enum { r = 0xFCFF }; };
|
||||
template <> struct OamDmaConflictMap<oam_dma_src_vram, false> { enum { r = 0x0300 }; };
|
||||
template <> struct OamDmaConflictMap<oam_dma_src_wram, false> { enum { r = 0xFCFF }; };
|
||||
template <> struct OamDmaConflictMap<oam_dma_src_invalid, false> { enum { r = 0x0000 }; };
|
||||
template <bool cgb> struct OamDmaConflictMap<oam_dma_src_rom, cgb> { enum { r = 0xFCFF }; };
|
||||
template <bool cgb> struct OamDmaConflictMap<oam_dma_src_sram, cgb> { enum { r = 0xFCFF }; };
|
||||
template <bool cgb> struct OamDmaConflictMap<oam_dma_src_vram, cgb> { enum { r = 0x0300 }; };
|
||||
template <bool cgb> struct OamDmaConflictMap<oam_dma_src_wram, cgb> { enum { r = cgb ? 0xF000 : 0xFCFF }; };
|
||||
template <bool cgb> struct OamDmaConflictMap<oam_dma_src_invalid, cgb> { enum { r = cgb ? 0xFCFF : 0x0000 }; };
|
||||
|
||||
template <bool cgb>
|
||||
bool isInOamDmaConflictArea(OamDmaSrc src, unsigned p)
|
||||
@ -52,7 +47,7 @@ template <OamDmaSrc src, bool cgb>
|
||||
void disconnectOamDmaAreas(unsigned char const *(&rmem)[0x10], unsigned char *(&wmem)[0x10])
|
||||
{
|
||||
if (OamDmaConflictMap<src, cgb>::r & 0x00FF)
|
||||
std::fill(rmem, rmem + 8, static_cast<unsigned char *>(0));
|
||||
std::fill_n(rmem, 8, static_cast<unsigned char *>(0));
|
||||
if (OamDmaConflictMap<src, cgb>::r & 0x0C00)
|
||||
rmem[0xB] = rmem[0xA] = wmem[0xB] = wmem[0xA] = 0;
|
||||
if (OamDmaConflictMap<src, cgb>::r & 0x7000)
|
||||
|
@ -7,8 +7,10 @@ enum {
|
||||
lcdc_bgen = 0x01,
|
||||
lcdc_objen = 0x02,
|
||||
lcdc_obj2x = 0x04,
|
||||
lcdc_bgtmsel = 0x08,
|
||||
lcdc_tdsel = 0x10,
|
||||
lcdc_we = 0x20,
|
||||
lcdc_wtmsel = 0x40,
|
||||
lcdc_en = 0x80 };
|
||||
|
||||
enum {
|
||||
|
@ -96,12 +96,22 @@ namespace StartWindowDraw {
|
||||
|
||||
#undef DECLARE_FUNC
|
||||
|
||||
enum { attr_xflip = 0x20, attr_yflip = 0x40, attr_bgpriority = 0x80 };
|
||||
enum { attr_cgbpalno = 0x07, attr_tdbank = 0x08, attr_dmgpalno = 0x10, attr_xflip = 0x20,
|
||||
attr_yflip = 0x40, attr_bgpriority = 0x80 };
|
||||
enum { win_draw_start = 1, win_draw_started = 2 };
|
||||
|
||||
int const m2_ds_offset = 3;
|
||||
int const max_m3start_cycles = 80;
|
||||
int const tile_bpp = 2;
|
||||
int const tile_bpp_mask = (1 << tile_bpp) - 1;
|
||||
int const tile_len = 8;
|
||||
int const tile_line_size = tile_bpp * tile_len / 8;
|
||||
int const tile_size = tile_line_size * tile_len;
|
||||
int const tile_map_begin = 0x1800;
|
||||
int const tile_map_len = 0x20;
|
||||
int const tile_map_size = tile_map_len * tile_map_len;
|
||||
int const tile_pattern_table_size = 0x1000;
|
||||
int const vram_bank_size = 0x2000;
|
||||
int const xpos_end = 168;
|
||||
|
||||
inline int spx(PPUPriv::Sprite const &s) { return s.spx; }
|
||||
@ -138,14 +148,14 @@ namespace M2_Ly0 {
|
||||
namespace M2_LyNon0 {
|
||||
void f0(PPUPriv &p) {
|
||||
p.weMaster |= lcdcWinEn(p) && p.lyCounter.ly() == p.wy;
|
||||
nextCall( weMasterCheckAfterLyIncLineCycle(p.cgb)
|
||||
- weMasterCheckPriorToLyIncLineCycle(p.cgb), f1_, p);
|
||||
nextCall(weMasterCheckAfterLyIncLineCycle(p.cgb)
|
||||
- weMasterCheckPriorToLyIncLineCycle(p.cgb), f1_, p);
|
||||
}
|
||||
|
||||
void f1(PPUPriv &p) {
|
||||
p.weMaster |= lcdcWinEn(p) && p.lyCounter.ly() + 1 == p.wy;
|
||||
nextCall(lcd_cycles_per_line - weMasterCheckAfterLyIncLineCycle(p.cgb) + m3StartLineCycle(p.cgb),
|
||||
M3Start::f0_, p);
|
||||
M3Start::f0_, p);
|
||||
}
|
||||
}
|
||||
|
||||
@ -166,37 +176,39 @@ namespace M2 {
|
||||
}
|
||||
|
||||
void f1(PPUPriv &p) {
|
||||
int const oam_entry_size = 4;
|
||||
int const oam_size = oam_entry_size * lcd_num_oam_entries;
|
||||
int cycles = p.cycles;
|
||||
unsigned oampos = p.reg0;
|
||||
unsigned nextSprite = p.nextSprite;
|
||||
unsigned const nly = (p.lyCounter.ly() + 1 == 154 ? 0 : p.lyCounter.ly() + 1)
|
||||
+ ((p.lyCounter.time()-(p.now-p.cycles)) <= 4);
|
||||
unsigned const nly = (p.lyCounter.ly() + 1 == lcd_lines_per_frame ? 0 : p.lyCounter.ly() + 1)
|
||||
+ (p.lyCounter.time() - (p.now - p.cycles) <= 4);
|
||||
bool const ls = p.spriteMapper.largeSpritesSource();
|
||||
|
||||
do {
|
||||
unsigned const spy = p.spriteMapper.oamram()[oampos ];
|
||||
unsigned const spx = p.spriteMapper.oamram()[oampos+1];
|
||||
unsigned const spy = p.spriteMapper.oamram()[oampos];
|
||||
unsigned const spx = p.spriteMapper.oamram()[oampos + 1];
|
||||
unsigned const ydiff = spy - nly;
|
||||
|
||||
if (ls ? ydiff < 16u : ydiff - 8u < 8u) {
|
||||
if (ls ? ydiff < 2u * tile_len : ydiff - 1u * tile_len < 1u * tile_len) {
|
||||
p.spriteList[nextSprite].spx = spx;
|
||||
p.spriteList[nextSprite].line = 15u - ydiff;
|
||||
p.spriteList[nextSprite].line = 2 * tile_len - 1 - ydiff;
|
||||
p.spriteList[nextSprite].oampos = oampos;
|
||||
|
||||
if (++nextSprite == lcd_max_num_sprites_per_line) {
|
||||
cycles -= (0xA0 - 4 - oampos) >> 1;
|
||||
oampos = 0xA0 - 4;
|
||||
cycles -= (oam_size - oam_entry_size - oampos) >> 1;
|
||||
oampos = oam_size - oam_entry_size;
|
||||
}
|
||||
}
|
||||
|
||||
oampos += 4;
|
||||
} while ((cycles-=2) >= 0 && oampos != 0xA0);
|
||||
oampos += oam_entry_size;
|
||||
} while ((cycles -= 2) >= 0 && oampos != oam_size);
|
||||
|
||||
p.reg0 = oampos;
|
||||
p.nextSprite = nextSprite;
|
||||
p.cycles = cycles;
|
||||
|
||||
if (oampos == 0xA0) {
|
||||
if (oampos == oam_size) {
|
||||
insertionSort(p.spriteList, p.spriteList + nextSprite, SpriteLess());
|
||||
p.spriteList[nextSprite].spx = 0xFF;
|
||||
p.nextSprite = 0;
|
||||
@ -211,10 +223,12 @@ int loadTileDataByte0(PPUPriv const &p) {
|
||||
? p.winYPos
|
||||
: p.scy + p.lyCounter.ly();
|
||||
|
||||
return p.vram[0x1000 + (p.nattrib << 10 & 0x2000)
|
||||
- ((p.reg1 * 32 | p.lcdc << 8) & 0x1000)
|
||||
+ p.reg1 * 16
|
||||
+ (-(p.nattrib >> 6 & 1) ^ yoffset) % tile_len * 2];
|
||||
return p.vram[tile_pattern_table_size
|
||||
+ vram_bank_size / attr_tdbank * (p.nattrib & attr_tdbank)
|
||||
- ((2 * tile_size * p.reg1 | tile_pattern_table_size / lcdc_tdsel * p.lcdc)
|
||||
& tile_pattern_table_size)
|
||||
+ p.reg1 * tile_size
|
||||
+ ((p.nattrib & attr_yflip ? -1 : 0) ^ yoffset) % tile_len * tile_line_size];
|
||||
}
|
||||
|
||||
int loadTileDataByte1(PPUPriv const &p) {
|
||||
@ -222,10 +236,12 @@ int loadTileDataByte1(PPUPriv const &p) {
|
||||
? p.winYPos
|
||||
: p.scy + p.lyCounter.ly();
|
||||
|
||||
return p.vram[0x1000 + (p.nattrib << 10 & 0x2000)
|
||||
- ((p.reg1 * 32 | p.lcdc << 8) & 0x1000)
|
||||
+ p.reg1 * 16
|
||||
+ (-(p.nattrib >> 6 & 1) ^ yoffset) % tile_len * 2 + 1];
|
||||
return p.vram[tile_pattern_table_size
|
||||
+ vram_bank_size / attr_tdbank * (p.nattrib & attr_tdbank)
|
||||
- ((2 * tile_size * p.reg1 | tile_pattern_table_size / lcdc_tdsel * p.lcdc)
|
||||
& tile_pattern_table_size)
|
||||
+ p.reg1 * tile_size
|
||||
+ ((p.nattrib & attr_yflip ? -1 : 0) ^ yoffset) % tile_len * tile_line_size + 1];
|
||||
}
|
||||
|
||||
namespace M3Start {
|
||||
@ -251,15 +267,23 @@ namespace M3Start {
|
||||
switch (p.xpos % tile_len) {
|
||||
case 0:
|
||||
if (p.winDrawState & win_draw_started) {
|
||||
p.reg1 = p.vram[(p.lcdc << 4 & 0x400) + (p.winYPos & 0xF8) * 4
|
||||
+ (p.wscx / tile_len & 0x1F) + 0x1800];
|
||||
p.nattrib = p.vram[(p.lcdc << 4 & 0x400) + (p.winYPos & 0xF8) * 4
|
||||
+ (p.wscx / tile_len & 0x1F) + 0x3800];
|
||||
p.reg1 = p.vram[tile_map_size / lcdc_wtmsel * (p.lcdc & lcdc_wtmsel)
|
||||
+ tile_map_len / tile_len * (p.winYPos & (0x100 - tile_len))
|
||||
+ p.wscx / tile_len % tile_map_len
|
||||
+ tile_map_begin];
|
||||
p.nattrib = p.vram[tile_map_size / lcdc_wtmsel * (p.lcdc & lcdc_wtmsel)
|
||||
+ tile_map_len / tile_len * (p.winYPos & (0x100 - tile_len))
|
||||
+ p.wscx / tile_len % tile_map_len
|
||||
+ tile_map_begin + vram_bank_size];
|
||||
} else {
|
||||
p.reg1 = p.vram[((p.lcdc << 7 | p.scx / tile_len) & 0x41F)
|
||||
+ ((p.scy + p.lyCounter.ly()) & 0xF8) * 4 + 0x1800];
|
||||
p.nattrib = p.vram[((p.lcdc << 7 | p.scx / tile_len) & 0x41F)
|
||||
+ ((p.scy + p.lyCounter.ly()) & 0xF8) * 4 + 0x3800];
|
||||
p.reg1 = p.vram[((tile_map_size / lcdc_bgtmsel * p.lcdc | p.scx / tile_len)
|
||||
& (tile_map_size + tile_map_len - 1))
|
||||
+ tile_map_len / tile_len * ((p.scy + p.lyCounter.ly()) & (0x100 - tile_len))
|
||||
+ tile_map_begin];
|
||||
p.nattrib = p.vram[((tile_map_size / lcdc_bgtmsel * p.lcdc | p.scx / tile_len)
|
||||
& (tile_map_size + tile_map_len - 1))
|
||||
+ tile_map_len / tile_len * ((p.scy + p.lyCounter.ly()) & (0x100 - tile_len))
|
||||
+ tile_map_begin + vram_bank_size];
|
||||
}
|
||||
|
||||
break;
|
||||
@ -293,7 +317,7 @@ namespace M3Start {
|
||||
unsigned spx = p.spriteMapper.posbuf()[pos + 1];
|
||||
|
||||
p.spriteList[i].spx = spx;
|
||||
p.spriteList[i].line = ly + 16 - spy;
|
||||
p.spriteList[i].line = ly + 2 * tile_len - spy;
|
||||
p.spriteList[i].oampos = pos * 2;
|
||||
p.spwordList[i] = 0;
|
||||
}
|
||||
@ -324,8 +348,9 @@ namespace M3Loop {
|
||||
|
||||
void doFullTilesUnrolledDmg(PPUPriv &p, int const xend, uint_least32_t *const dbufline,
|
||||
unsigned char const *const tileMapLine, unsigned const tileline, unsigned tileMapXpos) {
|
||||
unsigned const tileIndexSign = ~(p.lcdc * 8u) & 0x80;
|
||||
unsigned char const *const tileDataLine = p.vram + tileIndexSign * 32 + tileline * 2;
|
||||
unsigned const tileIndexSign = (~p.lcdc & lcdc_tdsel) * 8;
|
||||
unsigned char const *const tileDataLine = p.vram + 2 * tile_size * tileIndexSign
|
||||
+ tileline * tile_line_size;
|
||||
int xpos = p.xpos;
|
||||
|
||||
do {
|
||||
@ -336,7 +361,6 @@ void doFullTilesUnrolledDmg(PPUPriv &p, int const xend, uint_least32_t *const db
|
||||
|
||||
if (lcdcObjEn(p)) {
|
||||
cycles -= std::max(11 - (spx(p.spriteList[nextSprite]) - xpos), 6);
|
||||
|
||||
for (int i = nextSprite + 1; spx(p.spriteList[i]) < xpos + tile_len; ++i)
|
||||
cycles -= 6;
|
||||
|
||||
@ -347,14 +371,14 @@ void doFullTilesUnrolledDmg(PPUPriv &p, int const xend, uint_least32_t *const db
|
||||
|
||||
do {
|
||||
unsigned char const *const oam = p.spriteMapper.oamram();
|
||||
unsigned reg0, reg1 = oam[p.spriteList[nextSprite].oampos + 2] * 16;
|
||||
unsigned reg0, reg1 = oam[p.spriteList[nextSprite].oampos + 2] * tile_size;
|
||||
unsigned const attrib = oam[p.spriteList[nextSprite].oampos + 3];
|
||||
unsigned const spline = ( attrib & attr_yflip
|
||||
? p.spriteList[nextSprite].line ^ 15
|
||||
: p.spriteList[nextSprite].line ) * 2;
|
||||
|
||||
reg0 = p.vram[(lcdcObj2x(p) ? (reg1 & ~16u) | spline : reg1 | (spline & ~16u)) ];
|
||||
reg1 = p.vram[(lcdcObj2x(p) ? (reg1 & ~16u) | spline : reg1 | (spline & ~16u)) + 1];
|
||||
? p.spriteList[nextSprite].line ^ 2 * tile_len - 1
|
||||
: p.spriteList[nextSprite].line ) * tile_line_size;
|
||||
unsigned const ts = tile_size;
|
||||
reg0 = p.vram[(lcdcObj2x(p) ? (reg1 & ~ts) | spline : reg1 | (spline & ~ts)) ];
|
||||
reg1 = p.vram[(lcdcObj2x(p) ? (reg1 & ~ts) | spline : reg1 | (spline & ~ts)) + 1];
|
||||
|
||||
p.spwordList[nextSprite] = expand_lut[reg0 + (attrib & attr_xflip) * 8]
|
||||
+ expand_lut[reg1 + (attrib & attr_xflip) * 8] * 2;
|
||||
@ -390,24 +414,26 @@ void doFullTilesUnrolledDmg(PPUPriv &p, int const xend, uint_least32_t *const db
|
||||
do { *dst++ = p.bgPalette[0]; } while (dst != dstend);
|
||||
tileMapXpos += n / (1u * tile_len);
|
||||
|
||||
unsigned const tno = tileMapLine[(tileMapXpos - 1) & 0x1F];
|
||||
ntileword = expand_lut[(tileDataLine + tno * 16 - (tno & tileIndexSign) * 32)[0]]
|
||||
+ expand_lut[(tileDataLine + tno * 16 - (tno & tileIndexSign) * 32)[1]] * 2;
|
||||
unsigned const tno = tileMapLine[(tileMapXpos - 1) % tile_map_len];
|
||||
int const ts = tile_size;
|
||||
ntileword = expand_lut[(tileDataLine + ts * tno - 2 * ts * (tno & tileIndexSign))[0]]
|
||||
+ expand_lut[(tileDataLine + ts * tno - 2 * ts * (tno & tileIndexSign))[1]] * 2;
|
||||
} else do {
|
||||
dst[0] = p.bgPalette[ ntileword & 0x0003 ];
|
||||
dst[1] = p.bgPalette[(ntileword & 0x000C) >> 2];
|
||||
dst[2] = p.bgPalette[(ntileword & 0x0030) >> 4];
|
||||
dst[3] = p.bgPalette[(ntileword & 0x00C0) >> 6];
|
||||
dst[4] = p.bgPalette[(ntileword & 0x0300) >> 8];
|
||||
dst[5] = p.bgPalette[(ntileword & 0x0C00) >> 10];
|
||||
dst[6] = p.bgPalette[(ntileword & 0x3000) >> 12];
|
||||
dst[7] = p.bgPalette[ ntileword >> 14];
|
||||
dst[0] = p.bgPalette[ ntileword & tile_bpp_mask ];
|
||||
dst[1] = p.bgPalette[(ntileword & tile_bpp_mask << 1 * tile_bpp) >> 1 * tile_bpp];
|
||||
dst[2] = p.bgPalette[(ntileword & tile_bpp_mask << 2 * tile_bpp) >> 2 * tile_bpp];
|
||||
dst[3] = p.bgPalette[(ntileword & tile_bpp_mask << 3 * tile_bpp) >> 3 * tile_bpp];
|
||||
dst[4] = p.bgPalette[(ntileword & tile_bpp_mask << 4 * tile_bpp) >> 4 * tile_bpp];
|
||||
dst[5] = p.bgPalette[(ntileword & tile_bpp_mask << 5 * tile_bpp) >> 5 * tile_bpp];
|
||||
dst[6] = p.bgPalette[(ntileword & tile_bpp_mask << 6 * tile_bpp) >> 6 * tile_bpp];
|
||||
dst[7] = p.bgPalette[ ntileword >> 7 * tile_bpp];
|
||||
dst += tile_len;
|
||||
|
||||
unsigned const tno = tileMapLine[tileMapXpos & 0x1F];
|
||||
tileMapXpos = (tileMapXpos & 0x1F) + 1;
|
||||
ntileword = expand_lut[(tileDataLine + tno * 16 - (tno & tileIndexSign) * 32)[0]]
|
||||
+ expand_lut[(tileDataLine + tno * 16 - (tno & tileIndexSign) * 32)[1]] * 2;
|
||||
unsigned const tno = tileMapLine[tileMapXpos % tile_map_len];
|
||||
int const ts = tile_size;
|
||||
tileMapXpos = tileMapXpos % tile_map_len + 1;
|
||||
ntileword = expand_lut[(tileDataLine + ts * tno - 2 * ts * (tno & tileIndexSign))[0]]
|
||||
+ expand_lut[(tileDataLine + ts * tno - 2 * ts * (tno & tileIndexSign))[1]] * 2;
|
||||
} while (dst != dstend);
|
||||
|
||||
p.ntileword = ntileword;
|
||||
@ -422,23 +448,26 @@ void doFullTilesUnrolledDmg(PPUPriv &p, int const xend, uint_least32_t *const db
|
||||
|
||||
{
|
||||
uint_least32_t *const dst = dbufline + (xpos - tile_len);
|
||||
unsigned const tileword = -(p.lcdc & 1u) & p.ntileword;
|
||||
unsigned const tileword = -(p.lcdc & 1u * lcdc_bgen) & p.ntileword;
|
||||
|
||||
dst[0] = p.bgPalette[ tileword & 0x0003 ];
|
||||
dst[1] = p.bgPalette[(tileword & 0x000C) >> 2];
|
||||
dst[2] = p.bgPalette[(tileword & 0x0030) >> 4];
|
||||
dst[3] = p.bgPalette[(tileword & 0x00C0) >> 6];
|
||||
dst[4] = p.bgPalette[(tileword & 0x0300) >> 8];
|
||||
dst[5] = p.bgPalette[(tileword & 0x0C00) >> 10];
|
||||
dst[6] = p.bgPalette[(tileword & 0x3000) >> 12];
|
||||
dst[7] = p.bgPalette[ tileword >> 14];
|
||||
dst[0] = p.bgPalette[ tileword & tile_bpp_mask ];
|
||||
dst[1] = p.bgPalette[(tileword & tile_bpp_mask << 1 * tile_bpp) >> 1 * tile_bpp];
|
||||
dst[2] = p.bgPalette[(tileword & tile_bpp_mask << 2 * tile_bpp) >> 2 * tile_bpp];
|
||||
dst[3] = p.bgPalette[(tileword & tile_bpp_mask << 3 * tile_bpp) >> 3 * tile_bpp];
|
||||
dst[4] = p.bgPalette[(tileword & tile_bpp_mask << 4 * tile_bpp) >> 4 * tile_bpp];
|
||||
dst[5] = p.bgPalette[(tileword & tile_bpp_mask << 5 * tile_bpp) >> 5 * tile_bpp];
|
||||
dst[6] = p.bgPalette[(tileword & tile_bpp_mask << 6 * tile_bpp) >> 6 * tile_bpp];
|
||||
dst[7] = p.bgPalette[ tileword >> 7 * tile_bpp];
|
||||
|
||||
int i = nextSprite - 1;
|
||||
|
||||
if (!lcdcObjEn(p)) {
|
||||
do {
|
||||
int pos = spx(p.spriteList[i]) - xpos;
|
||||
p.spwordList[i] >>= pos * 2 >= 0 ? 16 - pos * 2 : 16 + pos * 2;
|
||||
int const pos = spx(p.spriteList[i]) - xpos;
|
||||
int const sa = pos * tile_bpp >= 0
|
||||
? tile_len * tile_bpp - pos * tile_bpp
|
||||
: tile_len * tile_bpp + pos * tile_bpp;
|
||||
p.spwordList[i] = 1l * p.spwordList[i] >> sa;
|
||||
--i;
|
||||
} while (i >= 0 && spx(p.spriteList[i]) > xpos - tile_len);
|
||||
} else {
|
||||
@ -452,45 +481,47 @@ void doFullTilesUnrolledDmg(PPUPriv &p, int const xend, uint_least32_t *const db
|
||||
n = tile_len - pos;
|
||||
|
||||
unsigned const attrib = p.spriteList[i].attrib;
|
||||
unsigned spword = p.spwordList[i];
|
||||
unsigned long const *const spPalette = p.spPalette + (attrib >> 2 & 4);
|
||||
long spword = p.spwordList[i];
|
||||
unsigned long const *const spPalette = p.spPalette
|
||||
+ (attrib & attr_dmgpalno) / (attr_dmgpalno / num_palette_entries);
|
||||
uint_least32_t *d = dst + pos;
|
||||
|
||||
if (!(attrib & attr_bgpriority)) {
|
||||
int const bpp = tile_bpp, m = tile_bpp_mask;
|
||||
switch (n) {
|
||||
case 8: if (spword >> 14 ) { d[7] = spPalette[spword >> 14 ]; }
|
||||
case 7: if (spword >> 12 & 3) { d[6] = spPalette[spword >> 12 & 3]; }
|
||||
case 6: if (spword >> 10 & 3) { d[5] = spPalette[spword >> 10 & 3]; }
|
||||
case 5: if (spword >> 8 & 3) { d[4] = spPalette[spword >> 8 & 3]; }
|
||||
case 4: if (spword >> 6 & 3) { d[3] = spPalette[spword >> 6 & 3]; }
|
||||
case 3: if (spword >> 4 & 3) { d[2] = spPalette[spword >> 4 & 3]; }
|
||||
case 2: if (spword >> 2 & 3) { d[1] = spPalette[spword >> 2 & 3]; }
|
||||
case 1: if (spword & 3) { d[0] = spPalette[spword & 3]; }
|
||||
case 8: if (spword >> 7 * bpp ) { d[7] = spPalette[spword >> 7 * bpp ]; } // fall through
|
||||
case 7: if (spword >> 6 * bpp & m) { d[6] = spPalette[spword >> 6 * bpp & m]; } // fall through
|
||||
case 6: if (spword >> 5 * bpp & m) { d[5] = spPalette[spword >> 5 * bpp & m]; } // fall through
|
||||
case 5: if (spword >> 4 * bpp & m) { d[4] = spPalette[spword >> 4 * bpp & m]; } // fall through
|
||||
case 4: if (spword >> 3 * bpp & m) { d[3] = spPalette[spword >> 3 * bpp & m]; } // fall through
|
||||
case 3: if (spword >> 2 * bpp & m) { d[2] = spPalette[spword >> 2 * bpp & m]; } // fall through
|
||||
case 2: if (spword >> 1 * bpp & m) { d[1] = spPalette[spword >> 1 * bpp & m]; } // fall through
|
||||
case 1: if (spword & m) { d[0] = spPalette[spword & m]; }
|
||||
}
|
||||
|
||||
spword >>= n * 2;
|
||||
spword >>= n * bpp;
|
||||
|
||||
/*do {
|
||||
if (spword & 3)
|
||||
dst[pos] = spPalette[spword & 3];
|
||||
if (spword & tile_bpp_mask)
|
||||
dst[pos] = spPalette[spword & tile_bpp_mask];
|
||||
|
||||
spword >>= 2;
|
||||
spword >>= tile_bpp;
|
||||
++pos;
|
||||
} while (--n);*/
|
||||
} else {
|
||||
unsigned tw = tileword >> pos * 2;
|
||||
unsigned tw = tileword >> pos * tile_bpp;
|
||||
d += n;
|
||||
n = -n;
|
||||
|
||||
do {
|
||||
if (spword & 3) {
|
||||
d[n] = tw & 3
|
||||
? p.bgPalette[ tw & 3]
|
||||
: spPalette[spword & 3];
|
||||
if (spword & tile_bpp_mask) {
|
||||
d[n] = tw & tile_bpp_mask
|
||||
? p.bgPalette[ tw & tile_bpp_mask]
|
||||
: spPalette[spword & tile_bpp_mask];
|
||||
}
|
||||
|
||||
spword >>= 2;
|
||||
tw >>= 2;
|
||||
spword >>= tile_bpp;
|
||||
tw >>= tile_bpp;
|
||||
} while (++n);
|
||||
}
|
||||
|
||||
@ -500,10 +531,11 @@ void doFullTilesUnrolledDmg(PPUPriv &p, int const xend, uint_least32_t *const db
|
||||
}
|
||||
}
|
||||
|
||||
unsigned const tno = tileMapLine[tileMapXpos & 0x1F];
|
||||
tileMapXpos = (tileMapXpos & 0x1F) + 1;
|
||||
p.ntileword = expand_lut[(tileDataLine + tno * 16 - (tno & tileIndexSign) * 32)[0]]
|
||||
+ expand_lut[(tileDataLine + tno * 16 - (tno & tileIndexSign) * 32)[1]] * 2;
|
||||
unsigned const tno = tileMapLine[tileMapXpos % tile_map_len];
|
||||
int const ts = tile_size;
|
||||
tileMapXpos = tileMapXpos % tile_map_len + 1;
|
||||
p.ntileword = expand_lut[(tileDataLine + ts * tno - 2 * ts * (tno & tileIndexSign))[0]]
|
||||
+ expand_lut[(tileDataLine + ts * tno - 2 * ts * (tno & tileIndexSign))[1]] * 2;
|
||||
|
||||
xpos = xpos + tile_len;
|
||||
} while (xpos < xend);
|
||||
@ -515,7 +547,7 @@ void doFullTilesUnrolledCgb(PPUPriv &p, int const xend, uint_least32_t *const db
|
||||
unsigned char const *const tileMapLine, unsigned const tileline, unsigned tileMapXpos) {
|
||||
int xpos = p.xpos;
|
||||
unsigned char const *const vram = p.vram;
|
||||
unsigned const tdoffset = tileline * 2 + (~p.lcdc & 0x10) * 0x100;
|
||||
unsigned const tdoffset = tileline * tile_line_size + (~p.lcdc & lcdc_tdsel) * 0x100;
|
||||
|
||||
do {
|
||||
int nextSprite = p.nextSprite;
|
||||
@ -523,7 +555,6 @@ void doFullTilesUnrolledCgb(PPUPriv &p, int const xend, uint_least32_t *const db
|
||||
if (spx(p.spriteList[nextSprite]) < xpos + tile_len) {
|
||||
int cycles = p.cycles - tile_len;
|
||||
cycles -= std::max(11 - (spx(p.spriteList[nextSprite]) - xpos), 6);
|
||||
|
||||
for (int i = nextSprite + 1; spx(p.spriteList[i]) < xpos + tile_len; ++i)
|
||||
cycles -= 6;
|
||||
|
||||
@ -534,16 +565,16 @@ void doFullTilesUnrolledCgb(PPUPriv &p, int const xend, uint_least32_t *const db
|
||||
|
||||
do {
|
||||
unsigned char const *const oam = p.spriteMapper.oamram();
|
||||
unsigned reg0, reg1 = oam[p.spriteList[nextSprite].oampos + 2] * 16;
|
||||
unsigned reg0, reg1 = oam[p.spriteList[nextSprite].oampos + 2] * tile_size;
|
||||
unsigned const attrib = oam[p.spriteList[nextSprite].oampos + 3];
|
||||
unsigned const spline = ( attrib & attr_yflip
|
||||
? p.spriteList[nextSprite].line ^ 15
|
||||
: p.spriteList[nextSprite].line ) * 2;
|
||||
|
||||
reg0 = vram[(attrib << 10 & 0x2000)
|
||||
+ (lcdcObj2x(p) ? (reg1 & ~16u) | spline : reg1 | (spline & ~16u)) ];
|
||||
reg1 = vram[(attrib << 10 & 0x2000)
|
||||
+ (lcdcObj2x(p) ? (reg1 & ~16u) | spline : reg1 | (spline & ~16u)) + 1];
|
||||
? p.spriteList[nextSprite].line ^ 2 * tile_len - 1
|
||||
: p.spriteList[nextSprite].line ) * tile_line_size;
|
||||
unsigned const ts = tile_size;
|
||||
reg0 = vram[vram_bank_size / attr_tdbank * (attrib & attr_tdbank)
|
||||
+ (lcdcObj2x(p) ? (reg1 & ~ts) | spline : reg1 | (spline & ~ts)) ];
|
||||
reg1 = vram[vram_bank_size / attr_tdbank * (attrib & attr_tdbank)
|
||||
+ (lcdcObj2x(p) ? (reg1 & ~ts) | spline : reg1 | (spline & ~ts)) + 1];
|
||||
|
||||
p.spwordList[nextSprite] = expand_lut[reg0 + (attrib & attr_xflip) * 8]
|
||||
+ expand_lut[reg1 + (attrib & attr_xflip) * 8] * 2;
|
||||
@ -567,35 +598,35 @@ void doFullTilesUnrolledCgb(PPUPriv &p, int const xend, uint_least32_t *const db
|
||||
xpos += n;
|
||||
|
||||
do {
|
||||
unsigned long const *const bgPalette = p.bgPalette + (nattrib & 7) * 4;
|
||||
dst[0] = bgPalette[ ntileword & 0x0003 ];
|
||||
dst[1] = bgPalette[(ntileword & 0x000C) >> 2];
|
||||
dst[2] = bgPalette[(ntileword & 0x0030) >> 4];
|
||||
dst[3] = bgPalette[(ntileword & 0x00C0) >> 6];
|
||||
dst[4] = bgPalette[(ntileword & 0x0300) >> 8];
|
||||
dst[5] = bgPalette[(ntileword & 0x0C00) >> 10];
|
||||
dst[6] = bgPalette[(ntileword & 0x3000) >> 12];
|
||||
dst[7] = bgPalette[ ntileword >> 14];
|
||||
unsigned long const *const bgPalette = p.bgPalette
|
||||
+ (nattrib & attr_cgbpalno) * num_palette_entries;
|
||||
dst[0] = bgPalette[ ntileword & tile_bpp_mask ];
|
||||
dst[1] = bgPalette[(ntileword & tile_bpp_mask << 1 * tile_bpp) >> 1 * tile_bpp];
|
||||
dst[2] = bgPalette[(ntileword & tile_bpp_mask << 2 * tile_bpp) >> 2 * tile_bpp];
|
||||
dst[3] = bgPalette[(ntileword & tile_bpp_mask << 3 * tile_bpp) >> 3 * tile_bpp];
|
||||
dst[4] = bgPalette[(ntileword & tile_bpp_mask << 4 * tile_bpp) >> 4 * tile_bpp];
|
||||
dst[5] = bgPalette[(ntileword & tile_bpp_mask << 5 * tile_bpp) >> 5 * tile_bpp];
|
||||
dst[6] = bgPalette[(ntileword & tile_bpp_mask << 6 * tile_bpp) >> 6 * tile_bpp];
|
||||
dst[7] = bgPalette[ ntileword >> 7 * tile_bpp];
|
||||
dst += tile_len;
|
||||
|
||||
unsigned const tno = tileMapLine[ tileMapXpos & 0x1F ];
|
||||
nattrib = tileMapLine[(tileMapXpos & 0x1F) + 0x2000];
|
||||
tileMapXpos = (tileMapXpos & 0x1F) + 1;
|
||||
unsigned const tno = tileMapLine[tileMapXpos % tile_map_len ];
|
||||
nattrib = tileMapLine[tileMapXpos % tile_map_len + vram_bank_size];
|
||||
tileMapXpos = tileMapXpos % tile_map_len + 1;
|
||||
|
||||
unsigned const tdo = tdoffset & ~(tno << 5);
|
||||
unsigned char const *const td = vram + tno * 16
|
||||
+ (nattrib & attr_yflip ? tdo ^ 14 : tdo)
|
||||
+ (nattrib << 10 & 0x2000);
|
||||
unsigned char const *const td = vram + tno * tile_size
|
||||
+ (nattrib & attr_yflip ? tdo ^ tile_line_size * (tile_len - 1) : tdo)
|
||||
+ vram_bank_size / attr_tdbank * (nattrib & attr_tdbank);
|
||||
unsigned short const *const explut = expand_lut + (nattrib & attr_xflip) * 8;
|
||||
ntileword = explut[td[0]] + explut[td[1]] * 2;
|
||||
} while (dst != dstend);
|
||||
|
||||
p.ntileword = ntileword;
|
||||
p.nattrib = nattrib;
|
||||
p.nattrib = nattrib;
|
||||
continue;
|
||||
} else {
|
||||
int cycles = p.cycles - tile_len;
|
||||
|
||||
if (cycles < 0)
|
||||
break;
|
||||
|
||||
@ -606,23 +637,26 @@ void doFullTilesUnrolledCgb(PPUPriv &p, int const xend, uint_least32_t *const db
|
||||
uint_least32_t *const dst = dbufline + (xpos - tile_len);
|
||||
unsigned const tileword = p.ntileword;
|
||||
unsigned const attrib = p.nattrib;
|
||||
unsigned long const *const bgPalette = p.bgPalette + (attrib & 7) * 4;
|
||||
|
||||
dst[0] = bgPalette[ tileword & 0x0003 ];
|
||||
dst[1] = bgPalette[(tileword & 0x000C) >> 2];
|
||||
dst[2] = bgPalette[(tileword & 0x0030) >> 4];
|
||||
dst[3] = bgPalette[(tileword & 0x00C0) >> 6];
|
||||
dst[4] = bgPalette[(tileword & 0x0300) >> 8];
|
||||
dst[5] = bgPalette[(tileword & 0x0C00) >> 10];
|
||||
dst[6] = bgPalette[(tileword & 0x3000) >> 12];
|
||||
dst[7] = bgPalette[ tileword >> 14];
|
||||
unsigned long const *const bgPalette = p.bgPalette
|
||||
+ (attrib & attr_cgbpalno) * num_palette_entries;
|
||||
dst[0] = bgPalette[ tileword & tile_bpp_mask ];
|
||||
dst[1] = bgPalette[(tileword & tile_bpp_mask << 1 * tile_bpp) >> 1 * tile_bpp];
|
||||
dst[2] = bgPalette[(tileword & tile_bpp_mask << 2 * tile_bpp) >> 2 * tile_bpp];
|
||||
dst[3] = bgPalette[(tileword & tile_bpp_mask << 3 * tile_bpp) >> 3 * tile_bpp];
|
||||
dst[4] = bgPalette[(tileword & tile_bpp_mask << 4 * tile_bpp) >> 4 * tile_bpp];
|
||||
dst[5] = bgPalette[(tileword & tile_bpp_mask << 5 * tile_bpp) >> 5 * tile_bpp];
|
||||
dst[6] = bgPalette[(tileword & tile_bpp_mask << 6 * tile_bpp) >> 6 * tile_bpp];
|
||||
dst[7] = bgPalette[ tileword >> 7 * tile_bpp];
|
||||
|
||||
int i = nextSprite - 1;
|
||||
|
||||
if (!lcdcObjEn(p)) {
|
||||
do {
|
||||
int pos = spx(p.spriteList[i]) - xpos;
|
||||
p.spwordList[i] >>= pos * 2 >= 0 ? 16 - pos * 2 : 16 + pos * 2;
|
||||
int const pos = spx(p.spriteList[i]) - xpos;
|
||||
int const sa = pos * tile_bpp >= 0
|
||||
? tile_len * tile_bpp - pos * tile_bpp
|
||||
: tile_len * tile_bpp + pos * tile_bpp;
|
||||
p.spwordList[i] = 1l * p.spwordList[i] >> sa;
|
||||
--i;
|
||||
} while (i >= 0 && spx(p.spriteList[i]) > xpos - tile_len);
|
||||
} else {
|
||||
@ -632,7 +666,6 @@ void doFullTilesUnrolledCgb(PPUPriv &p, int const xend, uint_least32_t *const db
|
||||
do {
|
||||
int n;
|
||||
int pos = spx(p.spriteList[i]) - xpos;
|
||||
|
||||
if (pos < 0) {
|
||||
n = pos + tile_len;
|
||||
pos = 0;
|
||||
@ -641,72 +674,73 @@ void doFullTilesUnrolledCgb(PPUPriv &p, int const xend, uint_least32_t *const db
|
||||
|
||||
unsigned char const id = p.spriteList[i].oampos;
|
||||
unsigned const sattrib = p.spriteList[i].attrib;
|
||||
unsigned spword = p.spwordList[i];
|
||||
unsigned long const *const spPalette = p.spPalette + (sattrib & 7) * 4;
|
||||
long spword = p.spwordList[i];
|
||||
unsigned long const *const spPalette = p.spPalette
|
||||
+ (sattrib & attr_cgbpalno) * num_palette_entries;
|
||||
|
||||
if (!((attrib | sattrib) & bgprioritymask)) {
|
||||
unsigned char *const idt = idtab + pos;
|
||||
uint_least32_t *const d = dst + pos;
|
||||
|
||||
switch (n) {
|
||||
case 8: if ((spword >> 14 ) && id < idt[7]) {
|
||||
case 8: if ((spword >> 7 * tile_bpp) && id < idt[7]) {
|
||||
idt[7] = id;
|
||||
d[7] = spPalette[spword >> 14 ];
|
||||
}
|
||||
case 7: if ((spword >> 12 & 3) && id < idt[6]) {
|
||||
d[7] = spPalette[spword >> 7 * tile_bpp];
|
||||
} // fall through
|
||||
case 7: if ((spword >> 6 * tile_bpp & tile_bpp_mask) && id < idt[6]) {
|
||||
idt[6] = id;
|
||||
d[6] = spPalette[spword >> 12 & 3];
|
||||
}
|
||||
case 6: if ((spword >> 10 & 3) && id < idt[5]) {
|
||||
d[6] = spPalette[spword >> 6 * tile_bpp & tile_bpp_mask];
|
||||
} // fall through
|
||||
case 6: if ((spword >> 5 * tile_bpp & tile_bpp_mask) && id < idt[5]) {
|
||||
idt[5] = id;
|
||||
d[5] = spPalette[spword >> 10 & 3];
|
||||
}
|
||||
case 5: if ((spword >> 8 & 3) && id < idt[4]) {
|
||||
d[5] = spPalette[spword >> 5 * tile_bpp & tile_bpp_mask];
|
||||
} // fall through
|
||||
case 5: if ((spword >> 4 * tile_bpp & tile_bpp_mask) && id < idt[4]) {
|
||||
idt[4] = id;
|
||||
d[4] = spPalette[spword >> 8 & 3];
|
||||
}
|
||||
case 4: if ((spword >> 6 & 3) && id < idt[3]) {
|
||||
d[4] = spPalette[spword >> 4 * tile_bpp & tile_bpp_mask];
|
||||
} // fall through
|
||||
case 4: if ((spword >> 3 * tile_bpp & tile_bpp_mask) && id < idt[3]) {
|
||||
idt[3] = id;
|
||||
d[3] = spPalette[spword >> 6 & 3];
|
||||
}
|
||||
case 3: if ((spword >> 4 & 3) && id < idt[2]) {
|
||||
d[3] = spPalette[spword >> 3 * tile_bpp & tile_bpp_mask];
|
||||
} // fall through
|
||||
case 3: if ((spword >> 2 * tile_bpp & tile_bpp_mask) && id < idt[2]) {
|
||||
idt[2] = id;
|
||||
d[2] = spPalette[spword >> 4 & 3];
|
||||
}
|
||||
case 2: if ((spword >> 2 & 3) && id < idt[1]) {
|
||||
d[2] = spPalette[spword >> 2 * tile_bpp & tile_bpp_mask];
|
||||
} // fall through
|
||||
case 2: if ((spword >> 1 * tile_bpp & tile_bpp_mask) && id < idt[1]) {
|
||||
idt[1] = id;
|
||||
d[1] = spPalette[spword >> 2 & 3];
|
||||
}
|
||||
case 1: if ((spword & 3) && id < idt[0]) {
|
||||
d[1] = spPalette[spword >> 1 * tile_bpp & tile_bpp_mask];
|
||||
} // fall through
|
||||
case 1: if ((spword & tile_bpp_mask) && id < idt[0]) {
|
||||
idt[0] = id;
|
||||
d[0] = spPalette[spword & 3];
|
||||
d[0] = spPalette[spword & tile_bpp_mask];
|
||||
}
|
||||
}
|
||||
|
||||
spword >>= n * 2;
|
||||
spword >>= n * tile_bpp;
|
||||
|
||||
/*do {
|
||||
if ((spword & 3) && id < idtab[pos]) {
|
||||
if ((spword & tile_bpp_mask) && id < idtab[pos]) {
|
||||
idtab[pos] = id;
|
||||
dst[pos] = spPalette[spword & 3];
|
||||
dst[pos] = spPalette[spword & tile_bpp_mask];
|
||||
}
|
||||
|
||||
spword >>= 2;
|
||||
spword >>= tile_bpp;
|
||||
++pos;
|
||||
} while (--n);*/
|
||||
} else {
|
||||
unsigned tw = tileword >> pos * 2;
|
||||
unsigned tw = tileword >> pos * tile_bpp;
|
||||
|
||||
do {
|
||||
if ((spword & 3) && id < idtab[pos]) {
|
||||
if ((spword & tile_bpp_mask) && id < idtab[pos]) {
|
||||
idtab[pos] = id;
|
||||
dst[pos] = tw & 3
|
||||
? bgPalette[ tw & 3]
|
||||
: spPalette[spword & 3];
|
||||
dst[pos] = tw & tile_bpp_mask
|
||||
? bgPalette[ tw & tile_bpp_mask]
|
||||
: spPalette[spword & tile_bpp_mask];
|
||||
}
|
||||
|
||||
spword >>= 2;
|
||||
tw >>= 2;
|
||||
spword >>= tile_bpp;
|
||||
tw >>= tile_bpp;
|
||||
++pos;
|
||||
} while (--n);
|
||||
}
|
||||
@ -718,17 +752,17 @@ void doFullTilesUnrolledCgb(PPUPriv &p, int const xend, uint_least32_t *const db
|
||||
}
|
||||
|
||||
{
|
||||
unsigned const tno = tileMapLine[ tileMapXpos & 0x1F ];
|
||||
unsigned const nattrib = tileMapLine[(tileMapXpos & 0x1F) + 0x2000];
|
||||
tileMapXpos = (tileMapXpos & 0x1F) + 1;
|
||||
unsigned const tno = tileMapLine[tileMapXpos % tile_map_len ];
|
||||
unsigned const nattrib = tileMapLine[tileMapXpos % tile_map_len + vram_bank_size];
|
||||
tileMapXpos = tileMapXpos % tile_map_len + 1;
|
||||
|
||||
unsigned const tdo = tdoffset & ~(tno << 5);
|
||||
unsigned char const *const td = vram + tno * 16
|
||||
+ (nattrib & attr_yflip ? tdo ^ 14 : tdo)
|
||||
+ (nattrib << 10 & 0x2000);
|
||||
unsigned char const *const td = vram + tno * tile_size
|
||||
+ (nattrib & attr_yflip ? tdo ^ tile_line_size * (tile_len - 1) : tdo)
|
||||
+ vram_bank_size / attr_tdbank * (nattrib & attr_tdbank);
|
||||
unsigned short const *const explut = expand_lut + (nattrib & attr_xflip) * 8;
|
||||
p.ntileword = explut[td[0]] + explut[td[1]] * 2;
|
||||
p.nattrib = nattrib;
|
||||
p.nattrib = nattrib;
|
||||
}
|
||||
|
||||
xpos = xpos + tile_len;
|
||||
@ -749,22 +783,22 @@ void doFullTilesUnrolled(PPUPriv &p) {
|
||||
unsigned char const *tileMapLine;
|
||||
unsigned tileline;
|
||||
unsigned tileMapXpos;
|
||||
|
||||
if (p.winDrawState & win_draw_started) {
|
||||
tileMapLine = p.vram + (p.lcdc << 4 & 0x400)
|
||||
+ (p.winYPos & 0xF8) * 4 + 0x1800;
|
||||
tileMapLine = p.vram + tile_map_size / lcdc_wtmsel * (p.lcdc & lcdc_wtmsel)
|
||||
+ tile_map_len / tile_len * (p.winYPos & (0x100 - tile_len))
|
||||
+ tile_map_begin;
|
||||
tileMapXpos = (xpos + p.wscx) / (1u * tile_len);
|
||||
tileline = p.winYPos % tile_len;
|
||||
} else {
|
||||
tileMapLine = p.vram + (p.lcdc << 7 & 0x400)
|
||||
+ ((p.scy + p.lyCounter.ly()) & 0xF8) * 4 + 0x1800;
|
||||
tileMapLine = p.vram + tile_map_size / lcdc_bgtmsel * (p.lcdc & lcdc_bgtmsel)
|
||||
+ tile_map_len / tile_len * ((p.scy + p.lyCounter.ly()) & (0x100 - tile_len))
|
||||
+ tile_map_begin;
|
||||
tileMapXpos = (p.scx + xpos + 1 - p.cgb) / (1u * tile_len);
|
||||
tileline = (p.scy + p.lyCounter.ly()) % tile_len;
|
||||
}
|
||||
|
||||
if (xpos < tile_len) {
|
||||
uint_least32_t prebuf[2 * tile_len];
|
||||
|
||||
if (p.cgb) {
|
||||
doFullTilesUnrolledCgb(p, std::min(tile_len, xend), prebuf + (tile_len - xpos),
|
||||
tileMapLine, tileline, tileMapXpos);
|
||||
@ -774,7 +808,6 @@ void doFullTilesUnrolled(PPUPriv &p) {
|
||||
}
|
||||
|
||||
int const newxpos = p.xpos;
|
||||
|
||||
if (newxpos > tile_len) {
|
||||
std::memcpy(dbufline, prebuf + (tile_len - xpos), (newxpos - tile_len) * sizeof *dbufline);
|
||||
} else if (newxpos < tile_len)
|
||||
@ -786,10 +819,9 @@ void doFullTilesUnrolled(PPUPriv &p) {
|
||||
tileMapXpos += (newxpos - xpos) / (1u * tile_len);
|
||||
}
|
||||
|
||||
if (p.cgb) {
|
||||
doFullTilesUnrolledCgb(p, xend, dbufline, tileMapLine, tileline, tileMapXpos);
|
||||
} else
|
||||
doFullTilesUnrolledDmg(p, xend, dbufline, tileMapLine, tileline, tileMapXpos);
|
||||
p.cgb
|
||||
? doFullTilesUnrolledCgb(p, xend, dbufline, tileMapLine, tileline, tileMapXpos)
|
||||
: doFullTilesUnrolledDmg(p, xend, dbufline, tileMapLine, tileline, tileMapXpos);
|
||||
}
|
||||
|
||||
void plotPixel(PPUPriv &p) {
|
||||
@ -807,8 +839,8 @@ void plotPixel(PPUPriv &p) {
|
||||
p.winDrawState |= win_draw_start;
|
||||
}
|
||||
|
||||
unsigned const twdata = tileword & ((p.lcdc & 1) | p.cgb) * 3;
|
||||
unsigned long pixel = p.bgPalette[twdata + (p.attrib & 7) * 4];
|
||||
unsigned const twdata = tileword & ((p.lcdc & lcdc_bgen) | p.cgb) * tile_bpp_mask;
|
||||
unsigned long pixel = p.bgPalette[twdata + (p.attrib & attr_cgbpalno) * num_palette_entries];
|
||||
int i = static_cast<int>(p.nextSprite) - 1;
|
||||
|
||||
if (i >= 0 && spx(p.spriteList[i]) > xpos - tile_len) {
|
||||
@ -819,33 +851,33 @@ void plotPixel(PPUPriv &p) {
|
||||
unsigned minId = 0xFF;
|
||||
|
||||
do {
|
||||
if ((p.spwordList[i] & 3) && p.spriteList[i].oampos < minId) {
|
||||
spdata = p.spwordList[i] & 3;
|
||||
if ((p.spwordList[i] & tile_bpp_mask) && p.spriteList[i].oampos < minId) {
|
||||
spdata = p.spwordList[i] & tile_bpp_mask;
|
||||
attrib = p.spriteList[i].attrib;
|
||||
minId = p.spriteList[i].oampos;
|
||||
}
|
||||
|
||||
p.spwordList[i] >>= 2;
|
||||
p.spwordList[i] >>= tile_bpp;
|
||||
--i;
|
||||
} while (i >= 0 && spx(p.spriteList[i]) > xpos - tile_len);
|
||||
|
||||
if (spdata && lcdcObjEn(p)
|
||||
&& (!((attrib | p.attrib) & attr_bgpriority) || !twdata || !lcdcBgEn(p))) {
|
||||
pixel = p.spPalette[(attrib & 7) * 4 + spdata];
|
||||
pixel = p.spPalette[(attrib & attr_cgbpalno) * num_palette_entries + spdata];
|
||||
}
|
||||
} else {
|
||||
do {
|
||||
if (p.spwordList[i] & 3) {
|
||||
spdata = p.spwordList[i] & 3;
|
||||
if (p.spwordList[i] & tile_bpp_mask) {
|
||||
spdata = p.spwordList[i] & tile_bpp_mask;
|
||||
attrib = p.spriteList[i].attrib;
|
||||
}
|
||||
|
||||
p.spwordList[i] >>= 2;
|
||||
p.spwordList[i] >>= tile_bpp;
|
||||
--i;
|
||||
} while (i >= 0 && spx(p.spriteList[i]) > xpos - tile_len);
|
||||
|
||||
if (spdata && lcdcObjEn(p) && (!(attrib & attr_bgpriority) || !twdata))
|
||||
pixel = p.spPalette[(attrib >> 2 & 4) + spdata];
|
||||
pixel = p.spPalette[(attrib & attr_dmgpalno) / (attr_dmgpalno / num_palette_entries) + spdata];
|
||||
}
|
||||
}
|
||||
|
||||
@ -853,7 +885,7 @@ void plotPixel(PPUPriv &p) {
|
||||
fbline[xpos - tile_len] = pixel;
|
||||
|
||||
p.xpos = xpos + 1;
|
||||
p.tileword = tileword >> 2;
|
||||
p.tileword = tileword >> tile_bpp;
|
||||
}
|
||||
|
||||
void plotPixelIfNoSprite(PPUPriv &p) {
|
||||
@ -935,15 +967,19 @@ namespace StartWindowDraw {
|
||||
p.wscx = tile_len - p.xpos;
|
||||
|
||||
if (p.winDrawState & win_draw_started) {
|
||||
p.reg1 = p.vram[(p.lcdc << 4 & 0x400)
|
||||
+ (p.winYPos & 0xF8) * 4 + 0x1800];
|
||||
p.nattrib = p.vram[(p.lcdc << 4 & 0x400)
|
||||
+ (p.winYPos & 0xF8) * 4 + 0x3800];
|
||||
p.reg1 = p.vram[tile_map_size / lcdc_wtmsel * (p.lcdc & lcdc_wtmsel)
|
||||
+ tile_map_len / tile_len * (p.winYPos & (0x100 - tile_len))
|
||||
+ tile_map_begin];
|
||||
p.nattrib = p.vram[tile_map_size / lcdc_wtmsel * (p.lcdc & lcdc_wtmsel)
|
||||
+ tile_map_len / tile_len * (p.winYPos & (0x100 - tile_len))
|
||||
+ tile_map_begin + vram_bank_size];
|
||||
} else {
|
||||
p.reg1 = p.vram[(p.lcdc << 7 & 0x400)
|
||||
+ ((p.scy + p.lyCounter.ly()) & 0xF8) * 4 + 0x1800];
|
||||
p.nattrib = p.vram[(p.lcdc << 7 & 0x400)
|
||||
+ ((p.scy + p.lyCounter.ly()) & 0xF8) * 4 + 0x3800];
|
||||
p.reg1 = p.vram[tile_map_size / lcdc_bgtmsel * (p.lcdc & lcdc_bgtmsel)
|
||||
+ tile_map_len / tile_len * ((p.scy + p.lyCounter.ly()) & (0x100 - tile_len))
|
||||
+ tile_map_begin];
|
||||
p.nattrib = p.vram[tile_map_size / lcdc_bgtmsel * (p.lcdc & lcdc_bgtmsel)
|
||||
+ tile_map_len / tile_len * ((p.scy + p.lyCounter.ly()) & (0x100 - tile_len))
|
||||
+ tile_map_begin + vram_bank_size];
|
||||
}
|
||||
|
||||
inc(f1_, p);
|
||||
@ -1009,10 +1045,12 @@ namespace LoadSprites {
|
||||
|
||||
unsigned const spline =
|
||||
( p.spriteList[p.currentSprite].attrib & attr_yflip
|
||||
? p.spriteList[p.currentSprite].line ^ 15
|
||||
: p.spriteList[p.currentSprite].line ) * 2;
|
||||
p.reg0 = p.vram[(p.spriteList[p.currentSprite].attrib << 10 & p.cgb * 0x2000)
|
||||
+ (lcdcObj2x(p) ? (p.reg1 * 16 & ~16u) | spline : p.reg1 * 16 | (spline & ~16u))];
|
||||
? p.spriteList[p.currentSprite].line ^ 2 * tile_len - 1
|
||||
: p.spriteList[p.currentSprite].line ) * tile_line_size;
|
||||
unsigned const ts = tile_size;
|
||||
p.reg0 = p.vram[vram_bank_size / attr_tdbank
|
||||
* (p.spriteList[p.currentSprite].attrib & p.cgb * attr_tdbank)
|
||||
+ (lcdcObj2x(p) ? (p.reg1 * ts & ~ts) | spline : p.reg1 * ts | (spline & ~ts))];
|
||||
inc(f3_, p);
|
||||
}
|
||||
|
||||
@ -1029,10 +1067,12 @@ namespace LoadSprites {
|
||||
|
||||
unsigned const spline =
|
||||
( p.spriteList[p.currentSprite].attrib & attr_yflip
|
||||
? p.spriteList[p.currentSprite].line ^ 15
|
||||
: p.spriteList[p.currentSprite].line ) * 2;
|
||||
p.reg1 = p.vram[(p.spriteList[p.currentSprite].attrib << 10 & p.cgb * 0x2000)
|
||||
+ (lcdcObj2x(p) ? (p.reg1 * 16 & ~16u) | spline : p.reg1 * 16 | (spline & ~16u)) + 1];
|
||||
? p.spriteList[p.currentSprite].line ^ 2 * tile_len - 1
|
||||
: p.spriteList[p.currentSprite].line ) * tile_line_size;
|
||||
unsigned const ts = tile_size;
|
||||
p.reg1 = p.vram[vram_bank_size / attr_tdbank
|
||||
* (p.spriteList[p.currentSprite].attrib & p.cgb * attr_tdbank)
|
||||
+ (lcdcObj2x(p) ? (p.reg1 * ts & ~ts) | spline : p.reg1 * ts | (spline & ~ts)) + 1];
|
||||
inc(f5_, p);
|
||||
}
|
||||
|
||||
@ -1093,15 +1133,22 @@ namespace Tile {
|
||||
p.endx = std::min(1u * xpos_end, p.xpos + 1u * tile_len);
|
||||
|
||||
if (p.winDrawState & win_draw_started) {
|
||||
p.reg1 = p.vram[(p.lcdc << 4 & 0x400) + (p.winYPos & 0xF8) * 4
|
||||
+ ((p.xpos + p.wscx) / tile_len & 0x1F) + 0x1800];
|
||||
p.nattrib = p.vram[(p.lcdc << 4 & 0x400) + (p.winYPos & 0xF8) * 4
|
||||
+ ((p.xpos + p.wscx) / tile_len & 0x1F) + 0x3800];
|
||||
p.reg1 = p.vram[tile_map_size / lcdc_wtmsel * (p.lcdc & lcdc_wtmsel)
|
||||
+ tile_map_len / tile_len * (p.winYPos & (0x100 - tile_len))
|
||||
+ (p.xpos + p.wscx) / tile_len % tile_map_len + tile_map_begin];
|
||||
p.nattrib = p.vram[tile_map_size / lcdc_wtmsel * (p.lcdc & lcdc_wtmsel)
|
||||
+ tile_map_len / tile_len * (p.winYPos & (0x100 - tile_len))
|
||||
+ (p.xpos + p.wscx) / tile_len % tile_map_len + tile_map_begin
|
||||
+ vram_bank_size];
|
||||
} else {
|
||||
p.reg1 = p.vram[((p.lcdc << 7 | (p.scx + p.xpos + 1u - p.cgb) / tile_len) & 0x41F)
|
||||
+ ((p.scy + p.lyCounter.ly()) & 0xF8) * 4 + 0x1800];
|
||||
p.nattrib = p.vram[((p.lcdc << 7 | (p.scx + p.xpos + 1u - p.cgb) / tile_len) & 0x41F)
|
||||
+ ((p.scy + p.lyCounter.ly()) & 0xF8) * 4 + 0x3800];
|
||||
p.reg1 = p.vram[((tile_map_size / lcdc_bgtmsel * p.lcdc | (p.scx + p.xpos + 1u - p.cgb) / tile_len)
|
||||
& (tile_map_size + tile_map_len - 1))
|
||||
+ tile_map_len / tile_len * ((p.scy + p.lyCounter.ly()) & (0x100 - tile_len))
|
||||
+ tile_map_begin];
|
||||
p.nattrib = p.vram[((tile_map_size / lcdc_bgtmsel * p.lcdc | (p.scx + p.xpos + 1u - p.cgb) / tile_len)
|
||||
& (tile_map_size + tile_map_len - 1))
|
||||
+ tile_map_len / tile_len * ((p.scy + p.lyCounter.ly()) & (0x100 - tile_len))
|
||||
+ tile_map_begin + vram_bank_size];
|
||||
}
|
||||
|
||||
inc(f1_, p);
|
||||
@ -1275,7 +1322,7 @@ namespace Tile {
|
||||
// because fno will be used.
|
||||
unsigned prevSpriteTileNo = (xpos - firstTileXpos) & -tile_len; // this tile. all sprites on this
|
||||
// tile will now add 6 cycles.
|
||||
// except this one
|
||||
// except this one.
|
||||
if (fno + spx - xpos < 5 && spx <= nwx) {
|
||||
cycles += 11 - (fno + spx - xpos);
|
||||
sprite += 1;
|
||||
@ -1608,7 +1655,7 @@ void loadSpriteList(PPUPriv &p, SaveState const &ss) {
|
||||
unsigned spx = p.spriteMapper.posbuf()[pos + 1];
|
||||
|
||||
p.spriteList[i].spx = spx;
|
||||
p.spriteList[i].line = ly + 16 - spy;
|
||||
p.spriteList[i].line = ly + 2 * tile_len - spy;
|
||||
p.spriteList[i].oampos = pos * 2;
|
||||
p.spriteList[i].attrib = ss.ppu.spAttribList[i] & 0xFF;
|
||||
p.spwordList[i] = (ss.ppu.spByte1List[i] * 0x100 + ss.ppu.spByte0List[i]) & 0xFFFF;
|
||||
|
Loading…
x
Reference in New Issue
Block a user