mirror of
https://github.com/TomHarte/CLK.git
synced 2025-02-19 23:29:05 +00:00
Decided not to run before I can walk and switched to storing the motion time and next step explicitly per object.
This commit is contained in:
parent
5ea232310f
commit
8d502a0b03
@ -30,7 +30,6 @@ TIA::TIA(bool create_crt) :
|
|||||||
motion_{0, 0, 0, 0, 0},
|
motion_{0, 0, 0, 0, 0},
|
||||||
is_moving_{false, false, false, false, false},
|
is_moving_{false, false, false, false, false},
|
||||||
horizontal_blank_extend_(false),
|
horizontal_blank_extend_(false),
|
||||||
horizontal_move_start_time_(0),
|
|
||||||
collision_flags_(0)
|
collision_flags_(0)
|
||||||
{
|
{
|
||||||
if(create_crt)
|
if(create_crt)
|
||||||
@ -329,7 +328,7 @@ void TIA::set_player_position(int player)
|
|||||||
|
|
||||||
void TIA::set_player_motion(int player, uint8_t motion)
|
void TIA::set_player_motion(int player, uint8_t motion)
|
||||||
{
|
{
|
||||||
motion_[(int)MotionIndex::Player0 + player] = motion >> 4;
|
motion_[(int)MotionIndex::Player0 + player] = (motion >> 4)&0xf;
|
||||||
}
|
}
|
||||||
|
|
||||||
void TIA::set_player_missile_colour(int player, uint8_t colour)
|
void TIA::set_player_missile_colour(int player, uint8_t colour)
|
||||||
@ -373,7 +372,8 @@ void TIA::move()
|
|||||||
{
|
{
|
||||||
horizontal_blank_extend_ = true;
|
horizontal_blank_extend_ = true;
|
||||||
is_moving_[0] = is_moving_[1] = is_moving_[2] = is_moving_[3] = is_moving_[4] = true;
|
is_moving_[0] = is_moving_[1] = is_moving_[2] = is_moving_[3] = is_moving_[4] = true;
|
||||||
horizontal_move_start_time_ = horizontal_counter_;
|
motion_step_[0] = motion_step_[1] = motion_step_[2] = motion_step_[3] = motion_step_[4] = 15;
|
||||||
|
motion_time_[0] = motion_time_[1] = motion_time_[2] = motion_time_[3] = motion_time_[4] = (horizontal_counter_ + 3) & ~3;
|
||||||
}
|
}
|
||||||
|
|
||||||
void TIA::clear_motion()
|
void TIA::clear_motion()
|
||||||
@ -415,6 +415,7 @@ void TIA::output_for_cycles(int number_of_cycles)
|
|||||||
if(line_end_function_) line_end_function_(collision_buffer_.data());
|
if(line_end_function_) line_end_function_(collision_buffer_.data());
|
||||||
memset(collision_buffer_.data(), 0, 160); // sizeof(collision_buffer_)
|
memset(collision_buffer_.data(), 0, 160); // sizeof(collision_buffer_)
|
||||||
horizontal_blank_extend_ = false;
|
horizontal_blank_extend_ = false;
|
||||||
|
for(int c = 0; c < 5; c++) motion_time_[c] %= 228;
|
||||||
}
|
}
|
||||||
|
|
||||||
// accumulate an OR'd version of the output into the collision buffer
|
// accumulate an OR'd version of the output into the collision buffer
|
||||||
@ -601,27 +602,27 @@ void TIA::draw_playfield(int start, int end)
|
|||||||
|
|
||||||
#pragma mark - Motion
|
#pragma mark - Motion
|
||||||
|
|
||||||
void TIA::perform_motion_step(int identity, int movement_time)
|
void TIA::perform_motion_step(int identity)
|
||||||
{
|
{
|
||||||
int movement_step = (movement_time - horizontal_move_start_time_) >> 2;
|
if((motion_step_[identity] ^ (motion_[identity] ^ 8)) == 0xf)
|
||||||
if(movement_step == (motion_[identity] ^ 8))
|
|
||||||
is_moving_[identity] = false;
|
is_moving_[identity] = false;
|
||||||
else
|
else
|
||||||
|
{
|
||||||
position_[identity] ++;
|
position_[identity] ++;
|
||||||
|
motion_step_[identity] --;
|
||||||
|
motion_time_[identity] += 4;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
int TIA::perform_border_motion(int identity, int start, int end, int &movement_time)
|
int TIA::perform_border_motion(int identity, int start, int end)
|
||||||
{
|
{
|
||||||
movement_time = (start + 3) & ~3;
|
|
||||||
if(!is_moving_[identity]) return 0;
|
if(!is_moving_[identity]) return 0;
|
||||||
|
|
||||||
int steps_taken = 0;
|
int steps_taken = 0;
|
||||||
int first_pixel = first_pixel_cycle + (horizontal_blank_extend_ ? 8 : 0) - 4;
|
while(is_moving_[identity] && motion_time_[identity] < end)
|
||||||
// round up to the next H@1 cycle
|
|
||||||
while(is_moving_[identity] && movement_time < end && movement_time < first_pixel)
|
|
||||||
{
|
{
|
||||||
perform_motion_step(identity, movement_time);
|
perform_motion_step(identity);
|
||||||
movement_time += 4;
|
steps_taken++;
|
||||||
}
|
}
|
||||||
position_[identity] %= 160;
|
position_[identity] %= 160;
|
||||||
|
|
||||||
@ -630,7 +631,7 @@ int TIA::perform_border_motion(int identity, int start, int end, int &movement_t
|
|||||||
|
|
||||||
#pragma mark - Player output
|
#pragma mark - Player output
|
||||||
|
|
||||||
void TIA::draw_player_visible(Player &player, CollisionType collision_identity, const int position_identity, int start, int end, int &movement_time)
|
void TIA::draw_player_visible(Player &player, CollisionType collision_identity, const int position_identity, int start, int end)
|
||||||
{
|
{
|
||||||
int &position = position_[position_identity];
|
int &position = position_[position_identity];
|
||||||
int adder = 4 >> player.size;
|
int adder = 4 >> player.size;
|
||||||
@ -638,14 +639,15 @@ void TIA::draw_player_visible(Player &player, CollisionType collision_identity,
|
|||||||
// perform a miniature event loop on (i) triggering draws; (ii) drawing; and (iii) motion
|
// perform a miniature event loop on (i) triggering draws; (ii) drawing; and (iii) motion
|
||||||
if(is_moving_[position_identity] || player.graphic[0])
|
if(is_moving_[position_identity] || player.graphic[0])
|
||||||
{
|
{
|
||||||
|
int next_motion_time = motion_time_[position_identity] - first_pixel_cycle + 4;
|
||||||
while(start < end)
|
while(start < end)
|
||||||
{
|
{
|
||||||
int next_event_time = end;
|
int next_event_time = end;
|
||||||
|
|
||||||
// is the next event a movement tick?
|
// is the next event a movement tick?
|
||||||
if(is_moving_[position_identity] && movement_time + 4 < next_event_time)
|
if(is_moving_[position_identity] && next_motion_time < next_event_time)
|
||||||
{
|
{
|
||||||
next_event_time = movement_time + 4;
|
next_event_time = next_motion_time;
|
||||||
}
|
}
|
||||||
|
|
||||||
// is the next event a graphics trigger?
|
// is the next event a graphics trigger?
|
||||||
@ -688,10 +690,10 @@ void TIA::draw_player_visible(Player &player, CollisionType collision_identity,
|
|||||||
start = next_event_time;
|
start = next_event_time;
|
||||||
|
|
||||||
// if the event is a motion tick, apply
|
// if the event is a motion tick, apply
|
||||||
if(is_moving_[position_identity] && start == movement_time + 4)
|
if(is_moving_[position_identity] && start == next_motion_time)
|
||||||
{
|
{
|
||||||
perform_motion_step(position_identity, movement_time);
|
perform_motion_step(position_identity);
|
||||||
movement_time += 4;
|
next_motion_time += 4;
|
||||||
}
|
}
|
||||||
|
|
||||||
// if it's a draw trigger, trigger a draw
|
// if it's a draw trigger, trigger a draw
|
||||||
@ -710,14 +712,16 @@ void TIA::draw_player_visible(Player &player, CollisionType collision_identity,
|
|||||||
|
|
||||||
void TIA::draw_player(Player &player, CollisionType collision_identity, const int position_identity, int start, int end)
|
void TIA::draw_player(Player &player, CollisionType collision_identity, const int position_identity, int start, int end)
|
||||||
{
|
{
|
||||||
int movement_time;
|
|
||||||
int adder = 4 >> player.size;
|
int adder = 4 >> player.size;
|
||||||
|
int first_pixel = first_pixel_cycle - 4 + (horizontal_blank_extend_ ? 8 : 0);
|
||||||
|
|
||||||
// movement works across the entire screen, so do work that falls outside of the pixel area
|
// movement works across the entire screen, so do work that falls outside of the pixel area
|
||||||
player.pixel_position += adder * perform_border_motion(position_identity, start, end, movement_time);;
|
if(start < first_pixel)
|
||||||
|
{
|
||||||
|
player.pixel_position = std::min(36, player.pixel_position + adder * perform_border_motion(position_identity, start, std::max(end, first_pixel)));
|
||||||
|
}
|
||||||
|
|
||||||
// don't continue to do any drawing if this window ends too early
|
// don't continue to do any drawing if this window ends too early
|
||||||
int first_pixel = first_pixel_cycle - 4 + (horizontal_blank_extend_ ? 8 : 0);
|
|
||||||
if(end < first_pixel) return;
|
if(end < first_pixel) return;
|
||||||
if(start < first_pixel) start = first_pixel;
|
if(start < first_pixel) start = first_pixel;
|
||||||
if(start >= end) return;
|
if(start >= end) return;
|
||||||
@ -725,15 +729,13 @@ void TIA::draw_player(Player &player, CollisionType collision_identity, const in
|
|||||||
// perform the visible part of the line, if any
|
// perform the visible part of the line, if any
|
||||||
if(start < 224)
|
if(start < 224)
|
||||||
{
|
{
|
||||||
movement_time -= first_pixel_cycle - 4;
|
draw_player_visible(player, collision_identity, position_identity, start - first_pixel_cycle + 4, std::min(end - first_pixel_cycle + 4, 160));
|
||||||
draw_player_visible(player, collision_identity, position_identity, start - first_pixel_cycle + 4, std::min(end - first_pixel_cycle + 4, 160), movement_time);
|
|
||||||
movement_time += first_pixel_cycle - 4;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// move further if required
|
// move further if required
|
||||||
if(is_moving_[position_identity] && end >= 224 && movement_time < end)
|
if(is_moving_[position_identity] && end >= 224 && motion_time_[position_identity] < end)
|
||||||
{
|
{
|
||||||
perform_motion_step(position_identity, movement_time);
|
perform_motion_step(position_identity);
|
||||||
player.pixel_position += adder;
|
player.pixel_position = std::min(36, player.pixel_position + adder);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -145,7 +145,7 @@ class TIA {
|
|||||||
int pixel_position;
|
int pixel_position;
|
||||||
bool graphic_delay;
|
bool graphic_delay;
|
||||||
|
|
||||||
Player() : size(0), copy_flags(0), graphic{0, 0}, reverse_mask(false), pixel_position(32), graphic_delay(false) {}
|
Player() : size(0), copy_flags(0), graphic{0, 0}, reverse_mask(false), pixel_position(36), graphic_delay(false) {}
|
||||||
} player_[2];
|
} player_[2];
|
||||||
|
|
||||||
// missile state
|
// missile state
|
||||||
@ -155,8 +155,9 @@ class TIA {
|
|||||||
|
|
||||||
// movement
|
// movement
|
||||||
bool horizontal_blank_extend_;
|
bool horizontal_blank_extend_;
|
||||||
int horizontal_move_start_time_;
|
|
||||||
int motion_[5];
|
int motion_[5];
|
||||||
|
int motion_step_[5];
|
||||||
|
int motion_time_[5];
|
||||||
int position_[5];
|
int position_[5];
|
||||||
bool is_moving_[5];
|
bool is_moving_[5];
|
||||||
enum class MotionIndex : uint8_t {
|
enum class MotionIndex : uint8_t {
|
||||||
@ -166,8 +167,8 @@ class TIA {
|
|||||||
Missile0,
|
Missile0,
|
||||||
Missile1
|
Missile1
|
||||||
};
|
};
|
||||||
inline int perform_border_motion(int identity, int start, int end, int &movement_time);
|
inline int perform_border_motion(int identity, int start, int end);
|
||||||
inline void perform_motion_step(int identity, int movement_time);
|
inline void perform_motion_step(int identity);
|
||||||
|
|
||||||
// drawing methods and state
|
// drawing methods and state
|
||||||
inline void output_for_cycles(int number_of_cycles);
|
inline void output_for_cycles(int number_of_cycles);
|
||||||
@ -175,7 +176,7 @@ class TIA {
|
|||||||
|
|
||||||
inline void draw_playfield(int start, int end);
|
inline void draw_playfield(int start, int end);
|
||||||
inline void draw_player(Player &player, CollisionType collision_identity, const int position_identity, int start, int end);
|
inline void draw_player(Player &player, CollisionType collision_identity, const int position_identity, int start, int end);
|
||||||
inline void draw_player_visible(Player &player, CollisionType collision_identity, const int position_identity, int start, int end, int &movement_time);
|
inline void draw_player_visible(Player &player, CollisionType collision_identity, const int position_identity, int start, int end);
|
||||||
|
|
||||||
inline void update_motion(int start, int end);
|
inline void update_motion(int start, int end);
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user