Several likely/unlikely optimization, saving on a memset
This commit is contained in:
parent
69de3f0fae
commit
c5f6be1e64
@ -912,12 +912,15 @@ static void render_line(GB_gameboy_t *gb)
|
|||||||
unsigned priority:6; // Object priority – 0 in DMG, OAM index in CGB
|
unsigned priority:6; // Object priority – 0 in DMG, OAM index in CGB
|
||||||
unsigned palette:3; // Palette, 0 - 7 (CGB); 0-1 in DMG (or just 0 for BG)
|
unsigned palette:3; // Palette, 0 - 7 (CGB); 0-1 in DMG (or just 0 for BG)
|
||||||
bool bg_priority:1; // BG priority bit
|
bool bg_priority:1; // BG priority bit
|
||||||
} object_buffer[160 + 16]; // allocate extra to avoid per pixel checks
|
} _object_buffer[160 + 16]; // allocate extra to avoid per pixel checks
|
||||||
memset(object_buffer, 0, sizeof(object_buffer));
|
static const uint8_t empty_object_buffer[sizeof(_object_buffer)];
|
||||||
|
const typeof(_object_buffer[0]) *object_buffer;
|
||||||
|
|
||||||
if (gb->n_visible_objs && !gb->objects_disabled && (gb->io_registers[GB_IO_LCDC] & 2)) {
|
if (gb->n_visible_objs && !gb->objects_disabled && (gb->io_registers[GB_IO_LCDC] & 2)) {
|
||||||
|
object_buffer = &_object_buffer[0];
|
||||||
object_t *objects = (object_t *) &gb->oam;
|
object_t *objects = (object_t *) &gb->oam;
|
||||||
|
memset(_object_buffer, 0, sizeof(_object_buffer));
|
||||||
|
|
||||||
while (gb->n_visible_objs) {
|
while (gb->n_visible_objs) {
|
||||||
unsigned object_index = gb->visible_objs[gb->n_visible_objs - 1];
|
unsigned object_index = gb->visible_objs[gb->n_visible_objs - 1];
|
||||||
unsigned priority = gb->object_priority == GB_OBJECT_PRIORITY_X? 0 : object_index;
|
unsigned priority = gb->object_priority == GB_OBJECT_PRIORITY_X? 0 : object_index;
|
||||||
@ -932,7 +935,7 @@ static void render_line(GB_gameboy_t *gb)
|
|||||||
data1 = flip(data1);
|
data1 = flip(data1);
|
||||||
}
|
}
|
||||||
|
|
||||||
typeof(object_buffer[0]) *p = object_buffer + object->x;
|
typeof(_object_buffer[0]) *p = _object_buffer + object->x;
|
||||||
if (object->x >= 168) {
|
if (object->x >= 168) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
@ -956,6 +959,9 @@ static void render_line(GB_gameboy_t *gb)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
else {
|
||||||
|
object_buffer = (const void *)empty_object_buffer;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
uint32_t *restrict p = gb->screen;
|
uint32_t *restrict p = gb->screen;
|
||||||
@ -1069,11 +1075,14 @@ static void render_line_sgb(GB_gameboy_t *gb)
|
|||||||
unsigned pixel:2; // Color, 0-3
|
unsigned pixel:2; // Color, 0-3
|
||||||
unsigned palette:1; // Palette, 0 - 7 (CGB); 0-1 in DMG (or just 0 for BG)
|
unsigned palette:1; // Palette, 0 - 7 (CGB); 0-1 in DMG (or just 0 for BG)
|
||||||
bool bg_priority:1; // BG priority bit
|
bool bg_priority:1; // BG priority bit
|
||||||
} object_buffer[160 + 16]; // allocate extra to avoid per pixel checks
|
} _object_buffer[160 + 16]; // allocate extra to avoid per pixel checks
|
||||||
memset(object_buffer, 0, sizeof(object_buffer));
|
static const uint8_t empty_object_buffer[sizeof(_object_buffer)];
|
||||||
|
const typeof(_object_buffer[0]) *object_buffer;
|
||||||
|
|
||||||
if (gb->n_visible_objs && !gb->objects_disabled && (gb->io_registers[GB_IO_LCDC] & 2)) {
|
if (gb->n_visible_objs && !gb->objects_disabled && (gb->io_registers[GB_IO_LCDC] & 2)) {
|
||||||
|
object_buffer = &_object_buffer[0];
|
||||||
object_t *objects = (object_t *) &gb->oam;
|
object_t *objects = (object_t *) &gb->oam;
|
||||||
|
memset(_object_buffer, 0, sizeof(_object_buffer));
|
||||||
|
|
||||||
while (gb->n_visible_objs) {
|
while (gb->n_visible_objs) {
|
||||||
const object_t *object = &objects[gb->visible_objs[gb->n_visible_objs - 1]];
|
const object_t *object = &objects[gb->visible_objs[gb->n_visible_objs - 1]];
|
||||||
@ -1087,7 +1096,7 @@ static void render_line_sgb(GB_gameboy_t *gb)
|
|||||||
data1 = flip(data1);
|
data1 = flip(data1);
|
||||||
}
|
}
|
||||||
|
|
||||||
typeof(object_buffer[0]) *p = object_buffer + object->x;
|
typeof(_object_buffer[0]) *p = _object_buffer + object->x;
|
||||||
if (object->x >= 168) {
|
if (object->x >= 168) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
@ -1104,6 +1113,9 @@ static void render_line_sgb(GB_gameboy_t *gb)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
else {
|
||||||
|
object_buffer = (const void *)empty_object_buffer;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
uint8_t *restrict p = gb->sgb->screen_buffer;
|
uint8_t *restrict p = gb->sgb->screen_buffer;
|
||||||
|
@ -1648,7 +1648,7 @@ void GB_write_memory(GB_gameboy_t *gb, uint16_t addr, uint8_t value)
|
|||||||
|
|
||||||
void GB_dma_run(GB_gameboy_t *gb)
|
void GB_dma_run(GB_gameboy_t *gb)
|
||||||
{
|
{
|
||||||
while (gb->dma_cycles >= 4 && gb->dma_steps_left) {
|
while (unlikely(gb->dma_cycles >= 4 && gb->dma_steps_left)) {
|
||||||
/* Todo: measure this value */
|
/* Todo: measure this value */
|
||||||
gb->dma_cycles -= 4;
|
gb->dma_cycles -= 4;
|
||||||
gb->dma_steps_left--;
|
gb->dma_steps_left--;
|
||||||
@ -1671,7 +1671,7 @@ void GB_dma_run(GB_gameboy_t *gb)
|
|||||||
|
|
||||||
void GB_hdma_run(GB_gameboy_t *gb)
|
void GB_hdma_run(GB_gameboy_t *gb)
|
||||||
{
|
{
|
||||||
if (!gb->hdma_on) return;
|
if (likely(!gb->hdma_on)) return;
|
||||||
|
|
||||||
while (gb->hdma_cycles >= 0x4) {
|
while (gb->hdma_cycles >= 0x4) {
|
||||||
gb->hdma_cycles -= 0x4;
|
gb->hdma_cycles -= 0x4;
|
||||||
|
@ -113,7 +113,7 @@ void GB_timing_sync(GB_gameboy_t *gb)
|
|||||||
|
|
||||||
static void ir_run(GB_gameboy_t *gb, uint32_t cycles)
|
static void ir_run(GB_gameboy_t *gb, uint32_t cycles)
|
||||||
{
|
{
|
||||||
if (gb->model == GB_MODEL_AGB) return;
|
if ((gb->model == GB_MODEL_AGB || !gb->cgb_mode) && gb->cartridge_type->mbc_type != GB_HUC1 && gb->cartridge_type->mbc_type != GB_HUC3) return;
|
||||||
if (gb->infrared_input || gb->cart_ir || (gb->io_registers[GB_IO_RP] & 1)) {
|
if (gb->infrared_input || gb->cart_ir || (gb->io_registers[GB_IO_RP] & 1)) {
|
||||||
gb->ir_sensor += cycles;
|
gb->ir_sensor += cycles;
|
||||||
if (gb->ir_sensor > IR_MAX) {
|
if (gb->ir_sensor > IR_MAX) {
|
||||||
@ -203,10 +203,10 @@ static void timers_run(GB_gameboy_t *gb, uint8_t cycles)
|
|||||||
|
|
||||||
static void advance_serial(GB_gameboy_t *gb, uint8_t cycles)
|
static void advance_serial(GB_gameboy_t *gb, uint8_t cycles)
|
||||||
{
|
{
|
||||||
if (gb->printer.command_state || gb->printer.bits_received) {
|
if (unlikely(gb->printer_callback && (gb->printer.command_state || gb->printer.bits_received))) {
|
||||||
gb->printer.idle_time += cycles;
|
gb->printer.idle_time += cycles;
|
||||||
}
|
}
|
||||||
if (gb->serial_length == 0) {
|
if (likely(gb->serial_length == 0)) {
|
||||||
gb->serial_cycles += cycles;
|
gb->serial_cycles += cycles;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@ -270,7 +270,7 @@ void GB_set_rtc_multiplier(GB_gameboy_t *gb, double multiplier)
|
|||||||
|
|
||||||
static void rtc_run(GB_gameboy_t *gb, uint8_t cycles)
|
static void rtc_run(GB_gameboy_t *gb, uint8_t cycles)
|
||||||
{
|
{
|
||||||
if (gb->cartridge_type->mbc_type != GB_HUC3 && !gb->cartridge_type->has_rtc) return;
|
if (likely(gb->cartridge_type->mbc_type != GB_HUC3 && !gb->cartridge_type->has_rtc)) return;
|
||||||
gb->rtc_cycles += cycles;
|
gb->rtc_cycles += cycles;
|
||||||
time_t current_time = 0;
|
time_t current_time = 0;
|
||||||
uint32_t rtc_second_length = unlikely(gb->rtc_second_length)? gb->rtc_second_length : GB_get_unmultiplied_clock_rate(gb) * 2;
|
uint32_t rtc_second_length = unlikely(gb->rtc_second_length)? gb->rtc_second_length : GB_get_unmultiplied_clock_rate(gb) * 2;
|
||||||
@ -368,7 +368,7 @@ static void rtc_run(GB_gameboy_t *gb, uint8_t cycles)
|
|||||||
|
|
||||||
void GB_advance_cycles(GB_gameboy_t *gb, uint8_t cycles)
|
void GB_advance_cycles(GB_gameboy_t *gb, uint8_t cycles)
|
||||||
{
|
{
|
||||||
if (gb->speed_switch_countdown) {
|
if (unlikely(gb->speed_switch_countdown)) {
|
||||||
if (gb->speed_switch_countdown == cycles) {
|
if (gb->speed_switch_countdown == cycles) {
|
||||||
gb->cgb_double_speed ^= true;
|
gb->cgb_double_speed ^= true;
|
||||||
gb->speed_switch_countdown = 0;
|
gb->speed_switch_countdown = 0;
|
||||||
@ -389,11 +389,11 @@ void GB_advance_cycles(GB_gameboy_t *gb, uint8_t cycles)
|
|||||||
gb->dma_cycles += cycles;
|
gb->dma_cycles += cycles;
|
||||||
|
|
||||||
timers_run(gb, cycles);
|
timers_run(gb, cycles);
|
||||||
if (!gb->stopped) {
|
if (unlikely(!gb->stopped)) {
|
||||||
advance_serial(gb, cycles); // TODO: Verify what happens in STOP mode
|
advance_serial(gb, cycles); // TODO: Verify what happens in STOP mode
|
||||||
}
|
}
|
||||||
|
|
||||||
if (gb->speed_switch_halt_countdown) {
|
if (unlikely(gb->speed_switch_halt_countdown)) {
|
||||||
gb->speed_switch_halt_countdown -= cycles;
|
gb->speed_switch_halt_countdown -= cycles;
|
||||||
if (gb->speed_switch_halt_countdown <= 0) {
|
if (gb->speed_switch_halt_countdown <= 0) {
|
||||||
gb->speed_switch_halt_countdown = 0;
|
gb->speed_switch_halt_countdown = 0;
|
||||||
@ -412,14 +412,14 @@ void GB_advance_cycles(GB_gameboy_t *gb, uint8_t cycles)
|
|||||||
gb->speed_switch_freeze = 0;
|
gb->speed_switch_freeze = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!gb->cgb_double_speed) {
|
if (unlikely(!gb->cgb_double_speed)) {
|
||||||
cycles <<= 1;
|
cycles <<= 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
gb->absolute_debugger_ticks += cycles;
|
gb->absolute_debugger_ticks += cycles;
|
||||||
|
|
||||||
// Not affected by speed boost
|
// Not affected by speed boost
|
||||||
if (gb->io_registers[GB_IO_LCDC] & 0x80) {
|
if (likely(gb->io_registers[GB_IO_LCDC] & 0x80)) {
|
||||||
gb->double_speed_alignment += cycles;
|
gb->double_speed_alignment += cycles;
|
||||||
}
|
}
|
||||||
gb->hdma_cycles += cycles;
|
gb->hdma_cycles += cycles;
|
||||||
@ -430,7 +430,7 @@ void GB_advance_cycles(GB_gameboy_t *gb, uint8_t cycles)
|
|||||||
gb->rumble_on_cycles += gb->rumble_strength & 3;
|
gb->rumble_on_cycles += gb->rumble_strength & 3;
|
||||||
gb->rumble_off_cycles += (gb->rumble_strength & 3) ^ 3;
|
gb->rumble_off_cycles += (gb->rumble_strength & 3) ^ 3;
|
||||||
|
|
||||||
if (!gb->stopped) { // TODO: Verify what happens in STOP mode
|
if (unlikely(!gb->stopped)) { // TODO: Verify what happens in STOP mode
|
||||||
GB_dma_run(gb);
|
GB_dma_run(gb);
|
||||||
GB_hdma_run(gb);
|
GB_hdma_run(gb);
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user