1 #include "controller-data.hpp"
3 #include "threadtypes.hpp"
5 #include "globalwrap.hpp"
11 const char* basecontrol_chars
= "F";
13 port_controller_button
* null_buttons
[] = {};
14 port_controller simple_controller
= {"(system)", "system", 0, null_buttons
};
15 port_controller
* simple_controllers
[] = {&simple_controller
};
16 port_controller_set simple_port
= {1, simple_controllers
};
18 struct porttype_basecontrol
: public port_type
20 porttype_basecontrol() : port_type("basecontrol", "basecontrol", 999998, 0)
22 write
= generic_port_write
<1, 0, 1>;
23 read
= generic_port_read
<1, 0, 1>;
24 display
= generic_port_display
<1, 0, 1, &basecontrol_chars
>;
25 serialize
= generic_port_serialize
<1, 0, 1, &basecontrol_chars
>;
26 deserialize
= generic_port_deserialize
<1, 0, 1>;
27 legal
= generic_port_legal
<1>;
28 controller_info
= &simple_port
;
29 used_indices
= generic_used_indices
<1, 1>;
31 static port_type
& get()
33 static porttype_basecontrol x
;
39 port_type::port_type(const std::string
& iname
, const std::string
& _hname
, unsigned id
,
40 size_t ssize
) throw(std::bad_alloc
)
41 : hname(_hname
), storage_size(ssize
), name(iname
), pt_id(id
)
45 port_type::~port_type() throw()
49 bool port_type::is_present(unsigned controller
) const throw()
51 return controller_info
->controller_count
> controller
;
56 size_t dummy_offset
= 0;
57 port_type
* dummy_type
= &porttype_basecontrol::get();
58 unsigned dummy_index
= 0;
61 std::vector
<port_type
*> types
;
63 bool matches(const std::vector
<class port_type
*>& x
)
65 if(x
.size() != types
.size())
67 for(size_t i
= 0; i
< x
.size(); i
++)
73 std::list
<binding
>& bindings()
75 static std::list
<binding
> x
;
80 port_type_set::port_type_set() throw()
83 port_offsets
= &dummy_offset
;
84 port_types
= &dummy_type
;
88 _indices
[0].valid
= true;
90 _indices
[0].controller
= 0;
91 _indices
[0].control
= 0;
94 controller_multiplier
= 1;
96 indices_tab
= &dummy_index
;
99 port_type_set
& port_type_set::make(std::vector
<class port_type
*> types
, struct port_index_map control_map
)
100 throw(std::bad_alloc
, std::runtime_error
)
102 for(auto i
: bindings())
105 //Not found, create new.
106 port_type_set
& ret
= *new port_type_set(types
, control_map
);
110 bindings().push_back(b
);
114 port_type_set::port_type_set(std::vector
<class port_type
*> types
, struct port_index_map control_map
)
116 port_count
= types
.size();
117 //Verify legality of port types.
118 for(size_t i
= 0; i
< port_count
; i
++)
119 if(!types
[i
] || !types
[i
]->legal(i
))
120 throw std::runtime_error("Illegal port types");
121 //Count maximum number of controller indices to determine the controller multiplier.
122 controller_multiplier
= 1;
123 for(size_t i
= 0; i
< port_count
; i
++)
124 for(unsigned j
= 0; j
< types
[i
]->controller_info
->controller_count
; j
++)
125 controller_multiplier
= max(controller_multiplier
, (size_t)types
[i
]->used_indices(j
));
126 //Count maximum number of controllers to determine the port multiplier.
128 for(size_t i
= 0; i
< port_count
; i
++)
129 port_multiplier
= max(port_multiplier
, controller_multiplier
*
130 (size_t)types
[i
]->controller_info
->controller_count
);
131 //Allocate the per-port tables.
132 port_offsets
= new size_t[types
.size()];
133 port_types
= new class port_type
*[types
.size()];
134 //Determine the total size and offsets.
136 for(size_t i
= 0; i
< port_count
; i
++) {
137 port_offsets
[i
] = offset
;
138 offset
+= types
[i
]->storage_size
;
139 port_types
[i
] = types
[i
];
142 //Determine the index size and allocate it.
143 indices_size
= port_multiplier
* port_count
;
144 indices_tab
= new unsigned[indices_size
];
145 for(size_t i
= 0; i
< indices_size
; i
++)
146 indices_tab
[i
] = 0xFFFFFFFFUL
;
147 //Copy the index data (and reverse it).
148 controllers
= control_map
.logical_map
;
149 legacy_pcids
= control_map
.pcid_map
;
150 _indices
= control_map
.indices
;
151 for(size_t j
= 0; j
< _indices
.size(); j
++) {
152 auto& i
= _indices
[j
];
154 indices_tab
[i
.port
* port_multiplier
+ i
.controller
* controller_multiplier
+ i
.control
] = j
;
158 short read_axis_value(const char* buf
, size_t& idx
) throw()
162 while(is_nonterminator(buf
[idx
])) {
164 if(ch
!= ' ' && ch
!= '\t')
168 //Read the sign if any.
170 if(!is_nonterminator(ch
))
172 bool negative
= false;
180 //Read numeric value.
182 while(is_nonterminator(buf
[idx
]) && isdigit(static_cast<unsigned char>(ch
= buf
[idx
]))) {
183 numval
= numval
* 10 + (ch
- '0');
189 return static_cast<short>(numval
);
194 port_type_set
& dummytypes()
196 static port_type_set x
;
201 pollcounter_vector::pollcounter_vector() throw(std::bad_alloc
)
203 types
= &dummytypes();
204 ctrs
= new uint32_t[types
->indices()];
208 pollcounter_vector::pollcounter_vector(const port_type_set
& p
) throw(std::bad_alloc
)
211 ctrs
= new uint32_t[types
->indices()];
215 pollcounter_vector::pollcounter_vector(const pollcounter_vector
& p
) throw(std::bad_alloc
)
217 ctrs
= new uint32_t[p
.types
->indices()];
219 memcpy(ctrs
, p
.ctrs
, sizeof(uint32_t) * p
.types
->indices());
222 pollcounter_vector
& pollcounter_vector::operator=(const pollcounter_vector
& p
) throw(std::bad_alloc
)
226 uint32_t* n
= new uint32_t[p
.types
->indices()];
228 memcpy(n
, p
.ctrs
, sizeof(uint32_t) * p
.types
->indices());
234 pollcounter_vector::~pollcounter_vector() throw()
239 void pollcounter_vector::clear() throw()
241 memset(ctrs
, 0, sizeof(uint32_t) * types
->indices());
244 void pollcounter_vector::set_all_DRDY() throw()
246 for(size_t i
= 0; i
< types
->indices(); i
++)
247 ctrs
[i
] |= 0x80000000UL
;
250 void pollcounter_vector::clear_DRDY(unsigned idx
) throw()
252 ctrs
[idx
] &= 0x7FFFFFFFUL
;
255 bool pollcounter_vector::get_DRDY(unsigned idx
) throw()
257 return ((ctrs
[idx
] & 0x80000000UL
) != 0);
260 bool pollcounter_vector::has_polled() throw()
263 for(size_t i
= 0; i
< types
->indices() ; i
++)
265 return ((res
& 0x7FFFFFFFUL
) != 0);
268 uint32_t pollcounter_vector::get_polls(unsigned idx
) throw()
270 return ctrs
[idx
] & 0x7FFFFFFFUL
;
273 uint32_t pollcounter_vector::increment_polls(unsigned idx
) throw()
275 uint32_t x
= ctrs
[idx
] & 0x7FFFFFFFUL
;
280 uint32_t pollcounter_vector::max_polls() throw()
283 for(unsigned i
= 0; i
< types
->indices(); i
++) {
284 uint32_t tmp
= ctrs
[i
] & 0x7FFFFFFFUL
;
285 max
= (max
< tmp
) ? tmp
: max
;
290 void pollcounter_vector::save_state(std::vector
<uint32_t>& mem
) throw(std::bad_alloc
)
292 mem
.resize(types
->indices());
294 for(size_t i
= 0; i
< types
->indices(); i
++)
298 void pollcounter_vector::load_state(const std::vector
<uint32_t>& mem
) throw()
300 for(size_t i
= 0; i
< types
->indices(); i
++)
304 bool pollcounter_vector::check(const std::vector
<uint32_t>& mem
) throw()
306 return (mem
.size() == types
->indices());
310 controller_frame::controller_frame(const port_type_set
& p
) throw(std::runtime_error
)
312 memset(memory
, 0, sizeof(memory
));
317 controller_frame::controller_frame(unsigned char* mem
, const port_type_set
& p
) throw(std::runtime_error
)
320 throw std::runtime_error("NULL backing memory not allowed");
321 memset(memory
, 0, sizeof(memory
));
326 controller_frame::controller_frame(const controller_frame
& obj
) throw()
328 memset(memory
, 0, sizeof(memory
));
331 memcpy(backing
, obj
.backing
, types
->size());
334 controller_frame
& controller_frame::operator=(const controller_frame
& obj
) throw(std::runtime_error
)
336 if(backing
!= memory
&& types
!= obj
.types
)
337 throw std::runtime_error("Port types do not match");
339 memcpy(backing
, obj
.backing
, types
->size());
343 size_t controller_frame_vector::walk_helper(size_t frame
, bool sflag
) throw()
345 size_t ret
= sflag
? frame
: 0;
350 size_t page
= frame
/ frames_per_page
;
351 size_t offset
= frame_size
* (frame
% frames_per_page
);
352 size_t index
= frame
% frames_per_page
;
353 if(cache_page_num
!= page
) {
354 cache_page
= &pages
[page
];
355 cache_page_num
= page
;
357 while(frame
< frames
) {
358 if(index
== frames_per_page
) {
360 cache_page
= &pages
[page
];
361 cache_page_num
= page
;
363 if(controller_frame::sync(cache_page
->content
+ offset
))
366 offset
+= frame_size
;
373 size_t controller_frame_vector::count_frames() throw()
379 cache_page
= &pages
[0];
382 for(size_t i
= 0; i
< frames
; i
++) {
383 if(index
== frames_per_page
) {
385 cache_page
= &pages
[cache_page_num
];
389 if(controller_frame::sync(cache_page
->content
+ offset
))
392 offset
+= frame_size
;
398 void controller_frame_vector::clear(const port_type_set
& p
) throw(std::runtime_error
)
400 frame_size
= p
.size();
401 frames_per_page
= CONTROLLER_PAGE_SIZE
/ frame_size
;
408 controller_frame_vector::~controller_frame_vector() throw()
414 controller_frame_vector::controller_frame_vector() throw()
419 controller_frame_vector::controller_frame_vector(const port_type_set
& p
) throw()
424 void controller_frame_vector::append(controller_frame frame
) throw(std::bad_alloc
, std::runtime_error
)
426 controller_frame
check(*types
);
427 if(!check
.types_match(frame
))
428 throw std::runtime_error("controller_frame_vector::append: Type mismatch");
429 if(frames
% frames_per_page
== 0) {
431 pages
[frames
/ frames_per_page
];
434 size_t page
= frames
/ frames_per_page
;
435 size_t offset
= frame_size
* (frames
% frames_per_page
);
436 if(cache_page_num
!= page
) {
437 cache_page_num
= page
;
438 cache_page
= &pages
[page
];
440 controller_frame(cache_page
->content
+ offset
, *types
) = frame
;
444 controller_frame_vector::controller_frame_vector(const controller_frame_vector
& vector
) throw(std::bad_alloc
)
446 clear(*vector
.types
);
450 controller_frame_vector
& controller_frame_vector::operator=(const controller_frame_vector
& v
)
451 throw(std::bad_alloc
)
459 frame_size
= v
.frame_size
;
460 frames_per_page
= v
.frames_per_page
;
463 //This can't fail anymore. Copy the raw page contents.
464 size_t pagecount
= (frames
+ frames_per_page
- 1) / frames_per_page
;
465 for(size_t i
= 0; i
< pagecount
; i
++) {
467 const page
& pg2
= v
.pages
.find(i
)->second
;
477 void controller_frame_vector::resize(size_t newsize
) throw(std::bad_alloc
)
482 } else if(newsize
< frames
) {
484 size_t current_pages
= (frames
+ frames_per_page
- 1) / frames_per_page
;
485 size_t pages_needed
= (newsize
+ frames_per_page
- 1) / frames_per_page
;
486 for(size_t i
= pages_needed
; i
< current_pages
; i
++)
488 //Now zeroize the excess memory.
489 if(newsize
< pages_needed
* frames_per_page
) {
490 size_t offset
= frame_size
* (newsize
% frames_per_page
);
491 memset(pages
[pages_needed
- 1].content
+ offset
, 0, CONTROLLER_PAGE_SIZE
- offset
);
494 } else if(newsize
> frames
) {
496 size_t current_pages
= (frames
+ frames_per_page
- 1) / frames_per_page
;
497 size_t pages_needed
= (newsize
+ frames_per_page
- 1) / frames_per_page
;
498 //Create the needed pages.
499 for(size_t i
= current_pages
; i
< pages_needed
; i
++) {
503 for(size_t i
= current_pages
; i
< pages_needed
; i
++)
513 controller_frame::controller_frame() throw()
515 memset(memory
, 0, sizeof(memory
));
517 types
= &dummytypes();
520 unsigned port_controller::analog_actions() const
523 for(unsigned i
= 0; i
< button_count
; i
++)
524 if(buttons
[i
]->is_analog() && !buttons
[i
]->shadow
)
529 std::pair
<unsigned, unsigned> port_controller::analog_action(unsigned k
) const
531 unsigned x1
= std::numeric_limits
<unsigned>::max();
532 unsigned x2
= std::numeric_limits
<unsigned>::max();
534 for(unsigned i
= 0; i
< button_count
; i
++)
535 if(buttons
[i
]->is_analog() && !buttons
[i
]->shadow
) {
542 return std::make_pair(x1
, x2
);