mirror of
https://github.com/TomHarte/CLK.git
synced 2024-11-26 08:49:37 +00:00
Implements the Command
side of the line command.
This commit is contained in:
parent
1c6a0ad3f7
commit
baa6f9b3cd
@ -46,11 +46,14 @@ struct Command {
|
||||
// This command is blocked until @c access has been performed, reading
|
||||
// from or writing to @c value. It should not be performed until at least
|
||||
// @c cycles have passed.
|
||||
MemoryAccess access = MemoryAccess::None;
|
||||
enum class AccessType {
|
||||
/// Plots a single pixel of the current contextual colour at @c location,
|
||||
/// which occurs as a read, then a 24-cycle pause, then a write.
|
||||
PlotPoint
|
||||
};
|
||||
AccessType access = AccessType::PlotPoint;
|
||||
int cycles = 0;
|
||||
uint8_t value = 0;
|
||||
|
||||
// TODO: how best to describe access destination? Probably as (x, y) and logical/fast?
|
||||
Vector location;
|
||||
|
||||
/// Current command parameters.
|
||||
CommandContext &context;
|
||||
@ -67,21 +70,59 @@ struct Command {
|
||||
|
||||
namespace Commands {
|
||||
|
||||
/// Implements the line command, which is plain-old Bresenham.
|
||||
///
|
||||
/// Per Grauw timing is:
|
||||
///
|
||||
/// * 88 cycles between every pixel plot;
|
||||
/// * plus an additional 32 cycles if a step along the minor axis is taken.
|
||||
struct Line: public Command {
|
||||
public:
|
||||
Line(CommandContext &context) : Command(context) {
|
||||
// Set up Bresenham constants.
|
||||
if(abs(context.size.v[0]) > abs(context.size.v[1])) {
|
||||
major_.v[0] = context.size.v[0] < 0 ? -1 : 1;
|
||||
minor_.v[1] = context.size.v[1] < 0 ? -1 : 1;
|
||||
major_.v[1] = minor_.v[0] = 0;
|
||||
|
||||
position_ = abs(context.size.v[1]);
|
||||
duration_ = abs(context.size.v[0]);
|
||||
} else {
|
||||
major_.v[1] = context.size.v[1] < 0 ? -1 : 1;
|
||||
minor_.v[0] = context.size.v[0] < 0 ? -1 : 1;
|
||||
major_.v[0] = minor_.v[1] = 0;
|
||||
|
||||
position_ = abs(context.size.v[0]);
|
||||
duration_ = abs(context.size.v[1]);
|
||||
}
|
||||
|
||||
numerator_ = position_ << 1;
|
||||
denominator_ = duration_ << 1;
|
||||
|
||||
cycles = 0;
|
||||
access = AccessType::PlotPoint;
|
||||
location = context.destination;
|
||||
}
|
||||
|
||||
bool next() {
|
||||
// Should implement Bresenham with cadence:
|
||||
//
|
||||
// 88 cycles before the next read; 24 to write.
|
||||
// Add 32 extra cycles if a minor-axis step occurs.
|
||||
return false;
|
||||
if(!duration_) return false;
|
||||
|
||||
--duration_;
|
||||
cycles = 88;
|
||||
location += major_;
|
||||
position_ -= numerator_;
|
||||
if(position_ < 0) {
|
||||
cycles += 32;
|
||||
location += minor_;
|
||||
position_ += denominator_;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
private:
|
||||
int position_, numerator_, denominator_, duration_;
|
||||
Vector major_, minor_;
|
||||
};
|
||||
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user