mirror of
https://github.com/TomHarte/CLK.git
synced 2024-09-08 03:54:27 +00:00
Attempted to template this thing. Without yet a plan in place for pixel lookup timing.
This commit is contained in:
parent
2bf784535c
commit
99547181f1
@ -643,6 +643,92 @@ int TIA::perform_border_motion(Object &object, int start, int end)
|
|||||||
return steps_taken;
|
return steps_taken;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
template<class T> void TIA::draw_object(T &target, Object &object, int start, int end)
|
||||||
|
{
|
||||||
|
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
|
||||||
|
if(start < first_pixel)
|
||||||
|
{
|
||||||
|
target.skip_pixels(perform_border_motion(object, start, std::max(end, first_pixel)));
|
||||||
|
}
|
||||||
|
|
||||||
|
// don't continue to do any drawing if this window ends too early
|
||||||
|
if(end < first_pixel) return;
|
||||||
|
if(start < first_pixel) start = first_pixel;
|
||||||
|
if(start >= end) return;
|
||||||
|
|
||||||
|
// perform the visible part of the line, if any
|
||||||
|
if(start < 224)
|
||||||
|
{
|
||||||
|
draw_object_visible<T>(target, object, start - first_pixel_cycle + 4, std::min(end - first_pixel_cycle + 4, 160));
|
||||||
|
}
|
||||||
|
|
||||||
|
// move further if required
|
||||||
|
if(object.is_moving && end >= 224 && object.motion_time < end)
|
||||||
|
{
|
||||||
|
perform_motion_step(object);
|
||||||
|
target.skip_pixels(1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
template<class T> void TIA::draw_object_visible(T &target, Object &object, int start, int end)
|
||||||
|
{
|
||||||
|
// perform a miniature event loop on (i) triggering draws; (ii) drawing; and (iii) motion
|
||||||
|
int next_motion_time = object.motion_time - first_pixel_cycle + 4;
|
||||||
|
while(start < end)
|
||||||
|
{
|
||||||
|
int next_event_time = end;
|
||||||
|
|
||||||
|
// is the next event a movement tick?
|
||||||
|
if(object.is_moving && next_motion_time < next_event_time)
|
||||||
|
{
|
||||||
|
next_event_time = next_motion_time;
|
||||||
|
}
|
||||||
|
|
||||||
|
// is the next event a graphics trigger?
|
||||||
|
int next_copy = 160;
|
||||||
|
if(target.copy_flags)
|
||||||
|
{
|
||||||
|
if(object.position < 16 && target.copy_flags&1)
|
||||||
|
{
|
||||||
|
next_copy = 16;
|
||||||
|
} else if(object.position < 32 && target.copy_flags&2)
|
||||||
|
{
|
||||||
|
next_copy = 32;
|
||||||
|
} else if(object.position < 64 && target.copy_flags&4)
|
||||||
|
{
|
||||||
|
next_copy = 64;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
int next_copy_time = start + next_copy - object.position;
|
||||||
|
if(next_copy_time < next_event_time) next_event_time = next_copy_time;
|
||||||
|
|
||||||
|
// the decision is to progress by length
|
||||||
|
const int length = next_event_time - start;
|
||||||
|
|
||||||
|
target.draw_pixels(length);
|
||||||
|
|
||||||
|
// the next interesting event is after next_event_time cycles, so progress
|
||||||
|
object.position = (object.position + length) % 160;
|
||||||
|
start = next_event_time;
|
||||||
|
|
||||||
|
// if the event is a motion tick, apply
|
||||||
|
if(object.is_moving && start == next_motion_time)
|
||||||
|
{
|
||||||
|
perform_motion_step(object);
|
||||||
|
next_motion_time += 4;
|
||||||
|
}
|
||||||
|
|
||||||
|
// if it's a draw trigger, trigger a draw
|
||||||
|
if(start == next_copy_time)
|
||||||
|
{
|
||||||
|
target.reset_pixels();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
#pragma mark - Player output
|
#pragma mark - Player output
|
||||||
|
|
||||||
void TIA::draw_player_visible(Player &player, Object &object, CollisionType collision_identity, int start, int end)
|
void TIA::draw_player_visible(Player &player, Object &object, CollisionType collision_identity, int start, int end)
|
||||||
|
@ -178,14 +178,7 @@ class TIA {
|
|||||||
// indicates whether this object is currently undergoing motion
|
// indicates whether this object is currently undergoing motion
|
||||||
bool is_moving;
|
bool is_moving;
|
||||||
|
|
||||||
// receives a list of drawing events; 20 is a deliberately over-specified quantity
|
Object() : is_moving(false) {};
|
||||||
struct DrawingEvent {
|
|
||||||
int time;
|
|
||||||
int copy;
|
|
||||||
} drawing_events[20];
|
|
||||||
int draw_event_read_pointer, draw_event_write_pointer;
|
|
||||||
|
|
||||||
Object() : draw_event_read_pointer(0), draw_event_write_pointer(0), is_moving(false) {};
|
|
||||||
} object_[5];
|
} object_[5];
|
||||||
enum class MotionIndex : uint8_t {
|
enum class MotionIndex : uint8_t {
|
||||||
Ball,
|
Ball,
|
||||||
@ -200,6 +193,9 @@ class TIA {
|
|||||||
inline void perform_motion_step(Object &object);
|
inline void perform_motion_step(Object &object);
|
||||||
|
|
||||||
// drawing methods and state
|
// drawing methods and state
|
||||||
|
template<class T> void draw_object(T &, Object &, int start, int end);
|
||||||
|
template<class T> void draw_object_visible(T &, Object &, int start, int end);
|
||||||
|
|
||||||
inline void output_for_cycles(int number_of_cycles);
|
inline void output_for_cycles(int number_of_cycles);
|
||||||
inline void output_line();
|
inline void output_line();
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user