From 6bcf95042cde0cfbd26b152cf09a473fcfa06791 Mon Sep 17 00:00:00 2001 From: Thomas Harte Date: Sun, 5 Feb 2017 17:51:56 -0500 Subject: [PATCH] Started trying to be a bit more explicit about usage, and to divide up drawing responsibility. --- Machines/Atari2600/TIA.cpp | 30 +++++++++++++++++++++++------- Machines/Atari2600/TIA.hpp | 23 +++++++++++++++++++---- 2 files changed, 42 insertions(+), 11 deletions(-) diff --git a/Machines/Atari2600/TIA.cpp b/Machines/Atari2600/TIA.cpp index 8398e8ca0..6a8888cac 100644 --- a/Machines/Atari2600/TIA.cpp +++ b/Machines/Atari2600/TIA.cpp @@ -126,7 +126,7 @@ void TIA::reset_horizontal_counter() int TIA::get_cycles_until_horizontal_blank(unsigned int from_offset) { - return cycles_per_line - (horizontal_counter_ + (int)from_offset) % cycles_per_line; + return 4 + (cycles_per_line - (horizontal_counter_ + (int)from_offset) % cycles_per_line); } void TIA::set_background_colour(uint8_t colour) @@ -156,6 +156,8 @@ void TIA::set_playfield(uint16_t offset, uint8_t value) void TIA::set_playfield_control_and_ball_size(uint8_t value) { background_half_mask_ = value & 1; + playfield_is_above_players_ = !!(value & 4); + playfield_is_in_score_mode_ = !playfield_is_above_players_ && (value & 2); } void TIA::set_playfield_ball_colour(uint8_t colour) @@ -338,12 +340,8 @@ void TIA::output_for_cycles(int number_of_cycles) } if(pixel_target_) { - while(output_cursor < horizontal_counter_) - { - int offset = (output_cursor - 68) >> 2; - pixel_target_[output_cursor - pixel_target_origin_] = ((background_[(offset/20)&background_half_mask_] >> (offset%20))&1) ? playfield_ball_colour_ : background_colour_; - output_cursor++; - } + draw_background(pixel_target_, output_cursor, horizontal_counter_); + output_cursor = horizontal_counter_; } else output_cursor = horizontal_counter_; if(horizontal_counter_ == cycles_per_line) { @@ -377,3 +375,21 @@ void TIA::output_line() break; } } + +#pragma mark - Background and playfield + +void TIA::draw_background(uint8_t *target, int start, int length) const +{ + if(!target) return; + int position = start; + while(length--) + { + int offset = (position - 68) >> 2; + target[position - pixel_target_origin_] = ((background_[(offset/20)&background_half_mask_] >> (offset%20))&1) ? playfield_ball_colour_ : background_colour_; + position++; + } +} + +void TIA::draw_playfield(uint8_t *target, int start, int length) const +{ +} diff --git a/Machines/Atari2600/TIA.hpp b/Machines/Atari2600/TIA.hpp index 6c76fc9cd..b9e56379e 100644 --- a/Machines/Atari2600/TIA.hpp +++ b/Machines/Atari2600/TIA.hpp @@ -23,6 +23,10 @@ class TIA { NTSC, PAL }; + /*! + Advances the TIA by @c number_of_cycles cycles. Any queued setters take effect in the + first cycle performed. + */ void run_for_cycles(int number_of_cycles); void set_output_mode(OutputMode output_mode); @@ -71,9 +75,8 @@ class TIA { inline void output_for_cycles(int number_of_cycles); inline void output_line(); - inline void draw_background(uint8_t *target, int start, int length); - inline void draw_playfield(uint8_t *target, int start, int length); - inline void draw_background_and_playfield(uint8_t *target, int start, int length); + inline void draw_background(uint8_t *target, int start, int length) const; + inline void draw_playfield(uint8_t *target, int start, int length) const; // the master counter; counts from 0 to 228 with all visible pixels being in the final 160 int horizontal_counter_; @@ -81,14 +84,25 @@ class TIA { // contains flags to indicate whether sync or blank are currently active int output_mode_; - // keeps track of the target pixel buffer for this line and when it was acquired + // keeps track of the target pixel buffer for this line and when it was acquired, and a corresponding collision buffer uint8_t *pixel_target_; int pixel_target_origin_; + uint8_t collision_buffer_[160]; + enum class CollisionType : uint8_t { + Playfield, + Sprite1, + Sprite2, + Missile1, + Missile2, + Ball + }; // playfield state uint8_t playfield_ball_colour_; uint8_t background_colour_; int background_half_mask_; + bool playfield_is_in_score_mode_; + bool playfield_is_above_players_; uint32_t background_[2]; // contains two 20-bit bitfields representing the background state; // at index 0 is the left-hand side of the playfield with bit 0 being // the first bit to display, bit 1 the second, etc. Index 1 contains @@ -96,6 +110,7 @@ class TIA { // mirroring mode, background_[0] will be output on the left and // background_[1] on the right; otherwise background_[0] will be // output twice. + int latched_playfield_value_; // player state struct Player {