1 #include "binarystream.hpp"
2 #include "portctrl-data.hpp"
5 #include "globalwrap.hpp"
6 #include "serialization.hpp"
18 const char* movie_page_id
= "Input tracks";
21 controller simple_controller
= {"(system)", "system", {}};
22 controller_set simple_port
= {"system", "system", "system", {simple_controller
},{0}};
24 struct porttype_basecontrol
: public type
26 porttype_basecontrol() : type("basecontrol", "basecontrol", 1)
28 write
= [](const type
* _this
, unsigned char* buffer
, unsigned idx
, unsigned ctrl
,
30 if(idx
> 0 || ctrl
> 0) return;
31 buffer
[0] = x
? 1 : 0;
33 read
= [](const type
* _this
, const unsigned char* buffer
, unsigned idx
, unsigned ctrl
) ->
35 if(idx
> 0 || ctrl
> 0) return 0;
36 return buffer
[0] ? 1 : 0;
38 serialize
= [](const type
* _this
, const unsigned char* buffer
, char* textbuf
) -> size_t {
39 textbuf
[0] = buffer
[0] ? 'F' : '-';
43 deserialize
= [](const type
* _this
, unsigned char* buffer
, const char* textbuf
) ->
47 if(read_button_value(textbuf
, ptr
))
49 skip_rest_of_field(textbuf
, ptr
, false);
52 controller_info
= &simple_port
;
56 unsigned macro_random_bit()
58 static unsigned char state
[32];
59 static unsigned extracted
= 256;
60 if(extracted
== 256) {
62 gettimeofday(&tv
, NULL
);
63 unsigned char buffer
[48];
64 memcpy(buffer
, state
, 32);
65 serialization::u64b(buffer
+ 32, tv
.tv_sec
);
66 serialization::u64b(buffer
+ 40, tv
.tv_usec
);
67 sha256::hash(state
, buffer
, 48);
70 unsigned bit
= extracted
++;
71 return ((state
[bit
/ 8] >> (bit
% 8)) & 1);
75 type
& get_default_system_port_type()
77 static porttype_basecontrol x
;
81 type::type(const std::string
& iname
, const std::string
& _hname
, size_t ssize
)
82 : hname(_hname
), storage_size(ssize
), name(iname
)
90 bool type::is_present(unsigned controller
) const throw()
92 return controller_info
->controllers
.size() > controller
;
97 size_t dummy_offset
= 0;
98 type
* dummy_type
= &get_default_system_port_type();
99 unsigned dummy_index
= 0;
102 std::vector
<type
*> types
;
104 bool matches(const std::vector
<class type
*>& x
)
106 if(x
.size() != types
.size())
108 for(size_t i
= 0; i
< x
.size(); i
++)
114 std::list
<binding
>& bindings()
116 static std::list
<binding
> x
;
121 type_set::type_set() throw()
124 port_offsets
= &dummy_offset
;
125 port_types
= &dummy_type
;
129 _indices
[0].valid
= true;
130 _indices
[0].port
= 0;
131 _indices
[0].controller
= 0;
132 _indices
[0].control
= 0;
135 controller_multiplier
= 1;
137 indices_tab
= &dummy_index
;
140 type_set
& type_set::make(std::vector
<class type
*> types
, struct index_map control_map
)
142 for(auto i
: bindings())
145 //Not found, create new.
146 type_set
& ret
= *new type_set(types
, control_map
);
150 bindings().push_back(b
);
154 type_set::type_set(std::vector
<class type
*> types
, struct index_map control_map
)
156 port_count
= types
.size();
157 //Verify legality of port types.
158 for(size_t i
= 0; i
< port_count
; i
++)
159 if(!types
[i
] || !types
[i
]->legal(i
))
160 throw std::runtime_error("Illegal port types");
161 //Count maximum number of controller indices to determine the controller multiplier.
162 controller_multiplier
= 1;
163 for(size_t i
= 0; i
< port_count
; i
++)
164 for(unsigned j
= 0; j
< types
[i
]->controller_info
->controllers
.size(); j
++)
165 controller_multiplier
= max(controller_multiplier
, (size_t)types
[i
]->used_indices(j
));
166 //Count maximum number of controllers to determine the port multiplier.
168 for(size_t i
= 0; i
< port_count
; i
++)
169 port_multiplier
= max(port_multiplier
, controller_multiplier
*
170 (size_t)types
[i
]->controller_info
->controllers
.size());
171 //Allocate the per-port tables.
172 port_offsets
= new size_t[types
.size()];
173 port_types
= new class type
*[types
.size()];
174 //Determine the total size and offsets.
176 for(size_t i
= 0; i
< port_count
; i
++) {
177 port_offsets
[i
] = offset
;
178 offset
+= types
[i
]->storage_size
;
179 port_types
[i
] = types
[i
];
182 //Determine the index size and allocate it.
183 indices_size
= port_multiplier
* port_count
;
184 indices_tab
= new unsigned[indices_size
];
185 for(size_t i
= 0; i
< indices_size
; i
++)
186 indices_tab
[i
] = 0xFFFFFFFFUL
;
187 //Copy the index data (and reverse it).
188 controllers
= control_map
.logical_map
;
189 legacy_pcids
= control_map
.pcid_map
;
190 _indices
= control_map
.indices
;
191 for(size_t j
= 0; j
< _indices
.size(); j
++) {
192 auto& i
= _indices
[j
];
194 indices_tab
[i
.port
* port_multiplier
+ i
.controller
* controller_multiplier
+ i
.control
] = j
;
198 short read_axis_value(const char* buf
, size_t& idx
) throw()
202 while(is_nonterminator(buf
[idx
])) {
204 if(ch
!= ' ' && ch
!= '\t')
208 //Read the sign if any.
210 if(!is_nonterminator(ch
))
212 bool negative
= false;
220 //Read numeric value.
222 while(is_nonterminator(buf
[idx
]) && isdigit(static_cast<unsigned char>(ch
= buf
[idx
]))) {
223 numval
= numval
* 10 + (ch
- '0');
229 return static_cast<short>(numval
);
232 size_t write_axis_value(char* buf
, short _v
)
237 if(v
< 0) { buf
[r
++] = '-'; v
= -v
; }
238 if(v
>= 10000) buf
[r
++] = '0' + (v
/ 10000 % 10);
239 if(v
>= 1000) buf
[r
++] = '0' + (v
/ 1000 % 10);
240 if(v
>= 100) buf
[r
++] = '0' + (v
/ 100 % 10);
241 if(v
>= 10) buf
[r
++] = '0' + (v
/ 10 % 10);
242 buf
[r
++] = '0' + (v
% 10);
248 type_set
& dummytypes()
254 size_t writeu32val(char32_t
* buf
, int val
)
258 sprintf(c
, "%d", val
);
259 for(i
= 0; c
[i
]; i
++)
264 uint64_t find_next_sync(frame_vector
& movie
, uint64_t after
)
266 if(after
>= movie
.size())
270 } while(after
< movie
.size() && !movie
[after
].sync());
275 void frame::display(unsigned port
, unsigned controller_n
, char32_t
* buf
) throw()
277 if(port
>= types
->ports()) {
282 uint8_t* backingmem
= backing
+ types
->port_offset(port
);
283 const type
& ptype
= types
->port_type(port
);
284 if(controller_n
>= ptype
.controller_info
->controllers
.size()) {
289 const controller
& pc
= ptype
.controller_info
->controllers
[controller_n
];
290 bool need_space
= false;
292 for(unsigned i
= 0; i
< pc
.buttons
.size(); i
++) {
293 const button
& pcb
= pc
.buttons
[i
];
294 if(need_space
&& pcb
.type
!= button::TYPE_NULL
) {
299 case button::TYPE_NULL
:
301 case button::TYPE_BUTTON
:
302 *(buf
++) = ptype
.read(&ptype
, backingmem
, controller_n
, i
) ? pcb
.symbol
: U
'-';
304 case button::TYPE_AXIS
:
305 case button::TYPE_RAXIS
:
306 case button::TYPE_TAXIS
:
307 case button::TYPE_LIGHTGUN
:
308 val
= ptype
.read(&ptype
, backingmem
, controller_n
, i
);
309 buf
+= writeu32val(buf
, val
);
319 types
= &dummytypes();
320 ctrs
= new uint32_t[types
->indices()];
324 counters::counters(const type_set
& p
)
327 ctrs
= new uint32_t[types
->indices()];
331 counters::counters(const counters
& p
)
333 ctrs
= new uint32_t[p
.types
->indices()];
335 memcpy(ctrs
, p
.ctrs
, sizeof(uint32_t) * p
.types
->indices());
336 framepflag
= p
.framepflag
;
339 counters
& counters::operator=(const counters
& p
)
343 uint32_t* n
= new uint32_t[p
.types
->indices()];
345 memcpy(n
, p
.ctrs
, sizeof(uint32_t) * p
.types
->indices());
348 framepflag
= p
.framepflag
;
352 counters::~counters() throw()
357 void counters::clear() throw()
359 memset(ctrs
, 0, sizeof(uint32_t) * types
->indices());
363 void counters::set_all_DRDY() throw()
365 for(size_t i
= 0; i
< types
->indices(); i
++)
366 ctrs
[i
] |= 0x80000000UL
;
369 void counters::clear_DRDY(unsigned idx
) throw()
371 ctrs
[idx
] &= 0x7FFFFFFFUL
;
374 bool counters::get_DRDY(unsigned idx
) throw()
376 return ((ctrs
[idx
] & 0x80000000UL
) != 0);
379 bool counters::has_polled() throw()
382 for(size_t i
= 0; i
< types
->indices() ; i
++)
384 return ((res
& 0x7FFFFFFFUL
) != 0);
387 uint32_t counters::get_polls(unsigned idx
) throw()
389 return ctrs
[idx
] & 0x7FFFFFFFUL
;
392 uint32_t counters::increment_polls(unsigned idx
) throw()
394 uint32_t x
= ctrs
[idx
] & 0x7FFFFFFFUL
;
399 uint32_t counters::max_polls() throw()
402 for(unsigned i
= 0; i
< types
->indices(); i
++) {
403 uint32_t tmp
= ctrs
[i
] & 0x7FFFFFFFUL
;
404 max
= (max
< tmp
) ? tmp
: max
;
409 void counters::save_state(std::vector
<uint32_t>& mem
)
411 mem
.resize(types
->indices());
413 for(size_t i
= 0; i
< types
->indices(); i
++)
417 void counters::load_state(const std::vector
<uint32_t>& mem
) throw()
419 for(size_t i
= 0; i
< types
->indices(); i
++)
423 bool counters::check(const std::vector
<uint32_t>& mem
) throw()
425 return (mem
.size() == types
->indices());
429 void counters::set_framepflag(bool value
) throw()
434 bool counters::get_framepflag() const throw()
439 frame::frame(const type_set
& p
)
441 memset(memory
, 0, sizeof(memory
));
447 frame::frame(unsigned char* mem
, const type_set
& p
, frame_vector
* _host
)
450 throw std::runtime_error("NULL backing memory not allowed");
451 memset(memory
, 0, sizeof(memory
));
457 frame::frame(const frame
& obj
) throw()
459 memset(memory
, 0, sizeof(memory
));
462 memcpy(backing
, obj
.backing
, types
->size());
466 frame
& frame::operator=(const frame
& obj
)
468 if(backing
!= memory
&& types
!= obj
.types
)
469 throw std::runtime_error("Port types do not match");
472 memcpy(backing
, obj
.backing
, types
->size());
473 if(host
) host
->notify_sync_change(sync() - old
);
477 frame_vector::fchange_listener::~fchange_listener()
481 size_t frame_vector::walk_helper(size_t frame
, bool sflag
) throw()
483 size_t ret
= sflag
? frame
: 0;
488 size_t page
= frame
/ frames_per_page
;
489 size_t offset
= frame_size
* (frame
% frames_per_page
);
490 size_t index
= frame
% frames_per_page
;
491 if(cache_page_num
!= page
) {
492 cache_page
= &pages
[page
];
493 cache_page_num
= page
;
495 while(frame
< frames
) {
496 if(index
== frames_per_page
) {
498 cache_page
= &pages
[page
];
499 cache_page_num
= page
;
503 if(frame::sync(cache_page
->content
+ offset
))
506 offset
+= frame_size
;
513 size_t frame_vector::recount_frames() throw()
515 uint64_t old_frame_count
= real_frame_count
;
520 cache_page
= &pages
[0];
523 for(size_t i
= 0; i
< frames
; i
++) {
524 if(index
== frames_per_page
) {
526 cache_page
= &pages
[cache_page_num
];
530 if(frame::sync(cache_page
->content
+ offset
))
533 offset
+= frame_size
;
536 real_frame_count
= ret
;
537 call_framecount_notification(old_frame_count
);
541 void frame_vector::clear(const type_set
& p
)
543 uint64_t old_frame_count
= real_frame_count
;
544 frame_size
= p
.size();
545 frames_per_page
= CONTROLLER_PAGE_SIZE
/ frame_size
;
550 real_frame_count
= 0;
551 call_framecount_notification(old_frame_count
);
554 frame_vector::~frame_vector() throw()
560 frame_vector::frame_vector() throw()
561 : tracker(memtracker::singleton(), movie_page_id
, sizeof(*this))
563 real_frame_count
= 0;
568 frame_vector::frame_vector(const type_set
& p
) throw()
569 : tracker(memtracker::singleton(), movie_page_id
, sizeof(*this))
571 real_frame_count
= 0;
576 void frame_vector::append(frame cframe
)
579 if(!check
.types_match(cframe
))
580 throw std::runtime_error("frame_vector::append: Type mismatch");
581 if(frames
% frames_per_page
== 0) {
583 pages
[frames
/ frames_per_page
];
586 size_t page
= frames
/ frames_per_page
;
587 size_t offset
= frame_size
* (frames
% frames_per_page
);
588 if(cache_page_num
!= page
) {
589 cache_page_num
= page
;
590 cache_page
= &pages
[page
];
592 frame(cache_page
->content
+ offset
, *types
) = cframe
;
593 if(cframe
.sync()) real_frame_count
++;
597 frame_vector::frame_vector(const frame_vector
& vector
)
598 : tracker(memtracker::singleton(), movie_page_id
, sizeof(*this))
600 real_frame_count
= 0;
602 clear(*vector
.types
);
606 frame_vector
& frame_vector::operator=(const frame_vector
& v
)
610 uint64_t old_frame_count
= real_frame_count
;
615 frame_size
= v
.frame_size
;
616 frames_per_page
= v
.frames_per_page
;
618 real_frame_count
= v
.real_frame_count
;
620 //This can't fail anymore. Copy the raw page contents.
621 size_t pagecount
= (frames
+ frames_per_page
- 1) / frames_per_page
;
622 for(size_t i
= 0; i
< pagecount
; i
++) {
624 const page
& pg2
= v
.pages
.find(i
)->second
;
627 call_framecount_notification(old_frame_count
);
631 void frame_vector::resize(size_t newsize
)
636 } else if(newsize
< frames
) {
638 uint64_t old_frame_count
= real_frame_count
;
639 for(size_t i
= newsize
; i
< frames
; i
++)
640 if((*this)[i
].sync()) real_frame_count
--;
641 size_t current_pages
= (frames
+ frames_per_page
- 1) / frames_per_page
;
642 size_t pages_needed
= (newsize
+ frames_per_page
- 1) / frames_per_page
;
643 for(size_t i
= pages_needed
; i
< current_pages
; i
++)
645 //Now zeroize the excess memory.
646 if(newsize
< pages_needed
* frames_per_page
) {
647 size_t offset
= frame_size
* (newsize
% frames_per_page
);
648 memset(pages
[pages_needed
- 1].content
+ offset
, 0, CONTROLLER_PAGE_SIZE
- offset
);
651 call_framecount_notification(old_frame_count
);
652 } else if(newsize
> frames
) {
654 size_t current_pages
= (frames
+ frames_per_page
- 1) / frames_per_page
;
655 size_t pages_needed
= (newsize
+ frames_per_page
- 1) / frames_per_page
;
656 //Create the needed pages.
657 for(size_t i
= current_pages
; i
< pages_needed
; i
++) {
661 for(size_t i
= current_pages
; i
< pages_needed
; i
++)
668 //This can use real_frame_count, because the real frame count won't change.
669 call_framecount_notification(real_frame_count
);
673 bool frame_vector::compatible(frame_vector
& with
, uint64_t nframe
, const uint32_t* polls
)
675 //Types have to match.
676 if(get_types() != with
.get_types())
678 const type_set
& pset
= with
.get_types();
679 //If new movie is before first frame, anything with same project_id is compatible.
682 //Scan both movies until frame syncs are seen. Out of bounds reads behave as all neutral but frame
684 uint64_t syncs_seen
= 0;
685 uint64_t frames_read
= 0;
686 size_t old_size
= size();
687 size_t new_size
= with
.size();
689 size_t ocomplete_pages
= old_size
/ frames_per_page
; //Round DOWN
690 size_t ncomplete_pages
= new_size
/ frames_per_page
; //Round DOWN
691 size_t complete_pages
= min(ocomplete_pages
, ncomplete_pages
);
692 while(syncs_seen
+ frames_per_page
< nframe
- 1 && pagenum
< complete_pages
) {
693 //Fast process page. The above condition guarantees that these pages are completely used.
694 auto opagedata
= pages
[pagenum
].content
;
695 auto npagedata
= with
.pages
[pagenum
].content
;
696 size_t pagedataamt
= frames_per_page
* frame_size
;
697 if(memcmp(opagedata
, npagedata
, pagedataamt
))
699 frames_read
+= frames_per_page
;
701 for(size_t i
= 0; i
< pagedataamt
; i
+= frame_size
)
702 if(opagedata
[i
] & 1) syncs_seen
++;
704 while(syncs_seen
< nframe
- 1) {
705 frame oldc
= blank_frame(true), newc
= with
.blank_frame(true);
706 if(frames_read
< old_size
)
707 oldc
= (*this)[frames_read
];
708 if(frames_read
< new_size
)
709 newc
= with
[frames_read
];
711 return false; //Mismatch.
716 //We increment the counter one time too many.
718 //Current frame. We need to compare each control up to poll counter.
719 uint64_t readable_old_subframes
= 0, readable_new_subframes
= 0;
720 uint64_t oldlen
= find_next_sync(*this, frames_read
);
721 uint64_t newlen
= find_next_sync(with
, frames_read
);
722 if(frames_read
< oldlen
)
723 readable_old_subframes
= oldlen
- frames_read
;
724 if(frames_read
< newlen
)
725 readable_new_subframes
= newlen
- frames_read
;
726 //Then rest of the stuff.
727 for(unsigned i
= 0; i
< pset
.indices(); i
++) {
728 uint32_t p
= polls
[i
] & 0x7FFFFFFFUL
;
729 short ov
= 0, nv
= 0;
730 for(uint32_t j
= 0; j
< p
; j
++) {
731 if(j
< readable_old_subframes
)
732 ov
= (*this)[j
+ frames_read
].axis2(i
);
733 if(j
< readable_new_subframes
)
734 nv
= with
[j
+ frames_read
].axis2(i
);
742 uint64_t frame_vector::binary_size() const throw()
744 return size() * get_stride();
747 void frame_vector::save_binary(binarystream::output
& stream
) const
749 uint64_t stride
= get_stride();
750 uint64_t pageframes
= get_frames_per_page();
751 uint64_t vsize
= size();
754 uint64_t count
= (vsize
> pageframes
) ? pageframes
: vsize
;
755 size_t bytes
= count
* stride
;
756 const unsigned char* content
= get_page_buffer(pagenum
++);
757 stream
.raw(content
, bytes
);
762 void frame_vector::load_binary(binarystream::input
& stream
)
764 uint64_t stride
= get_stride();
765 uint64_t pageframes
= get_frames_per_page();
768 uint64_t pagesize
= stride
* pageframes
;
769 while(stream
.get_left()) {
770 resize(vsize
+ pageframes
);
771 unsigned char* contents
= get_page_buffer(pagenum
++);
772 uint64_t gcount
= min(pagesize
, stream
.get_left());
773 stream
.raw(contents
, gcount
);
774 vsize
+= (gcount
/ stride
);
780 void frame_vector::swap_data(frame_vector
& v
) throw()
782 uint64_t toldsize
= real_frame_count
;
783 uint64_t voldsize
= v
.real_frame_count
;
784 std::swap(pages
, v
.pages
);
785 std::swap(frames_per_page
, v
.frames_per_page
);
786 std::swap(frame_size
, v
.frame_size
);
787 std::swap(frames
, v
.frames
);
788 std::swap(types
, v
.types
);
789 std::swap(cache_page_num
, v
.cache_page_num
);
790 std::swap(cache_page
, v
.cache_page
);
791 std::swap(real_frame_count
, v
.real_frame_count
);
793 call_framecount_notification(toldsize
);
795 v
.call_framecount_notification(voldsize
);
798 int64_t frame_vector::find_frame(uint64_t n
)
801 uint64_t stride
= get_stride();
802 uint64_t pageframes
= get_frames_per_page();
803 uint64_t vsize
= size();
806 uint64_t count
= (vsize
> pageframes
) ? pageframes
: vsize
;
807 const unsigned char* content
= get_page_buffer(pagenum
++);
809 for(unsigned i
= 0; i
< count
; i
++) {
810 if(frame::sync(content
+ offset
)) n
--;
811 if(n
== 0) return (pagenum
- 1) * pageframes
+ i
;
819 int64_t frame_vector::subframe_to_frame(uint64_t n
)
822 uint64_t stride
= get_stride();
823 uint64_t pageframes
= get_frames_per_page();
824 uint64_t vsize
= size();
825 if(n
>= vsize
) return -1;
827 size_t cpage
= n
/ pageframes
;
828 for(uint64_t p
= 0; p
< cpage
; p
++) {
829 const unsigned char* content
= get_page_buffer(pagenum
++);
831 for(unsigned i
= 0; i
< pageframes
; i
++) {
832 if(frame::sync(content
+ offset
)) ret
++;
837 const unsigned char* content
= get_page_buffer(pagenum
++);
839 unsigned idx
= n
% pageframes
;
840 for(unsigned i
= 0; i
< idx
; i
++) {
841 if(frame::sync(content
+ offset
)) ret
++;
848 frame::frame() throw()
850 memset(memory
, 0, sizeof(memory
));
852 types
= &dummytypes();
856 unsigned controller::analog_actions() const
858 unsigned r
= 0, s
= 0;
859 for(unsigned i
= 0; i
< buttons
.size(); i
++) {
860 if(buttons
[i
].shadow
)
862 switch(buttons
[i
].type
) {
863 case button::TYPE_AXIS
:
864 case button::TYPE_RAXIS
:
865 case button::TYPE_LIGHTGUN
:
868 case button::TYPE_TAXIS
:
871 case button::TYPE_NULL
:
872 case button::TYPE_BUTTON
:
876 return (r
+ 1)/ 2 + s
;
879 std::pair
<unsigned, unsigned> controller::analog_action(unsigned k
) const
881 unsigned x1
= std::numeric_limits
<unsigned>::max();
882 unsigned x2
= std::numeric_limits
<unsigned>::max();
885 bool selecting
= false;
886 for(unsigned i
= 0; i
< buttons
.size(); i
++) {
887 if(buttons
[i
].shadow
)
889 switch(buttons
[i
].type
) {
890 case button::TYPE_AXIS
:
891 case button::TYPE_RAXIS
:
892 case button::TYPE_LIGHTGUN
:
897 if(r
== k
&& !second
) {
898 //This and following.
906 case button::TYPE_TAXIS
:
915 case button::TYPE_NULL
:
916 case button::TYPE_BUTTON
:
921 return std::make_pair(x1
, x2
);
926 std::string
macro_field_as_string(const JSON::node
& parent
, const std::string
& path
)
928 const JSON::node
& n
= parent
.follow(path
);
929 if(n
.type() != JSON::string
)
930 (stringfmt() << "Expected string as field '" << path
<< "'").throwex();
931 return n
.as_string8();
934 bool macro_field_as_boolean(const JSON::node
& parent
, const std::string
& path
)
936 const JSON::node
& n
= parent
.follow(path
);
937 if(n
.type() != JSON::boolean
)
938 (stringfmt() << "Expected boolean as field '" << path
<< "'").throwex();
942 const JSON::node
& macro_field_as_array(const JSON::node
& parent
, const std::string
& path
)
944 const JSON::node
& n
= parent
.follow(path
);
945 if(n
.type() != JSON::array
)
946 (stringfmt() << "Expected array as field '" << path
<< "'").throwex();
951 macro_data::macro_data(const std::string
& spec
, const JSON::node
& desc
, unsigned inum
)
955 std::map
<std::string
, unsigned> symbols
;
956 if(desc
.type() != JSON::array
)
957 (stringfmt() << "Expected controller descriptor " << (inum
+ 1) << " to be an array");
958 for(auto i
= desc
.begin(); i
!= desc
.end(); ++i
) {
959 if(i
->type() == JSON::string
) {
960 symbols
[i
->as_string8()] = btnnum
++;
961 btnmap
.push_back(i
.index());
962 } else if(i
->type() == JSON::number
) {
963 uint64_t anum
= i
->as_uint();
964 if(anum
> aaxes
.size())
965 (stringfmt() << "Descriptor axis number " << anum
<< " out of range in descriptor "
966 << (inum
+ 1)).throwex();
967 else if(anum
== aaxes
.size())
968 aaxes
.push_back(std::make_pair(i
.index(), std::numeric_limits
<unsigned>::max()));
970 aaxes
[anum
].second
= i
.index();
972 (stringfmt() << "Controller descriptor " << (inum
+ 1) << " contains element of unknown"
973 << "kind").throwex();
975 buttons
= symbols
.size();
978 autoterminate
= false;
980 std::deque
<size_t> stack
;
981 bool in_sparen
= false;
983 bool btn_token
= false;
984 bool btn_token_next
= false;
986 size_t last_size
= 0;
987 size_t astride
= aaxes
.size();
988 size_t stride
= get_stride();
990 size_t len
= spec
.length();
993 btn_token
= btn_token_next
;
994 btn_token_next
= false;
995 unsigned char ch
= spec
[idx
];
997 throw std::runtime_error("Asterisk must be the last thing");
1000 throw std::runtime_error("Parentheses in square brackets not allowed");
1001 stack
.push_back(data
.size());
1002 } else if(ch
== ')') {
1004 throw std::runtime_error("Parentheses in square brackets not allowed");
1006 throw std::runtime_error("Unmatched right parenthesis");
1007 size_t x
= stack
.back();
1009 last_size
= (data
.size() - x
) / stride
;
1010 } else if(ch
== '*') {
1011 autoterminate
= true;
1012 } else if(ch
== '?') {
1014 throw std::runtime_error("? needs button to apply to");
1016 throw std::runtime_error("? needs to be in brackets");
1017 data
[data
.size() - stride
+ last_bit
] |= 2;
1018 } else if(ch
== '[') {
1020 throw std::runtime_error("Nested square brackets not allowed");
1022 data
.resize(data
.size() + stride
);
1023 adata
.resize(adata
.size() + astride
);
1025 } else if(ch
== ']') {
1027 throw std::runtime_error("Unmatched right square bracket");
1029 } else if(ch
== '.') {
1031 data
.resize(data
.size() + stride
);
1032 adata
.resize(adata
.size() + astride
);
1035 } else if(spec
[idx
] >= '0' && spec
[idx
] <= '9') {
1038 while(spec
[idx
+ i
] >= '0' && spec
[idx
+ i
] <= '9') {
1039 rep
= 10 * rep
+ (spec
[idx
+ i
] - '0');
1043 //This has special meaning: Axis transform.
1044 //Rep is the axis pair to operate on.
1045 if(spec
[idx
+ i
] != ':')
1046 throw std::runtime_error("Expected ':' in axis transform");
1048 while(idx
+ i
< len
&& spec
[idx
+ i
] != '@')
1051 throw std::runtime_error("Expected '@' in axis transform");
1052 std::string aexpr
= spec
.substr(idx
+ sep
+ 1, i
- sep
- 1);
1054 throw std::runtime_error("Axis transform refers to invalid axis");
1055 adata
[adata
.size() - astride
+ rep
] = axis_transform(aexpr
);
1059 throw std::runtime_error("Repeat not allowed without frame to "
1061 size_t o
= data
.size();
1062 size_t ao
= adata
.size();
1063 data
.resize(o
+ (rep
- 1) * last_size
* stride
);
1064 adata
.resize(ao
+ (rep
- 1) * last_size
* astride
);
1065 for(unsigned i
= 1; i
< rep
; i
++) {
1066 memcpy(&data
[o
+ (i
- 1) * last_size
* stride
], &data
[o
- last_size
*
1067 stride
], last_size
* stride
);
1068 memcpy(&data
[ao
+ (i
- 1) * last_size
* astride
], &data
[ao
-
1069 last_size
* astride
], last_size
* astride
);
1071 last_size
= last_size
* rep
;
1073 idx
= idx
+ (i
- 1);
1076 for(auto k
: symbols
) {
1077 std::string key
= k
.first
;
1079 for(j
= 0; idx
+ j
< len
&& j
< key
.length(); j
++)
1080 if(spec
[idx
+ j
] != key
[j
])
1082 if(j
== key
.length()) {
1083 idx
+= key
.length() - 1;
1086 data
.resize(data
.size() + stride
);
1087 adata
.resize(adata
.size() + astride
);
1089 last_bit
= k
.second
;
1090 data
[data
.size() - stride
+ k
.second
] |= 1;
1096 throw std::runtime_error("Unknown character or button");
1097 btn_token_next
= true;
1103 throw std::runtime_error("Unmatched left square bracket");
1105 throw std::runtime_error("Unmatched left parenthesis");
1106 } catch(std::exception
& e
) {
1107 (stringfmt() << "Error parsing macro for controller " << (inum
+ 1) << ": " << e
.what()).throwex();
1111 bool macro_data::syntax_check(const std::string
& spec
, const JSON::node
& desc
)
1113 unsigned buttons
= 0;
1115 if(desc
.type() != JSON::array
)
1117 for(auto i
= desc
.begin(); i
!= desc
.end(); ++i
) {
1118 if(i
->type() == JSON::string
)
1120 else if(i
->type() == JSON::number
) {
1121 uint64_t anum
= i
->as_uint();
1124 else if(anum
== astride
)
1129 bool autoterminate
= false;
1131 bool in_sparen
= false;
1133 bool btn_token
= false;
1134 bool btn_token_next
= false;
1136 size_t len
= spec
.length();
1138 btn_token
= btn_token_next
;
1139 btn_token_next
= false;
1140 unsigned char ch
= spec
[idx
];
1147 } else if(ch
== ')') {
1153 } else if(ch
== '*') {
1154 autoterminate
= true;
1155 } else if(ch
== '?') {
1156 if(!btn_token
|| !in_sparen
)
1158 } else if(ch
== '[') {
1162 } else if(ch
== ']') {
1166 } else if(ch
== '.') {
1167 } else if(spec
[idx
] >= '0' && spec
[idx
] <= '9') {
1170 while(spec
[idx
+ i
] >= '0' && spec
[idx
+ i
] <= '9') {
1171 rep
= 10 * rep
+ (spec
[idx
+ i
] - '0');
1175 //This has special meaning: Axis transform.
1176 //Rep is the axis pair to operate on.
1177 if(spec
[idx
+ i
] != ':')
1180 while(idx
+ i
< len
&& spec
[idx
+ i
] != '@')
1187 std::string aexpr
= spec
.substr(idx
+ sep
+ 1, i
- sep
- 1);
1188 axis_transform
x(aexpr
);
1197 idx
= idx
+ (i
- 1);
1200 for(auto i
= desc
.begin(); i
!= desc
.end(); ++i
) {
1201 if(i
->type() != JSON::string
)
1203 std::string key
= i
->as_string8();
1205 for(j
= 0; idx
+ j
< len
&& j
< key
.length(); j
++)
1206 if(spec
[idx
+ j
] != key
[j
])
1208 if(j
== key
.length()) {
1209 idx
+= key
.length() - 1;
1215 btn_token_next
= true;
1227 void macro_data::write(frame
& frame
, unsigned port
, unsigned controller_n
, int64_t nframe
,
1232 if(autoterminate
&& (nframe
< 0 || nframe
>= (int64_t)get_frames()))
1235 nframe
+= ((-nframe
/ get_frames()) + 3) * get_frames();
1236 nframe
%= get_frames();
1237 for(size_t i
= 0; i
< buttons
; i
++) {
1238 unsigned lb
= btnmap
[i
];
1239 unsigned st
= data
[nframe
* get_stride() + i
];
1241 st
= macro_random_bit();
1246 frame
.axis3(port
, controller_n
, lb
, 1);
1249 frame
.axis3(port
, controller_n
, lb
, frame
.axis3(port
, controller_n
, lb
) ^ 1);
1255 frame
.axis3(port
, controller_n
, lb
, 0);
1262 const controller
* _ctrl
= frame
.porttypes().port_type(port
).controller_info
->get(controller_n
);
1265 size_t abuttons
= aaxes
.size();
1266 for(size_t i
= 0; i
< abuttons
; i
++) {
1267 unsigned ax
= aaxes
[i
].first
;
1268 unsigned ay
= aaxes
[i
].second
;
1269 if(ay
!= std::numeric_limits
<unsigned>::max()) {
1270 if(ax
> _ctrl
->buttons
.size()) continue;
1271 if(ay
> _ctrl
->buttons
.size()) continue;
1272 auto g
= adata
[nframe
* abuttons
+ i
].transform(_ctrl
->buttons
[ax
], _ctrl
->buttons
[ay
],
1273 frame
.axis3(port
, controller_n
, ax
), frame
.axis3(port
, controller_n
, ay
));
1274 frame
.axis3(port
, controller_n
, ax
, g
.first
);
1275 frame
.axis3(port
, controller_n
, ay
, g
.second
);
1277 if(ax
> _ctrl
->buttons
.size()) continue;
1278 int16_t g
= adata
[nframe
* abuttons
+ i
].transform(_ctrl
->buttons
[ax
],
1279 frame
.axis3(port
, controller_n
, ax
));
1280 frame
.axis3(port
, controller_n
, ax
, g
);
1285 std::string
macro_data::dump(const controller
& ctrl
)
1287 std::ostringstream o
;
1288 for(size_t i
= 0; i
< get_frames(); i
++) {
1290 for(size_t j
= 0; j
< aaxes
.size(); j
++) {
1291 macro_data::axis_transform
& t
= adata
[i
* aaxes
.size() + j
];
1293 o
<< t
.coeffs
[0] << "," << t
.coeffs
[1] << "," << t
.coeffs
[2] << ",";
1294 o
<< t
.coeffs
[3] << "," << t
.coeffs
[4] << "," << t
.coeffs
[5] << "@";
1296 for(size_t j
= 0; j
< buttons
&& j
< ctrl
.buttons
.size(); j
++) {
1297 unsigned st
= data
[i
* get_stride() + j
];
1298 if(ctrl
.buttons
[j
].macro
== "")
1301 o
<< ctrl
.buttons
[j
].macro
;
1303 o
<< ctrl
.buttons
[j
].macro
<< "?";
1312 void macro::write(frame
& frame
, int64_t nframe
)
1314 for(auto& i
: macros
) {
1316 unsigned controller
;
1318 auto g
= frame
.porttypes().lcid_to_pcid(i
.first
);
1320 controller
= g
.second
;
1324 i
.second
.write(frame
, port
, controller
, nframe
, amode
);
1328 int16_t macro_data::axis_transform::transform(const button
& b
, int16_t v
)
1330 return scale_axis(b
, coeffs
[0] * unscale_axis(b
, v
) + coeffs
[4]);
1333 std::pair
<int16_t, int16_t> macro_data::axis_transform::transform(const button
& b1
,
1334 const button
& b2
, int16_t v1
, int16_t v2
)
1336 double x
, y
, u
, v
, au
, av
, s
;
1337 x
= unscale_axis(b1
, v1
);
1338 y
= unscale_axis(b2
, v2
);
1339 u
= coeffs
[0] * x
+ coeffs
[1] * y
+ coeffs
[4];
1340 v
= coeffs
[2] * x
+ coeffs
[3] * y
+ coeffs
[5];
1343 s
= max(max(au
, 1.0), max(av
, 1.0));
1344 //If u and v exceed nominal range of [-1,1], those need to be projected to the edge.
1349 auto g
= std::make_pair(scale_axis(b1
, u
), scale_axis(b2
, v
));
1353 double macro_data::axis_transform::unscale_axis(const button
& b
, int16_t v
)
1356 int32_t center
= ((int32_t)b
.rmin
+ (int32_t)b
.rmax
) / 2;
1360 return -(center
- (double)v
) / (center
- b
.rmin
);
1364 return ((double)v
- center
) / (b
.rmax
- center
);
1371 return ((double)v
- b
.rmin
) / (b
.rmax
- b
.rmin
);
1375 int16_t macro_data::axis_transform::scale_axis(const button
& b
, double v
)
1378 int32_t center
= ((int32_t)b
.rmin
+ (int32_t)b
.rmax
) / 2;
1382 double v2
= v
* (center
- b
.rmin
) + center
;
1387 double v2
= v
* (b
.rmax
- center
) + center
;
1392 double v2
= v
* (b
.rmax
- b
.rmin
) + b
.rmin
;
1403 std::complex<double> parse_complex(const std::string
& expr
)
1406 if(r
= regex("\\((.*),(.*)\\)", expr
)) {
1408 return std::complex<double>(parse_value
<double>(r
[1]), parse_value
<double>(r
[2]));
1409 } else if(r
= regex("\\((.*)<(.*)\\)", expr
)) {
1410 return std::polar(parse_value
<double>(r
[1]), parse_value
<double>(r
[2]) * M_PI
/ 180);
1412 return std::complex<double>(parse_value
<double>(expr
), 0.0);
1417 macro_data::axis_transform::axis_transform(const std::string
& expr
)
1420 if(r
= regex("\\*(.*)\\+(.*)", expr
)) {
1422 std::complex<double> a
= parse_complex(r
[1]);
1423 std::complex<double> b
= parse_complex(r
[2]);
1424 coeffs
[0] = a
.real();
1425 coeffs
[1] = -a
.imag();
1426 coeffs
[2] = a
.imag();
1427 coeffs
[3] = a
.real();
1428 coeffs
[4] = b
.real();
1429 coeffs
[5] = b
.imag();
1430 } else if(r
= regex("\\*(.*)", expr
)) {
1432 std::complex<double> a
= parse_complex(r
[1]);
1433 coeffs
[0] = a
.real();
1434 coeffs
[1] = -a
.imag();
1435 coeffs
[2] = a
.imag();
1436 coeffs
[3] = a
.real();
1439 } else if(r
= regex("\\+(.*)", expr
)) {
1441 std::complex<double> b
= parse_complex(r
[1]);
1446 coeffs
[4] = b
.real();
1447 coeffs
[5] = b
.imag();
1448 } else if(r
= regex("(.*),(.*),(.*),(.*),(.*),(.*)", expr
)) {
1450 coeffs
[0] = parse_value
<double>(r
[1]);
1451 coeffs
[1] = parse_value
<double>(r
[2]);
1452 coeffs
[2] = parse_value
<double>(r
[3]);
1453 coeffs
[3] = parse_value
<double>(r
[4]);
1454 coeffs
[4] = parse_value
<double>(r
[5]);
1455 coeffs
[5] = parse_value
<double>(r
[6]);
1458 std::complex<double> b
= parse_complex(expr
);
1463 coeffs
[4] = b
.real();
1464 coeffs
[5] = b
.imag();
1468 JSON::node
macro::serialize()
1470 JSON::node
v(JSON::object
);
1472 case macro_data::AM_OVERWRITE
: v
.insert("mode", JSON::s("overwrite")); break;
1473 case macro_data::AM_OR
: v
.insert("mode", JSON::s("or")); break;
1474 case macro_data::AM_XOR
: v
.insert("mode", JSON::s("xor")); break;
1476 JSON::node
& c
= v
.insert("data", JSON::array());
1477 for(auto& i
: macros
) {
1478 while(i
.first
> c
.index_count())
1479 c
.append(JSON::n());
1480 i
.second
.serialize(c
.append(JSON::n()));
1485 void macro_data::serialize(JSON::node
& v
)
1488 v
.insert("enable", JSON::b(enabled
));
1489 v
.insert("expr", JSON::s(orig
));
1490 v
.insert("desc", _descriptor
);
1493 JSON::node
macro_data::make_descriptor(const controller
& ctrl
)
1495 JSON::node
n(JSON::array
);
1496 for(size_t i
= 0; i
< ctrl
.buttons
.size(); i
++) {
1497 if(ctrl
.buttons
[i
].macro
!= "")
1498 n
.append(JSON::s(ctrl
.buttons
[i
].macro
));
1500 n
.append(JSON::n()); //Placeholder.
1502 for(size_t i
= 0; i
< ctrl
.analog_actions(); i
++) {
1503 auto g
= ctrl
.analog_action(i
);
1504 n
.index(g
.first
) = JSON::u(i
);
1505 if(g
.second
!= std::numeric_limits
<unsigned>::max())
1506 n
.index(g
.second
) = JSON::u(i
);
1511 macro::macro(const JSON::node
& v
)
1513 if(v
.type() != JSON::object
)
1514 throw std::runtime_error("Expected macro to be JSON object");
1515 std::string mode
= macro_field_as_string(v
, "mode");
1516 if(mode
== "overwrite") amode
= macro_data::AM_OVERWRITE
;
1517 else if(mode
== "or") amode
= macro_data::AM_OR
;
1518 else if(mode
== "xor") amode
= macro_data::AM_XOR
;
1519 else (stringfmt() << "Unknown button mode '" << mode
<< "'").throwex();
1520 const JSON::node
& c
= macro_field_as_array(v
, "data");
1521 for(auto i
= c
.begin(); i
!= c
.end(); ++i
) {
1522 if(i
->type() == JSON::object
)
1523 macros
[i
.index()] = macro_data(*i
, i
.index());
1525 (stringfmt() << "Expected object as field 'data/" << i
.index() << "'").throwex();
1529 macro_data::macro_data(const JSON::node
& v
, unsigned i
)
1530 : macro_data(macro_field_as_string(v
, "expr"), macro_field_as_array(v
, "desc"), i
)
1532 enabled
= macro_field_as_boolean(v
, "enable");