找到了inline的漏网之鱼了,赶紧加上

This commit is contained in:
root 2024-05-13 00:35:16 +08:00
parent 5abde8b8c2
commit 27fc7c07df

View File

@ -101,18 +101,18 @@ void PPU::DrawSpriteFetchOAM(uint cycle) {
auto& drawer_state = sprite.drawer_state[sprite.state_wr];
const auto Submit = [&]() {
// Swap the draw states and engage the drawer unit.
sprite.state_rd ^= 1;
sprite.state_wr ^= 1;
sprite.drawing = true;
// const auto Submit = [&]() {
// // Swap the draw states and engage the drawer unit.
// sprite.state_rd ^= 1;
// sprite.state_wr ^= 1;
// sprite.drawing = true;
// Start fetching the next OAM entry
oam_fetch.index++;
oam_fetch.step = 0;
oam_fetch.wait = oam_fetch.pending_wait;
oam_fetch.delay_wait = true;
};
// // Start fetching the next OAM entry
// oam_fetch.index++;
// oam_fetch.step = 0;
// oam_fetch.wait = oam_fetch.pending_wait;
// oam_fetch.delay_wait = true;
// };
const int step = oam_fetch.step;
@ -237,7 +237,16 @@ void PPU::DrawSpriteFetchOAM(uint cycle) {
if(drawer_state.affine) {
oam_fetch.step = 2;
} else {
Submit();
//Submit();
sprite.state_rd ^= 1;
sprite.state_wr ^= 1;
sprite.drawing = true;
// Start fetching the next OAM entry
oam_fetch.index++;
oam_fetch.step = 0;
oam_fetch.wait = oam_fetch.pending_wait;
oam_fetch.delay_wait = true;
}
break;
}
@ -257,13 +266,52 @@ void PPU::DrawSpriteFetchOAM(uint cycle) {
drawer_state.texture_x = (drawer_state.matrix[0] * x0 + drawer_state.matrix[1] * y0) + (drawer_state.width << 7);
drawer_state.texture_y = (drawer_state.matrix[2] * x0 + drawer_state.matrix[3] * y0) + (drawer_state.height << 7);
Submit();
//Submit();
{
sprite.state_rd ^= 1;
sprite.state_wr ^= 1;
sprite.drawing = true;
// Start fetching the next OAM entry
oam_fetch.index++;
oam_fetch.step = 0;
oam_fetch.wait = oam_fetch.pending_wait;
oam_fetch.delay_wait = true;
}
}
break;
}
}
}
ALWAYS_INLINE auto CalculateTileNumber4BPP(int cond, uint base_tile, int width, int block_x, int block_y) -> uint {
// @todo: can the OAM mapping be changed mid-scanline? what would that do?
//if(mmio.dispcnt.oam_mapping_1d) {
if( cond ){
return (base_tile + block_y * ((uint)width >> 3) + block_x) & 0x3FFU;
}
return ((base_tile + (block_y << 5)) & 0x3E0U) | ((base_tile + block_x) & 0x1FU);
}
ALWAYS_INLINE auto CalculateTileNumber8BPP(int cond, uint base_tile, int width, int block_x, int block_y) -> uint {
// @todo: can the OAM mapping be changed mid-scanline? what would that do?
// if(mmio.dispcnt.oam_mapping_1d) {
if( cond ){
return (base_tile + block_y * ((uint)width >> 2) + (block_x << 1)) & 0x3FFU;
}
return ((base_tile + (block_y << 5)) & 0x3E0U) | (((base_tile & ~1) + (block_x << 1)) & 0x1FU);
}
ALWAYS_INLINE auto CalculateAddress4BPP(uint tile, int tile_x, int tile_y) -> uint {
return 0x10000U + (tile << 5) + (tile_y << 2) + (tile_x >> 1);
}
ALWAYS_INLINE auto CalculateAddress8BPP(uint tile, int tile_x, int tile_y) -> uint {
return 0x10000U + (tile << 5) + (tile_y << 3) + tile_x;
}
void PPU::DrawSpriteFetchVRAM(uint cycle) {
if(!sprite.drawing) {
return;
@ -276,57 +324,58 @@ void PPU::DrawSpriteFetchVRAM(uint cycle) {
const uint base_tile = drawer_state.tile_number;
const auto CalculateTileNumber4BPP = [&](int block_x, int block_y) -> uint {
// @todo: can the OAM mapping be changed mid-scanline? what would that do?
if(mmio.dispcnt.oam_mapping_1d) {
return (base_tile + block_y * ((uint)width >> 3) + block_x) & 0x3FFU;
}
// 这五个函数可以inline也应该inline的用lambda是暴殄天物
// const auto CalculateTileNumber4BPP = [&](int block_x, int block_y) -> uint {
// // @todo: can the OAM mapping be changed mid-scanline? what would that do?
// if(mmio.dispcnt.oam_mapping_1d) {
// return (base_tile + block_y * ((uint)width >> 3) + block_x) & 0x3FFU;
// }
return ((base_tile + (block_y << 5)) & 0x3E0U) | ((base_tile + block_x) & 0x1FU);
};
// return ((base_tile + (block_y << 5)) & 0x3E0U) | ((base_tile + block_x) & 0x1FU);
// };
const auto CalculateTileNumber8BPP = [&](int block_x, int block_y) -> uint {
// @todo: can the OAM mapping be changed mid-scanline? what would that do?
if(mmio.dispcnt.oam_mapping_1d) {
return (base_tile + block_y * ((uint)width >> 2) + (block_x << 1)) & 0x3FFU;
}
// const auto CalculateTileNumber8BPP = [&](int block_x, int block_y) -> uint {
// // @todo: can the OAM mapping be changed mid-scanline? what would that do?
// if(mmio.dispcnt.oam_mapping_1d) {
// return (base_tile + block_y * ((uint)width >> 2) + (block_x << 1)) & 0x3FFU;
// }
return ((base_tile + (block_y << 5)) & 0x3E0U) | (((base_tile & ~1) + (block_x << 1)) & 0x1FU);
};
// return ((base_tile + (block_y << 5)) & 0x3E0U) | (((base_tile & ~1) + (block_x << 1)) & 0x1FU);
// };
const auto CalculateAddress4BPP = [&](uint tile, int tile_x, int tile_y) -> uint {
return 0x10000U + (tile << 5) + (tile_y << 2) + (tile_x >> 1);
};
// const auto CalculateAddress4BPP = [&](uint tile, int tile_x, int tile_y) -> uint {
// return 0x10000U + (tile << 5) + (tile_y << 2) + (tile_x >> 1);
// };
const auto CalculateAddress8BPP = [&](uint tile, int tile_x, int tile_y) -> uint {
return 0x10000U + (tile << 5) + (tile_y << 3) + tile_x;
};
// const auto CalculateAddress8BPP = [&](uint tile, int tile_x, int tile_y) -> uint {
// return 0x10000U + (tile << 5) + (tile_y << 3) + tile_x;
// };
const auto Plot = [&](int x, uint color) {
if(x < 0 || x >= 240) return;
// const auto Plot = [&](int x, uint color) {
// if(x < 0 || x >= 240) return;
auto& pixel = sprite.buffer_wr[x];
// auto& pixel = sprite.buffer_wr[x];
const bool opaque = color != 0U;
const auto mode = drawer_state.mode;
const uint priority = drawer_state.priority;
// const bool opaque = color != 0U;
// const auto mode = drawer_state.mode;
// const uint priority = drawer_state.priority;
/**
* Transparent/outside OBJ window pixels are treated the same as
* normal/semi-transparent sprite pixels, meaning that (unlike opaque/inside OBJ window pixels) they
* update the mosaic and priority attributes.
*/
if(mode == OBJ_WINDOW && opaque) {
pixel.window = 1;
} else if(priority < pixel.priority || pixel.color == 0U) {
if(opaque) {
pixel.color = color;
pixel.alpha = (mode == OBJ_SEMI) ? 1U : 0U;
}
pixel.mosaic = drawer_state.mosaic ? 1U : 0U;
pixel.priority = priority;
}
};
// /**
// * Transparent/outside OBJ window pixels are treated the same as
// * normal/semi-transparent sprite pixels, meaning that (unlike opaque/inside OBJ window pixels) they
// * update the mosaic and priority attributes.
// */
// if(mode == OBJ_WINDOW && opaque) {
// pixel.window = 1;
// } else if(priority < pixel.priority || pixel.color == 0U) {
// if(opaque) {
// pixel.color = color;
// pixel.alpha = (mode == OBJ_SEMI) ? 1U : 0U;
// }
// pixel.mosaic = drawer_state.mosaic ? 1U : 0U;
// pixel.priority = priority;
// }
// };
if(drawer_state.affine) {
if(sprite.oam_fetch.delay_wait) {
@ -336,8 +385,9 @@ void PPU::DrawSpriteFetchVRAM(uint cycle) {
const int texture_x = drawer_state.texture_x >> 8;
const int texture_y = drawer_state.texture_y >> 8;
if(texture_x >= 0 && texture_x < width &&
texture_y >= 0 && texture_y < height) {
// if(texture_x >= 0 && texture_x < width &&
// texture_y >= 0 && texture_y < height) {
if( (texture_x | (width-1-texture_x) | texture_y | (height-1-texture_y) ) > 0 ){
const int tile_x = texture_x & 7;
const int tile_y = texture_y & 7;
@ -347,11 +397,11 @@ void PPU::DrawSpriteFetchVRAM(uint cycle) {
uint color_index = 0U;
if(drawer_state.is_256) {
const uint tile = CalculateTileNumber8BPP(block_x, block_y);
const uint tile = CalculateTileNumber8BPP(mmio.dispcnt.oam_mapping_1d, base_tile, width, block_x, block_y);
color_index = FetchVRAM_OBJ<u8>(cycle, CalculateAddress8BPP(tile, tile_x, tile_y));
} else {
const uint tile = CalculateTileNumber4BPP(block_x, block_y);
const uint tile = CalculateTileNumber4BPP(mmio.dispcnt.oam_mapping_1d, base_tile, width, block_x, block_y);
const u8 data = FetchVRAM_OBJ<u8>(cycle, CalculateAddress4BPP(tile, tile_x, tile_y));
if(tile_x & 1U) {
@ -365,7 +415,34 @@ void PPU::DrawSpriteFetchVRAM(uint cycle) {
}
}
Plot(drawer_state.draw_x, color_index);
// Plot(drawer_state.draw_x, color_index);
{
auto x = drawer_state.draw_x;
auto color = color_index;
if( ( x | ((int)239-x) ) > 0 ) {
auto& pixel = sprite.buffer_wr[x];
const bool opaque = color != 0U;
const auto mode = drawer_state.mode;
const uint priority = drawer_state.priority;
/**
* Transparent/outside OBJ window pixels are treated the same as
* normal/semi-transparent sprite pixels, meaning that (unlike opaque/inside OBJ window pixels) they
* update the mosaic and priority attributes.
*/
if(mode == OBJ_WINDOW && opaque) {
pixel.window = 1;
} else if(priority < pixel.priority || pixel.color == 0U) {
if(opaque) {
pixel.color = color;
pixel.alpha = (mode == OBJ_SEMI) ? 1U : 0U;
}
pixel.mosaic = drawer_state.mosaic ? 1U : 0U;
pixel.priority = priority;
}
}
}
}
drawer_state.draw_x++;
@ -389,7 +466,7 @@ void PPU::DrawSpriteFetchVRAM(uint cycle) {
uint color_indices[2] {0, 0};
if(drawer_state.is_256) {
const uint tile = CalculateTileNumber8BPP(block_x, block_y);
const uint tile = CalculateTileNumber8BPP(mmio.dispcnt.oam_mapping_1d, base_tile, width, block_x, block_y);
const u16 data = FetchVRAM_OBJ<u16>(cycle, CalculateAddress8BPP(tile, tile_x, tile_y));
if(flip_h) {
@ -402,7 +479,7 @@ void PPU::DrawSpriteFetchVRAM(uint cycle) {
palette = 0U;
} else {
const uint tile = CalculateTileNumber4BPP(block_x, block_y);
const uint tile = CalculateTileNumber4BPP(mmio.dispcnt.oam_mapping_1d, base_tile, width, block_x, block_y);
const u8 data = FetchVRAM_OBJ<u8>(cycle, CalculateAddress4BPP(tile, tile_x, tile_y));
if(flip_h) {
@ -423,7 +500,35 @@ void PPU::DrawSpriteFetchVRAM(uint cycle) {
color_index |= palette;
}
Plot(drawer_state.draw_x++, color_index);
//Plot(drawer_state.draw_x++, color_index);
{
auto x = drawer_state.draw_x++;
auto color = color_index;
if( ( x | ((int)239-x) ) > 0 ) {
auto& pixel = sprite.buffer_wr[x];
const bool opaque = color != 0U;
const auto mode = drawer_state.mode;
const uint priority = drawer_state.priority;
/**
* Transparent/outside OBJ window pixels are treated the same as
* normal/semi-transparent sprite pixels, meaning that (unlike opaque/inside OBJ window pixels) they
* update the mosaic and priority attributes.
*/
if(mode == OBJ_WINDOW && opaque) {
pixel.window = 1;
} else if(priority < pixel.priority || pixel.color == 0U) {
if(opaque) {
pixel.color = color;
pixel.alpha = (mode == OBJ_SEMI) ? 1U : 0U;
}
pixel.mosaic = drawer_state.mosaic ? 1U : 0U;
pixel.priority = priority;
}
}
}
}
drawer_state.texture_x += 2;