From df8a5cbe6d747a17df47df8801d9f5c681aa7018 Mon Sep 17 00:00:00 2001 From: Thomas Harte Date: Sun, 12 Feb 2017 17:35:09 -0500 Subject: [PATCH] Made attempts (i) to respect the delay flag; and (ii) to account for border-region sprite clocking. --- Machines/Atari2600/TIA.cpp | 36 ++++++++++++++++++++++++++---------- Machines/Atari2600/TIA.hpp | 3 ++- 2 files changed, 28 insertions(+), 11 deletions(-) diff --git a/Machines/Atari2600/TIA.cpp b/Machines/Atari2600/TIA.cpp index d351d731d..3698ddfd3 100644 --- a/Machines/Atari2600/TIA.cpp +++ b/Machines/Atari2600/TIA.cpp @@ -289,7 +289,8 @@ void TIA::set_player_number_and_size(int player, uint8_t value) void TIA::set_player_graphic(int player, uint8_t value) { - player_[player].graphic = value; + player_[player].graphic[player_[player].graphic_delay ? 1 : 0] = value; + player_[player^1].graphic[0] = player_[player^1].graphic[1]; } void TIA::set_player_reflected(int player, bool reflected) @@ -299,7 +300,7 @@ void TIA::set_player_reflected(int player, bool reflected) void TIA::set_player_delay(int player, bool delay) { - // TODO + player_[player].graphic_delay = delay; } void TIA::set_player_position(int player) @@ -611,7 +612,19 @@ void TIA::draw_player(Player &player, CollisionType collision_identity, const in // movement works across the entire screen, so do work that falls outside of the pixel area int movement_time; - perform_border_motion(position_identity, start, end, movement_time); + int adder = 4 >> player.size; + int added = perform_border_motion(position_identity, start, end, movement_time); + if(player.output_delay > 0) + { + int delay_distance = std::min(player.output_delay, added); + player.output_delay -= delay_distance; + added -= delay_distance; + if(!player.output_delay) player.pixel_position = 0; + } + if(player.pixel_position < 32) + { + player.pixel_position += added * adder; + } // don't continue to do any drawing if this window ends too early int first_pixel = first_pixel_cycle + (horizontal_blank_extend_ ? 8 : 0); @@ -619,7 +632,7 @@ void TIA::draw_player(Player &player, CollisionType collision_identity, const in if(start < first_pixel) start = first_pixel; // perform a miniature event loop on (i) triggering draws; (ii) drawing; and (iii) motion - if(is_moving_[position_identity] || player.graphic) + if(is_moving_[position_identity] || player.graphic[0]) { while(start < end) { @@ -633,15 +646,19 @@ void TIA::draw_player(Player &player, CollisionType collision_identity, const in // is the next event a graphics trigger? int next_copy = 160; - if(player.graphic) + if(player.graphic[0]) { if(position < 16 && player.copy_flags&1) { next_copy = 16; - } else if(position < 32 && player.copy_flags&2) + } + else + if(position < 32 && player.copy_flags&2) { next_copy = 32; - } else if(position < 64 && player.copy_flags&4) + } + else + if(position < 64 && player.copy_flags&4) { next_copy = 64; } @@ -661,13 +678,12 @@ void TIA::draw_player(Player &player, CollisionType collision_identity, const in if(player.pixel_position < 32) { - int adder = 4 >> player.size; -// player.pixel_position &= ~(adder - 1); + player.pixel_position &= ~(adder - 1); int output_cursor = 0; while(player.pixel_position < 32 && output_cursor < length) { int shift = (player.pixel_position >> 2) ^ player.reverse_mask; - collision_buffer_[start + output_cursor - first_pixel_cycle] |= ((player.graphic >> shift)&1) * (uint8_t)collision_identity; + collision_buffer_[start + output_cursor - first_pixel_cycle] |= ((player.graphic[0] >> shift)&1) * (uint8_t)collision_identity; output_cursor++; player.pixel_position += adder; } diff --git a/Machines/Atari2600/TIA.hpp b/Machines/Atari2600/TIA.hpp index 25b214ba6..3fa4e3a30 100644 --- a/Machines/Atari2600/TIA.hpp +++ b/Machines/Atari2600/TIA.hpp @@ -132,11 +132,12 @@ class TIA { struct Player { int size; // 0 = normal, 1 = double, 2 = quad int copy_flags; // a bit field, corresponding to the first few values of NUSIZ - uint8_t graphic; // the player graphic + uint8_t graphic[2]; // the player graphic int reverse_mask; // 7 for a reflected player, 0 for normal int pixel_position; int output_delay; + bool graphic_delay; } player_[2]; // missile state