1 #include "controller-data.hpp"
2 #include "threadtypes.hpp"
4 #include "globalwrap.hpp"
10 const char* basecontrol_chars
= "F";
12 port_controller_button
* null_buttons
[] = {};
13 port_controller simple_controller
= {"(system)", "system", 0, null_buttons
};
14 port_controller
* simple_controllers
[] = {&simple_controller
};
15 port_controller_set simple_port
= {1, simple_controllers
};
17 struct porttype_basecontrol
: public port_type
19 porttype_basecontrol() : port_type("basecontrol", "basecontrol", 999998, 1)
21 write
= [](unsigned char* buffer
, unsigned idx
, unsigned ctrl
, short x
) -> void {
22 if(idx
> 0 || ctrl
> 0) return;
23 buffer
[0] = x
? 1 : 0;
25 read
= [](const unsigned char* buffer
, unsigned idx
, unsigned ctrl
) -> short {
26 if(idx
> 0 || ctrl
> 0) return 0;
27 return buffer
[0] ? 1 : 0;
29 serialize
= [](const unsigned char* buffer
, char* textbuf
) -> size_t {
30 textbuf
[0] = buffer
[0] ? 'F' : '-';
34 deserialize
= [](unsigned char* buffer
, const char* textbuf
) -> size_t {
37 if(read_button_value(textbuf
, ptr
))
39 skip_rest_of_field(textbuf
, ptr
, false);
42 legal
= [](unsigned port
) -> int { return (port
== 0); };
43 controller_info
= &simple_port
;
44 used_indices
= [](unsigned controller
) -> unsigned { return (controller
== 0) ? 1 : 0; };
49 port_type
& get_default_system_port_type()
51 static porttype_basecontrol x
;
55 port_type::port_type(const std::string
& iname
, const std::string
& _hname
, unsigned id
,
56 size_t ssize
) throw(std::bad_alloc
)
57 : hname(_hname
), storage_size(ssize
), name(iname
), pt_id(id
)
61 port_type::~port_type() throw()
65 bool port_type::is_present(unsigned controller
) const throw()
67 return controller_info
->controller_count
> controller
;
72 size_t dummy_offset
= 0;
73 port_type
* dummy_type
= &get_default_system_port_type();
74 unsigned dummy_index
= 0;
77 std::vector
<port_type
*> types
;
79 bool matches(const std::vector
<class port_type
*>& x
)
81 if(x
.size() != types
.size())
83 for(size_t i
= 0; i
< x
.size(); i
++)
89 std::list
<binding
>& bindings()
91 static std::list
<binding
> x
;
96 port_type_set::port_type_set() throw()
99 port_offsets
= &dummy_offset
;
100 port_types
= &dummy_type
;
104 _indices
[0].valid
= true;
105 _indices
[0].port
= 0;
106 _indices
[0].controller
= 0;
107 _indices
[0].control
= 0;
110 controller_multiplier
= 1;
112 indices_tab
= &dummy_index
;
115 port_type_set
& port_type_set::make(std::vector
<class port_type
*> types
, struct port_index_map control_map
)
116 throw(std::bad_alloc
, std::runtime_error
)
118 for(auto i
: bindings())
121 //Not found, create new.
122 port_type_set
& ret
= *new port_type_set(types
, control_map
);
126 bindings().push_back(b
);
130 port_type_set::port_type_set(std::vector
<class port_type
*> types
, struct port_index_map control_map
)
132 port_count
= types
.size();
133 //Verify legality of port types.
134 for(size_t i
= 0; i
< port_count
; i
++)
135 if(!types
[i
] || !types
[i
]->legal(i
))
136 throw std::runtime_error("Illegal port types");
137 //Count maximum number of controller indices to determine the controller multiplier.
138 controller_multiplier
= 1;
139 for(size_t i
= 0; i
< port_count
; i
++)
140 for(unsigned j
= 0; j
< types
[i
]->controller_info
->controller_count
; j
++)
141 controller_multiplier
= max(controller_multiplier
, (size_t)types
[i
]->used_indices(j
));
142 //Count maximum number of controllers to determine the port multiplier.
144 for(size_t i
= 0; i
< port_count
; i
++)
145 port_multiplier
= max(port_multiplier
, controller_multiplier
*
146 (size_t)types
[i
]->controller_info
->controller_count
);
147 //Allocate the per-port tables.
148 port_offsets
= new size_t[types
.size()];
149 port_types
= new class port_type
*[types
.size()];
150 //Determine the total size and offsets.
152 for(size_t i
= 0; i
< port_count
; i
++) {
153 port_offsets
[i
] = offset
;
154 offset
+= types
[i
]->storage_size
;
155 port_types
[i
] = types
[i
];
158 //Determine the index size and allocate it.
159 indices_size
= port_multiplier
* port_count
;
160 indices_tab
= new unsigned[indices_size
];
161 for(size_t i
= 0; i
< indices_size
; i
++)
162 indices_tab
[i
] = 0xFFFFFFFFUL
;
163 //Copy the index data (and reverse it).
164 controllers
= control_map
.logical_map
;
165 legacy_pcids
= control_map
.pcid_map
;
166 _indices
= control_map
.indices
;
167 for(size_t j
= 0; j
< _indices
.size(); j
++) {
168 auto& i
= _indices
[j
];
170 indices_tab
[i
.port
* port_multiplier
+ i
.controller
* controller_multiplier
+ i
.control
] = j
;
174 short read_axis_value(const char* buf
, size_t& idx
) throw()
178 while(is_nonterminator(buf
[idx
])) {
180 if(ch
!= ' ' && ch
!= '\t')
184 //Read the sign if any.
186 if(!is_nonterminator(ch
))
188 bool negative
= false;
196 //Read numeric value.
198 while(is_nonterminator(buf
[idx
]) && isdigit(static_cast<unsigned char>(ch
= buf
[idx
]))) {
199 numval
= numval
* 10 + (ch
- '0');
205 return static_cast<short>(numval
);
210 port_type_set
& dummytypes()
212 static port_type_set x
;
216 size_t writeu32val(char32_t
* buf
, int val
)
220 sprintf(c
, "%d", val
);
221 for(i
= 0; c
[i
]; i
++)
227 void controller_frame::display(unsigned port
, unsigned controller
, char32_t
* buf
) throw()
229 if(port
>= types
->ports()) {
234 uint8_t* backingmem
= backing
+ types
->port_offset(port
);
235 const port_type
& ptype
= types
->port_type(port
);
236 if(controller
>= ptype
.controller_info
->controller_count
) {
241 const port_controller
* pc
= ptype
.controller_info
->controllers
[controller
];
242 bool need_space
= false;
244 for(unsigned i
= 0; i
< pc
->button_count
; i
++) {
245 const port_controller_button
* pcb
= pc
->buttons
[i
];
246 if(need_space
&& pcb
->type
!= port_controller_button::TYPE_NULL
) {
251 case port_controller_button::TYPE_NULL
:
253 case port_controller_button::TYPE_BUTTON
:
254 *(buf
++) = ptype
.read(backingmem
, controller
, i
) ? pcb
->symbol
: U
'-';
256 case port_controller_button::TYPE_AXIS
:
257 case port_controller_button::TYPE_RAXIS
:
258 case port_controller_button::TYPE_TAXIS
:
259 val
= ptype
.read(backingmem
, controller
, i
);
260 buf
+= writeu32val(buf
, val
);
268 pollcounter_vector::pollcounter_vector() throw(std::bad_alloc
)
270 types
= &dummytypes();
271 ctrs
= new uint32_t[types
->indices()];
275 pollcounter_vector::pollcounter_vector(const port_type_set
& p
) throw(std::bad_alloc
)
278 ctrs
= new uint32_t[types
->indices()];
282 pollcounter_vector::pollcounter_vector(const pollcounter_vector
& p
) throw(std::bad_alloc
)
284 ctrs
= new uint32_t[p
.types
->indices()];
286 memcpy(ctrs
, p
.ctrs
, sizeof(uint32_t) * p
.types
->indices());
289 pollcounter_vector
& pollcounter_vector::operator=(const pollcounter_vector
& p
) throw(std::bad_alloc
)
293 uint32_t* n
= new uint32_t[p
.types
->indices()];
295 memcpy(n
, p
.ctrs
, sizeof(uint32_t) * p
.types
->indices());
301 pollcounter_vector::~pollcounter_vector() throw()
306 void pollcounter_vector::clear() throw()
308 memset(ctrs
, 0, sizeof(uint32_t) * types
->indices());
311 void pollcounter_vector::set_all_DRDY() throw()
313 for(size_t i
= 0; i
< types
->indices(); i
++)
314 ctrs
[i
] |= 0x80000000UL
;
317 void pollcounter_vector::clear_DRDY(unsigned idx
) throw()
319 ctrs
[idx
] &= 0x7FFFFFFFUL
;
322 bool pollcounter_vector::get_DRDY(unsigned idx
) throw()
324 return ((ctrs
[idx
] & 0x80000000UL
) != 0);
327 bool pollcounter_vector::has_polled() throw()
330 for(size_t i
= 0; i
< types
->indices() ; i
++)
332 return ((res
& 0x7FFFFFFFUL
) != 0);
335 uint32_t pollcounter_vector::get_polls(unsigned idx
) throw()
337 return ctrs
[idx
] & 0x7FFFFFFFUL
;
340 uint32_t pollcounter_vector::increment_polls(unsigned idx
) throw()
342 uint32_t x
= ctrs
[idx
] & 0x7FFFFFFFUL
;
347 uint32_t pollcounter_vector::max_polls() throw()
350 for(unsigned i
= 0; i
< types
->indices(); i
++) {
351 uint32_t tmp
= ctrs
[i
] & 0x7FFFFFFFUL
;
352 max
= (max
< tmp
) ? tmp
: max
;
357 void pollcounter_vector::save_state(std::vector
<uint32_t>& mem
) throw(std::bad_alloc
)
359 mem
.resize(types
->indices());
361 for(size_t i
= 0; i
< types
->indices(); i
++)
365 void pollcounter_vector::load_state(const std::vector
<uint32_t>& mem
) throw()
367 for(size_t i
= 0; i
< types
->indices(); i
++)
371 bool pollcounter_vector::check(const std::vector
<uint32_t>& mem
) throw()
373 return (mem
.size() == types
->indices());
377 controller_frame::controller_frame(const port_type_set
& p
) throw(std::runtime_error
)
379 memset(memory
, 0, sizeof(memory
));
384 controller_frame::controller_frame(unsigned char* mem
, const port_type_set
& p
) throw(std::runtime_error
)
387 throw std::runtime_error("NULL backing memory not allowed");
388 memset(memory
, 0, sizeof(memory
));
393 controller_frame::controller_frame(const controller_frame
& obj
) throw()
395 memset(memory
, 0, sizeof(memory
));
398 memcpy(backing
, obj
.backing
, types
->size());
401 controller_frame
& controller_frame::operator=(const controller_frame
& obj
) throw(std::runtime_error
)
403 if(backing
!= memory
&& types
!= obj
.types
)
404 throw std::runtime_error("Port types do not match");
406 memcpy(backing
, obj
.backing
, types
->size());
410 size_t controller_frame_vector::walk_helper(size_t frame
, bool sflag
) throw()
412 size_t ret
= sflag
? frame
: 0;
417 size_t page
= frame
/ frames_per_page
;
418 size_t offset
= frame_size
* (frame
% frames_per_page
);
419 size_t index
= frame
% frames_per_page
;
420 if(cache_page_num
!= page
) {
421 cache_page
= &pages
[page
];
422 cache_page_num
= page
;
424 while(frame
< frames
) {
425 if(index
== frames_per_page
) {
427 cache_page
= &pages
[page
];
428 cache_page_num
= page
;
430 if(controller_frame::sync(cache_page
->content
+ offset
))
433 offset
+= frame_size
;
440 size_t controller_frame_vector::count_frames() throw()
446 cache_page
= &pages
[0];
449 for(size_t i
= 0; i
< frames
; i
++) {
450 if(index
== frames_per_page
) {
452 cache_page
= &pages
[cache_page_num
];
456 if(controller_frame::sync(cache_page
->content
+ offset
))
459 offset
+= frame_size
;
465 void controller_frame_vector::clear(const port_type_set
& p
) throw(std::runtime_error
)
467 frame_size
= p
.size();
468 frames_per_page
= CONTROLLER_PAGE_SIZE
/ frame_size
;
475 controller_frame_vector::~controller_frame_vector() throw()
481 controller_frame_vector::controller_frame_vector() throw()
486 controller_frame_vector::controller_frame_vector(const port_type_set
& p
) throw()
491 void controller_frame_vector::append(controller_frame frame
) throw(std::bad_alloc
, std::runtime_error
)
493 controller_frame
check(*types
);
494 if(!check
.types_match(frame
))
495 throw std::runtime_error("controller_frame_vector::append: Type mismatch");
496 if(frames
% frames_per_page
== 0) {
498 pages
[frames
/ frames_per_page
];
501 size_t page
= frames
/ frames_per_page
;
502 size_t offset
= frame_size
* (frames
% frames_per_page
);
503 if(cache_page_num
!= page
) {
504 cache_page_num
= page
;
505 cache_page
= &pages
[page
];
507 controller_frame(cache_page
->content
+ offset
, *types
) = frame
;
511 controller_frame_vector::controller_frame_vector(const controller_frame_vector
& vector
) throw(std::bad_alloc
)
513 clear(*vector
.types
);
517 controller_frame_vector
& controller_frame_vector::operator=(const controller_frame_vector
& v
)
518 throw(std::bad_alloc
)
526 frame_size
= v
.frame_size
;
527 frames_per_page
= v
.frames_per_page
;
530 //This can't fail anymore. Copy the raw page contents.
531 size_t pagecount
= (frames
+ frames_per_page
- 1) / frames_per_page
;
532 for(size_t i
= 0; i
< pagecount
; i
++) {
534 const page
& pg2
= v
.pages
.find(i
)->second
;
544 void controller_frame_vector::resize(size_t newsize
) throw(std::bad_alloc
)
549 } else if(newsize
< frames
) {
551 size_t current_pages
= (frames
+ frames_per_page
- 1) / frames_per_page
;
552 size_t pages_needed
= (newsize
+ frames_per_page
- 1) / frames_per_page
;
553 for(size_t i
= pages_needed
; i
< current_pages
; i
++)
555 //Now zeroize the excess memory.
556 if(newsize
< pages_needed
* frames_per_page
) {
557 size_t offset
= frame_size
* (newsize
% frames_per_page
);
558 memset(pages
[pages_needed
- 1].content
+ offset
, 0, CONTROLLER_PAGE_SIZE
- offset
);
561 } else if(newsize
> frames
) {
563 size_t current_pages
= (frames
+ frames_per_page
- 1) / frames_per_page
;
564 size_t pages_needed
= (newsize
+ frames_per_page
- 1) / frames_per_page
;
565 //Create the needed pages.
566 for(size_t i
= current_pages
; i
< pages_needed
; i
++) {
570 for(size_t i
= current_pages
; i
< pages_needed
; i
++)
580 controller_frame::controller_frame() throw()
582 memset(memory
, 0, sizeof(memory
));
584 types
= &dummytypes();
587 unsigned port_controller::analog_actions() const
589 unsigned r
= 0, s
= 0;
590 for(unsigned i
= 0; i
< button_count
; i
++) {
591 if(buttons
[i
]->shadow
)
593 switch(buttons
[i
]->type
) {
594 case port_controller_button::TYPE_AXIS
:
595 case port_controller_button::TYPE_RAXIS
:
598 case port_controller_button::TYPE_TAXIS
:
603 return (r
+ 1)/ 2 + s
;
606 std::pair
<unsigned, unsigned> port_controller::analog_action(unsigned k
) const
608 unsigned x1
= std::numeric_limits
<unsigned>::max();
609 unsigned x2
= std::numeric_limits
<unsigned>::max();
612 bool selecting
= false;
613 for(unsigned i
= 0; i
< button_count
; i
++) {
614 if(buttons
[i
]->shadow
)
616 switch(buttons
[i
]->type
) {
617 case port_controller_button::TYPE_AXIS
:
618 case port_controller_button::TYPE_RAXIS
:
623 if(r
== k
&& !second
) {
624 //This and following.
632 case port_controller_button::TYPE_TAXIS
:
644 return std::make_pair(x1
, x2
);