54 #include "video_screen_io_device.h"
57 using namespace std::chrono;
58 using namespace r_code;
59 using namespace r_exec;
61 namespace video_screen {
63 template<
class O,
class S> VideoScreenIoDevice<O, S>::VideoScreenIoDevice()
65 lastInjectTime_ = Timestamp(seconds(0));
67 ready_opcode_ = 0xFFFF;
68 move_opcode_ = 0xFFFF;
69 fovea_pattern_property_ = NULL;
71 lastCommandTime_ = Timestamp(seconds(0));
74 template<
class O,
class S> VideoScreenIoDevice<O, S>::~VideoScreenIoDevice() {
80 (
const vector<Code*> *objects, uint32 stdin_oid, uint32 stdout_oid,
90 if (!video_screen_->load(objects))
94 ready_opcode_ = r_exec::GetOpcode(
"ready");
95 move_opcode_ = r_exec::GetOpcode(
"move");
98 fovea_pattern_property_ = S::find_object(objects,
"fovea_pattern");
104 uint16
function = (command->code(CMD_FUNCTION).atom_ >> 8) & 0x000000FF;
106 if (
function == ready_opcode_) {
107 uint16 args_set_index = command->code(CMD_ARGS).asIndex();
108 if (command->code_size() >= 2 && command->code(args_set_index + 1).getDescriptor() == Atom::I_PTR &&
109 command->code(command->code(args_set_index + 1).asIndex()).getDescriptor() == Atom::STRING) {
110 string identifier = Utils::GetString(&command->code(command->code(args_set_index + 1).asIndex()));
112 if (identifier ==
"pong") {
113 if (!(command->code_size() >= 3 && command->code(args_set_index + 2).getDescriptor() == Atom::R_PTR &&
114 command->references_size() > command->code(args_set_index + 2).asIndex())) {
115 cout <<
"WARNING: Cannot get the object for ready \"pong\"" << endl;
118 if (!fovea_pattern_property_) {
119 cout <<
"WARNING: Can't find the fovea_pattern property" << endl;
123 Code* obj = command->get_reference(command->code(args_set_index + 2).asIndex());
137 cout <<
"WARNING: Ignoring unrecognized ready command identifier: " << identifier << endl;
142 else if (
function == move_opcode_) {
143 auto now = r_exec::Now();
144 lastCommandTime_ = now;
145 uint16 args_set_index = command->code(CMD_ARGS).asIndex();
146 if (command->code(args_set_index).getAtomCount() < 3) {
147 cout <<
"WARNING: Not enough args for (cmd move [eye1 X Y])" << endl;
151 Code* obj = command->get_reference(command->code(args_set_index + 1).asIndex());
164 int delta_x = (int)command->code(args_set_index + 2).asFloat();
165 int delta_y = (int)command->code(args_set_index + 3).asFloat();
169 video_screen_->move_eye(delta_x, delta_y, actual_delta_x, actual_delta_y);
170 if (actual_delta_x == delta_x && actual_delta_y == delta_y)
177 actual_command->code(0) = Atom::Object(r_exec::GetOpcode(
"cmd"), 3);
178 actual_command->code(1) = Atom::DeviceFunction(move_opcode_);
179 actual_command->code(2) = Atom::IPointer(4);
180 actual_command->code(3) = Atom::Float(1);
181 actual_command->code(4) = Atom::Set(3);
182 actual_command->code(5) = Atom::RPointer(0);
183 actual_command->code(6) = Atom::Float(actual_delta_x);
184 actual_command->code(7) = Atom::Float(actual_delta_y);
185 actual_command->set_reference(0, eye_obj_);
187 return actual_command;
195 auto now = r_exec::Now();
196 if (now <= lastInjectTime_ + S::get_sampling_period() * 8 / 10)
202 if (lastInjectTime_.time_since_epoch().count() == 0) {
206 position_y_ += velocity_y_ * duration_cast<microseconds>(now - lastInjectTime_).count();
209 lastInjectTime_ = now;
211 S::inject_marker_value_from_io_device(
212 eye_obj_, fovea_pattern_property_, video_screen_->get_fovea_pattern(),
213 now, now + S::get_sampling_period());
218 template class VideoScreenIoDevice<r_exec::LObject, r_exec::MemStatic>;
219 template class VideoScreenIoDevice<r_exec::LObject, r_exec::MemVolatile>;