1 #include "library/controller-data.hpp"
2 #include "library/workthread.hpp"
3 #include "library/minmax.hpp"
4 #include "library/globalwrap.hpp"
10 void set_core_controller_illegal(unsigned port
) throw()
12 std::cerr
<< "Attempt to set core port type to INVALID port type" << std::endl
;
16 int button_id_illegal(unsigned controller
, unsigned lbid
)
21 struct port_index_map
invalid_construct_map(std::vector
<port_type
*> types
)
23 struct port_index_map i
;
25 i
.indices
[0].valid
= true;
26 i
.indices
[0].port
= 0;
27 i
.indices
[0].controller
= 0;
28 i
.indices
[0].control
= 0;
32 inline size_t invalid_serialize(const unsigned char* buffer
, char* textbuf
) throw()
37 inline void invalid_display(const unsigned char* buffer
, unsigned idx
, char* buf
)
42 inline void basecontrol_display(const unsigned char* buffer
, unsigned idx
, char* buf
)
47 buf
[0] = (buffer
[0] & 1) ? 'F' : '-';
52 inline const char* invalid_controller_name(unsigned c
)
54 return c
? NULL
: "(system)";
57 struct port_type_group invalid_group
;
58 struct porttype_invalid
: public port_type
60 porttype_invalid() : port_type(invalid_group
, "invalid-port-type", "invalid-port-type", 999999, 0)
62 write
= generic_port_write
<0, 0, 0>;
63 read
= generic_port_read
<0, 0, 0>;
64 display
= invalid_display
;
65 serialize
= invalid_serialize
;
66 deserialize
= generic_port_deserialize
<0, 0, 0>;
67 legal
= generic_port_legal
<0xFFFFFFFFU
>;
68 deviceflags
= generic_port_deviceflags
<0, 0>;
69 used_indices
= generic_used_indices
<0, 0>;
70 controller_name
= invalid_controller_name
;
71 button_id
= button_id_illegal
;
72 construct_map
= invalid_construct_map
;
74 set_core_controller
= set_core_controller_illegal
;
78 inline size_t basecontrol_serialize(const unsigned char* buffer
, char* textbuf
) throw()
80 textbuf
[0] = (buffer
[0] & 1) ? 'F' : '.';
84 struct porttype_basecontrol
: public port_type
86 porttype_basecontrol() : port_type(invalid_group
, "basecontrol", "basecontrol", 999998, 0)
88 write
= generic_port_write
<1, 0, 1>;
89 read
= generic_port_read
<1, 0, 1>;
90 display
= basecontrol_display
;
91 serialize
= basecontrol_serialize
;
92 deserialize
= generic_port_deserialize
<1, 0, 1>;
93 legal
= generic_port_legal
<0>;
94 deviceflags
= generic_port_deviceflags
<0, 0>;
95 button_id
= button_id_illegal
;
96 construct_map
= invalid_construct_map
;
97 used_indices
= generic_used_indices
<1, 1>;
98 controller_name
= invalid_controller_name
;
100 set_core_controller
= set_core_controller_illegal
;
102 static port_type
& get()
104 static porttype_basecontrol x
;
109 struct pending_registration
111 port_type_group
* group
;
116 globalwrap
<mutex_class
> reg_mutex
;
117 globalwrap
<std::set
<port_type_group
*>> ready_groups
;
118 globalwrap
<std::list
<pending_registration
>> pending_registrations
;
120 void run_pending_registrations()
122 umutex_class
m(reg_mutex());
123 auto i
= pending_registrations().begin();
124 while(i
!= pending_registrations().end()) {
126 if(ready_groups().count(entry
->group
)) {
127 entry
->group
->register_type(entry
->name
, *entry
->toreg
);
128 pending_registrations().erase(entry
);
133 void add_registration(port_type_group
& group
, const std::string
& name
, port_type
& type
)
136 umutex_class
m(reg_mutex());
137 pending_registration p
;
141 pending_registrations().push_back(p
);
143 run_pending_registrations();
146 void delete_registration(port_type_group
& group
, const std::string
& name
)
149 umutex_class
m(reg_mutex());
150 if(ready_groups().count(&group
))
151 group
.unregister_type(name
);
153 auto i
= pending_registrations().begin();
154 while(i
!= pending_registrations().end()) {
156 if(entry
->group
== &group
&& entry
->name
== name
)
157 pending_registrations().erase(entry
);
164 port_type_group::port_type_group() throw(std::bad_alloc
)
167 umutex_class
m(reg_mutex());
168 ready_groups().insert(this);
170 run_pending_registrations();
173 port_type_group::~port_type_group() throw()
176 umutex_class
m(reg_mutex());
177 ready_groups().erase(this);
181 port_type
& port_type_group::get_type(const std::string
& name
) const throw(std::runtime_error
)
183 if(types
.count(name
))
184 return *(types
.find(name
)->second
);
186 throw std::runtime_error("Unknown port type");
189 port_type
& port_type_group::get_default_type(unsigned port
) const throw(std::runtime_error
)
191 if(defaults
.count(port
))
192 return *(defaults
.find(port
)->second
);
194 throw std::runtime_error("No default for this port");
197 std::set
<port_type
*> port_type_group::get_types() const throw(std::bad_alloc
)
199 std::set
<port_type
*> p
;
205 void port_type_group::set_default(unsigned port
, port_type
& ptype
)
207 defaults
[port
] = &ptype
;
210 void port_type_group::register_type(const std::string
& type
, port_type
& port
)
215 void port_type_group::unregister_type(const std::string
& type
)
220 port_type::port_type(port_type_group
& group
, const std::string
& iname
, const std::string
& _hname
, unsigned id
,
221 size_t ssize
) throw(std::bad_alloc
)
222 : ingroup(group
), name(iname
), hname(_hname
), pt_id(id
), storage_size(ssize
)
224 add_registration(ingroup
, name
, *this);
227 port_type::~port_type() throw()
229 delete_registration(ingroup
, name
);
232 bool port_type::is_present(unsigned controller
) const throw()
234 return (deviceflags(controller
) & 1) != 0;
237 bool port_type::is_analog(unsigned controller
) const throw()
239 return (deviceflags(controller
) & 6) != 0;
242 bool port_type::is_mouse(unsigned controller
) const throw()
244 return (deviceflags(controller
) & 4) != 0;
249 size_t dummy_offset
= 0;
250 port_type
* dummy_type
= &porttype_basecontrol::get();
251 unsigned dummy_index
= 0;
254 std::vector
<port_type
*> types
;
255 port_type_set
* stype
;
256 bool matches(const std::vector
<class port_type
*>& x
)
258 if(x
.size() != types
.size())
260 for(size_t i
= 0; i
< x
.size(); i
++)
266 std::list
<binding
>& bindings()
268 static std::list
<binding
> x
;
273 port_type_set::port_type_set() throw()
276 port_offsets
= &dummy_offset
;
277 port_types
= &dummy_type
;
281 _indices
[0].valid
= true;
282 _indices
[0].port
= 0;
283 _indices
[0].controller
= 0;
284 _indices
[0].control
= 0;
285 _indices
[0].marks_nonlag
= false;
288 controller_multiplier
= 1;
290 indices_tab
= &dummy_index
;
293 port_type_set
& port_type_set::make(std::vector
<class port_type
*> types
) throw(std::bad_alloc
, std::runtime_error
)
295 for(auto i
: bindings())
298 //Not found, create new.
299 port_type_set
& ret
= *new port_type_set(types
);
303 bindings().push_back(b
);
307 port_type_set::port_type_set(std::vector
<class port_type
*> types
)
309 port_count
= types
.size();
310 //Verify legality of port types.
311 for(size_t i
= 0; i
< port_count
; i
++)
312 if(!types
[i
] || (i
> 0 && !types
[i
]->legal(i
- 1)))
313 throw std::runtime_error("Illegal port types");
314 //Count maximum number of controller indices to determine the controller multiplier.
315 controller_multiplier
= 1;
316 for(size_t i
= 0; i
< port_count
; i
++)
317 for(unsigned j
= 0; j
< types
[i
]->controllers
; j
++)
318 controller_multiplier
= max(controller_multiplier
, (size_t)types
[i
]->used_indices(j
));
319 //Count maximum number of controllers to determine the port multiplier.
321 for(size_t i
= 0; i
< port_count
; i
++)
322 port_multiplier
= max(port_multiplier
, controller_multiplier
* (size_t)types
[i
]->controllers
);
323 //Query core about maps.
324 struct port_index_map control_map
= types
[0]->construct_map(types
);
325 //Allocate the per-port tables.
326 port_offsets
= new size_t[types
.size()];
327 port_types
= new class port_type
*[types
.size()];
328 //Determine the total size and offsets.
330 for(size_t i
= 0; i
< port_count
; i
++) {
331 port_offsets
[i
] = offset
;
332 offset
+= types
[i
]->storage_size
;
333 port_types
[i
] = types
[i
];
336 //Determine the index size and allocate it.
337 indices_size
= port_multiplier
* port_count
;
338 indices_tab
= new unsigned[indices_size
];
339 for(size_t i
= 0; i
< indices_size
; i
++)
340 indices_tab
[i
] = 0xFFFFFFFFUL
;
341 //Copy the index data (and reverse it).
342 controllers
= control_map
.logical_map
;
343 legacy_pcids
= control_map
.pcid_map
;
344 _indices
= control_map
.indices
;
345 for(size_t j
= 0; j
< _indices
.size(); j
++) {
346 auto& i
= _indices
[j
];
348 indices_tab
[i
.port
* port_multiplier
+ i
.controller
* controller_multiplier
+ i
.control
] = j
;
352 short read_axis_value(const char* buf
, size_t& idx
) throw()
356 while(is_nonterminator(buf
[idx
])) {
358 if(ch
!= ' ' && ch
!= '\t')
362 //Read the sign if any.
364 if(!is_nonterminator(ch
))
366 bool negative
= false;
374 //Read numeric value.
376 while(is_nonterminator(buf
[idx
]) && isdigit(static_cast<unsigned char>(ch
= buf
[idx
]))) {
377 numval
= numval
* 10 + (ch
- '0');
383 return static_cast<short>(numval
);
386 port_type
& get_dummy_port_type() throw(std::bad_alloc
)
388 static porttype_invalid inv
;
394 port_type_set
& dummytypes()
396 static port_type_set x
;
401 pollcounter_vector::pollcounter_vector() throw(std::bad_alloc
)
403 types
= &dummytypes();
404 ctrs
= new uint32_t[types
->indices()];
408 pollcounter_vector::pollcounter_vector(const port_type_set
& p
) throw(std::bad_alloc
)
411 ctrs
= new uint32_t[types
->indices()];
415 pollcounter_vector::pollcounter_vector(const pollcounter_vector
& p
) throw(std::bad_alloc
)
417 ctrs
= new uint32_t[p
.types
->indices()];
419 memcpy(ctrs
, p
.ctrs
, sizeof(uint32_t) * p
.types
->indices());
422 pollcounter_vector
& pollcounter_vector::operator=(const pollcounter_vector
& p
) throw(std::bad_alloc
)
426 uint32_t* n
= new uint32_t[p
.types
->indices()];
428 memcpy(n
, p
.ctrs
, sizeof(uint32_t) * p
.types
->indices());
434 pollcounter_vector::~pollcounter_vector() throw()
439 void pollcounter_vector::clear() throw()
441 memset(ctrs
, 0, sizeof(uint32_t) * types
->indices());
444 void pollcounter_vector::set_all_DRDY() throw()
446 for(size_t i
= 0; i
< types
->indices(); i
++)
447 ctrs
[i
] |= 0x80000000UL
;
450 void pollcounter_vector::clear_DRDY(unsigned idx
) throw()
452 ctrs
[idx
] &= 0x7FFFFFFFUL
;
455 bool pollcounter_vector::get_DRDY(unsigned idx
) throw()
457 return ((ctrs
[idx
] & 0x80000000UL
) != 0);
460 bool pollcounter_vector::has_polled() throw()
463 for(size_t i
= 0; i
< types
->indices() ; i
++)
465 return ((res
& 0x7FFFFFFFUL
) != 0);
468 uint32_t pollcounter_vector::get_polls(unsigned idx
) throw()
470 return ctrs
[idx
] & 0x7FFFFFFFUL
;
473 uint32_t pollcounter_vector::increment_polls(unsigned idx
) throw()
475 uint32_t x
= ctrs
[idx
] & 0x7FFFFFFFUL
;
480 uint32_t pollcounter_vector::max_polls() throw()
483 for(unsigned i
= 0; i
< types
->indices(); i
++) {
484 uint32_t tmp
= ctrs
[i
] & 0x7FFFFFFFUL
;
485 max
= (max
< tmp
) ? tmp
: max
;
490 void pollcounter_vector::save_state(std::vector
<uint32_t>& mem
) throw(std::bad_alloc
)
492 mem
.resize(types
->indices());
494 for(size_t i
= 0; i
< types
->indices(); i
++)
498 void pollcounter_vector::load_state(const std::vector
<uint32_t>& mem
) throw()
500 for(size_t i
= 0; i
< types
->indices(); i
++)
504 bool pollcounter_vector::check(const std::vector
<uint32_t>& mem
) throw()
506 return (mem
.size() == types
->indices());
510 controller_frame::controller_frame(const port_type_set
& p
) throw(std::runtime_error
)
512 memset(memory
, 0, sizeof(memory
));
517 controller_frame::controller_frame(unsigned char* mem
, const port_type_set
& p
) throw(std::runtime_error
)
520 throw std::runtime_error("NULL backing memory not allowed");
521 memset(memory
, 0, sizeof(memory
));
526 controller_frame::controller_frame(const controller_frame
& obj
) throw()
528 memset(memory
, 0, sizeof(memory
));
531 memcpy(backing
, obj
.backing
, types
->size());
534 controller_frame
& controller_frame::operator=(const controller_frame
& obj
) throw(std::runtime_error
)
536 if(backing
!= memory
&& types
!= obj
.types
)
537 throw std::runtime_error("Port types do not match");
539 memcpy(backing
, obj
.backing
, types
->size());
542 size_t controller_frame_vector::walk_helper(size_t frame
, bool sflag
) throw()
544 size_t ret
= sflag
? frame
: 0;
549 size_t page
= frame
/ frames_per_page
;
550 size_t offset
= frame_size
* (frame
% frames_per_page
);
551 size_t index
= frame
% frames_per_page
;
552 if(cache_page_num
!= page
) {
553 cache_page
= &pages
[page
];
554 cache_page_num
= page
;
556 while(frame
< frames
) {
557 if(index
== frames_per_page
) {
559 cache_page
= &pages
[page
];
560 cache_page_num
= page
;
562 if(controller_frame::sync(cache_page
->content
+ offset
))
565 offset
+= frame_size
;
572 size_t controller_frame_vector::count_frames() throw()
578 cache_page
= &pages
[0];
581 for(size_t i
= 0; i
< frames
; i
++) {
582 if(index
== frames_per_page
) {
584 cache_page
= &pages
[cache_page_num
];
588 if(controller_frame::sync(cache_page
->content
+ offset
))
591 offset
+= frame_size
;
597 void controller_frame_vector::clear(const port_type_set
& p
) throw(std::runtime_error
)
599 frame_size
= p
.size();
600 frames_per_page
= CONTROLLER_PAGE_SIZE
/ frame_size
;
607 controller_frame_vector::~controller_frame_vector() throw()
613 controller_frame_vector::controller_frame_vector() throw()
618 controller_frame_vector::controller_frame_vector(const port_type_set
& p
) throw()
623 void controller_frame_vector::append(controller_frame frame
) throw(std::bad_alloc
, std::runtime_error
)
625 controller_frame
check(*types
);
626 if(!check
.types_match(frame
))
627 throw std::runtime_error("controller_frame_vector::append: Type mismatch");
628 if(frames
% frames_per_page
== 0) {
630 pages
[frames
/ frames_per_page
];
633 size_t page
= frames
/ frames_per_page
;
634 size_t offset
= frame_size
* (frames
% frames_per_page
);
635 if(cache_page_num
!= page
) {
636 cache_page_num
= page
;
637 cache_page
= &pages
[page
];
639 controller_frame(cache_page
->content
+ offset
, *types
) = frame
;
643 controller_frame_vector::controller_frame_vector(const controller_frame_vector
& vector
) throw(std::bad_alloc
)
645 clear(*vector
.types
);
649 controller_frame_vector
& controller_frame_vector::operator=(const controller_frame_vector
& v
)
650 throw(std::bad_alloc
)
658 frame_size
= v
.frame_size
;
659 frames_per_page
= v
.frames_per_page
;
662 //This can't fail anymore. Copy the raw page contents.
663 size_t pagecount
= (frames
+ frames_per_page
- 1) / frames_per_page
;
664 for(size_t i
= 0; i
< pagecount
; i
++) {
666 const page
& pg2
= v
.pages
.find(i
)->second
;
676 void controller_frame_vector::resize(size_t newsize
) throw(std::bad_alloc
)
681 } else if(newsize
< frames
) {
683 size_t current_pages
= (frames
+ frames_per_page
- 1) / frames_per_page
;
684 size_t pages_needed
= (newsize
+ frames_per_page
- 1) / frames_per_page
;
685 for(size_t i
= pages_needed
; i
< current_pages
; i
++)
687 //Now zeroize the excess memory.
688 if(newsize
< pages_needed
* frames_per_page
) {
689 size_t offset
= frame_size
* (newsize
% frames_per_page
);
690 memset(pages
[pages_needed
- 1].content
+ offset
, 0, CONTROLLER_PAGE_SIZE
- offset
);
693 } else if(newsize
> frames
) {
695 size_t current_pages
= (frames
+ frames_per_page
- 1) / frames_per_page
;
696 size_t pages_needed
= (newsize
+ frames_per_page
- 1) / frames_per_page
;
697 //Create the needed pages.
698 for(size_t i
= current_pages
; i
< pages_needed
; i
++) {
702 for(size_t i
= current_pages
; i
< pages_needed
; i
++)
712 controller_frame::controller_frame() throw()
714 memset(memory
, 0, sizeof(memory
));
716 types
= &dummytypes();