15
15
16
16
#include " multiplex-mappers-internal.h"
17
17
18
- namespace rgb_matrix {
19
- namespace internal {
20
- // A Pixel Mapper maps physical pixels locations to the internal logical
21
- // mapping in a panel or panel-assembly, which depends on the wiring.
22
- class MultiplexMapperBase : public MultiplexMapper {
23
- public:
24
- MultiplexMapperBase (const char *name, int stretch_factor)
25
- : name_(name), panel_stretch_factor_(stretch_factor) {}
26
-
27
- // This method is const, but we sneakily remember the original size
28
- // of the panels so that we can more easily quantize things.
29
- // So technically, we're stateful, but let's pretend we're not changing
30
- // state. In the context this is used, it is never accessed in multiple
31
- // threads.
32
- virtual void EditColsRows (int *cols, int *rows) const {
33
- panel_rows_ = *rows;
34
- panel_cols_ = *cols;
35
-
36
- *rows /= panel_stretch_factor_;
37
- *cols *= panel_stretch_factor_;
38
- }
39
-
40
- virtual bool GetSizeMapping (int matrix_width, int matrix_height,
41
- int *visible_width, int *visible_height) const {
42
- // Matrix width has been altered. Alter it back.
43
- *visible_width = matrix_width / panel_stretch_factor_;
44
- *visible_height = matrix_height * panel_stretch_factor_;
45
- return true ;
46
- }
47
-
48
- virtual const char *GetName () const { return name_; }
49
-
50
- // The MapVisibleToMatrix() as required by PanelMatrix here breaks it
51
- // down to the individual panel, so that derived classes only need to
52
- // implement MapSinglePanel().
53
- virtual void MapVisibleToMatrix (int matrix_width, int matrix_height,
54
- int visible_x, int visible_y,
55
- int *matrix_x, int *matrix_y) const {
56
- const int chained_panel = visible_x / panel_cols_;
57
- const int parallel_panel = visible_y / panel_rows_;
58
-
59
- const int within_panel_x = visible_x % panel_cols_;
60
- const int within_panel_y = visible_y % panel_rows_;
61
-
62
- int new_x, new_y;
63
- MapSinglePanel (within_panel_x, within_panel_y, &new_x, &new_y);
64
- *matrix_x = chained_panel * panel_stretch_factor_*panel_cols_ + new_x;
65
- *matrix_y = parallel_panel * panel_rows_/panel_stretch_factor_ + new_y;
66
- }
67
-
68
- // Map the coordinates for a single panel. This is to be overridden in
69
- // derived classes.
70
- // Input parameter is the visible position on the matrix, and this method
71
- // should return the internal multiplexed position.
72
- virtual void MapSinglePanel (int visible_x, int visible_y,
73
- int *matrix_x, int *matrix_y) const = 0;
74
-
75
- protected:
76
- const char *const name_;
77
- const int panel_stretch_factor_;
78
-
79
- mutable int panel_cols_;
80
- mutable int panel_rows_;
81
- };
82
-
83
-
84
- /* ========================================================================
18
+ namespace rgb_matrix
19
+ {
20
+ namespace internal
21
+ {
22
+ // A Pixel Mapper maps physical pixels locations to the internal logical
23
+ // mapping in a panel or panel-assembly, which depends on the wiring.
24
+ class MultiplexMapperBase : public MultiplexMapper
25
+ {
26
+ public:
27
+ MultiplexMapperBase (const char *name, int stretch_factor)
28
+ : name_(name), panel_stretch_factor_(stretch_factor) {}
29
+
30
+ // This method is const, but we sneakily remember the original size
31
+ // of the panels so that we can more easily quantize things.
32
+ // So technically, we're stateful, but let's pretend we're not changing
33
+ // state. In the context this is used, it is never accessed in multiple
34
+ // threads.
35
+ virtual void EditColsRows (int *cols, int *rows) const
36
+ {
37
+ panel_rows_ = *rows;
38
+ panel_cols_ = *cols;
39
+
40
+ *rows /= panel_stretch_factor_;
41
+ *cols *= panel_stretch_factor_;
42
+ }
43
+
44
+ virtual bool GetSizeMapping (int matrix_width, int matrix_height,
45
+ int *visible_width, int *visible_height) const
46
+ {
47
+ // Matrix width has been altered. Alter it back.
48
+ *visible_width = matrix_width / panel_stretch_factor_;
49
+ *visible_height = matrix_height * panel_stretch_factor_;
50
+ return true ;
51
+ }
52
+
53
+ virtual const char *GetName () const { return name_; }
54
+
55
+ // The MapVisibleToMatrix() as required by PanelMatrix here breaks it
56
+ // down to the individual panel, so that derived classes only need to
57
+ // implement MapSinglePanel().
58
+ virtual void MapVisibleToMatrix (int matrix_width, int matrix_height,
59
+ int visible_x, int visible_y,
60
+ int *matrix_x, int *matrix_y) const
61
+ {
62
+ const int chained_panel = visible_x / panel_cols_;
63
+ const int parallel_panel = visible_y / panel_rows_;
64
+
65
+ const int within_panel_x = visible_x % panel_cols_;
66
+ const int within_panel_y = visible_y % panel_rows_;
67
+
68
+ int new_x, new_y;
69
+ MapSinglePanel (within_panel_x, within_panel_y, &new_x, &new_y);
70
+ *matrix_x = chained_panel * panel_stretch_factor_ * panel_cols_ + new_x;
71
+ *matrix_y = parallel_panel * panel_rows_ / panel_stretch_factor_ + new_y;
72
+ }
73
+
74
+ // Map the coordinates for a single panel. This is to be overridden in
75
+ // derived classes.
76
+ // Input parameter is the visible position on the matrix, and this method
77
+ // should return the internal multiplexed position.
78
+ virtual void MapSinglePanel (int visible_x, int visible_y,
79
+ int *matrix_x, int *matrix_y) const = 0;
80
+
81
+ protected:
82
+ const char *const name_;
83
+ const int panel_stretch_factor_;
84
+
85
+ mutable int panel_cols_;
86
+ mutable int panel_rows_;
87
+ };
88
+
89
+ /* ========================================================================
85
90
* Multiplexer implementations.
86
91
*
87
92
* Extend MultiplexMapperBase and implement MapSinglePanel. You only have
@@ -92,350 +97,393 @@ class MultiplexMapperBase : public MultiplexMapper {
92
97
* below. After that, the new mapper is available in the --led-multiplexing
93
98
* option.
94
99
*/
95
- class StripeMultiplexMapper : public MultiplexMapperBase {
96
- public:
97
- StripeMultiplexMapper () : MultiplexMapperBase(" Stripe" , 2 ) {}
98
-
99
- void MapSinglePanel (int x, int y, int *matrix_x, int *matrix_y) const {
100
- const bool is_top_stripe = (y % (panel_rows_/2 )) < panel_rows_/4 ;
101
- *matrix_x = is_top_stripe ? x + panel_cols_ : x;
102
- *matrix_y = ((y / (panel_rows_/2 )) * (panel_rows_/4 )
103
- + y % (panel_rows_/4 ));
104
- }
105
- };
106
-
107
- class CheckeredMultiplexMapper : public MultiplexMapperBase {
108
- public:
109
- CheckeredMultiplexMapper () : MultiplexMapperBase(" Checkered" , 2 ) {}
110
-
111
- void MapSinglePanel (int x, int y, int *matrix_x, int *matrix_y) const {
112
- const bool is_top_check = (y % (panel_rows_/2 )) < panel_rows_/4 ;
113
- const bool is_left_check = (x < panel_cols_/2 );
114
- if (is_top_check) {
115
- *matrix_x = is_left_check ? x+panel_cols_/2 : x+panel_cols_;
116
- } else {
117
- *matrix_x = is_left_check ? x : x + panel_cols_/2 ;
118
- }
119
- *matrix_y = ((y / (panel_rows_/2 )) * (panel_rows_/4 )
120
- + y % (panel_rows_/4 ));
121
- }
122
- };
123
-
124
- class SpiralMultiplexMapper : public MultiplexMapperBase {
125
- public:
126
- SpiralMultiplexMapper () : MultiplexMapperBase(" Spiral" , 2 ) {}
127
-
128
- void MapSinglePanel (int x, int y, int *matrix_x, int *matrix_y) const {
129
- const bool is_top_stripe = (y % (panel_rows_/2 )) < panel_rows_/4 ;
130
- const int panel_quarter = panel_cols_/4 ;
131
- const int quarter = x / panel_quarter;
132
- const int offset = x % panel_quarter;
133
- *matrix_x = ((2 *quarter*panel_quarter)
134
- + (is_top_stripe
135
- ? panel_quarter - 1 - offset
136
- : panel_quarter + offset));
137
- *matrix_y = ((y / (panel_rows_/2 )) * (panel_rows_/4 )
138
- + y % (panel_rows_/4 ));
139
- }
140
- };
141
-
142
- class ZStripeMultiplexMapper : public MultiplexMapperBase {
143
- public:
144
- ZStripeMultiplexMapper (const char *name, int even_vblock_offset, int odd_vblock_offset)
145
- : MultiplexMapperBase(name, 2 ),
146
- even_vblock_offset_ (even_vblock_offset),
147
- odd_vblock_offset_(odd_vblock_offset) {}
148
-
149
- void MapSinglePanel (int x, int y, int *matrix_x, int *matrix_y) const {
150
- static const int tile_width = 8 ;
151
- static const int tile_height = 4 ;
152
-
153
- const int vert_block_is_odd = ((y / tile_height) % 2 );
154
-
155
- const int even_vblock_shift = (1 - vert_block_is_odd) * even_vblock_offset_;
156
- const int odd_vblock_shitf = vert_block_is_odd * odd_vblock_offset_;
157
-
158
- *matrix_x = x + ((x + even_vblock_shift) / tile_width) * tile_width + odd_vblock_shitf;
159
- *matrix_y = (y % tile_height) + tile_height * (y / (tile_height * 2 ));
160
- }
161
-
162
- private:
163
- const int even_vblock_offset_;
164
- const int odd_vblock_offset_;
165
- };
166
-
167
- class CoremanMapper : public MultiplexMapperBase {
168
- public:
169
- CoremanMapper () : MultiplexMapperBase(" coreman" , 2 ) {}
170
-
171
- void MapSinglePanel (int x, int y, int *matrix_x, int *matrix_y) const {
172
- const bool is_left_check = (x < panel_cols_/2 );
173
-
174
- if ((y <= 7 ) || ((y >= 16 ) && (y <= 23 ))){
175
- *matrix_x = ((x / (panel_cols_/2 )) * panel_cols_) + (x % (panel_cols_/2 ));
176
- if ((y & (panel_rows_/4 )) == 0 ) {
177
- *matrix_y = (y / (panel_rows_/2 )) * (panel_rows_/4 ) + (y % (panel_rows_/4 ));
100
+ class StripeMultiplexMapper : public MultiplexMapperBase
101
+ {
102
+ public:
103
+ StripeMultiplexMapper () : MultiplexMapperBase(" Stripe" , 2 ) {}
104
+
105
+ void MapSinglePanel (int x, int y, int *matrix_x, int *matrix_y) const
106
+ {
107
+ const bool is_top_stripe = (y % (panel_rows_ / 2 )) < panel_rows_ / 4 ;
108
+ *matrix_x = is_top_stripe ? x + panel_cols_ : x;
109
+ *matrix_y = ((y / (panel_rows_ / 2 )) * (panel_rows_ / 4 ) + y % (panel_rows_ / 4 ));
178
110
}
179
- } else {
180
- *matrix_x = is_left_check ? x + panel_cols_/2 : x + panel_cols_;
181
- *matrix_y = (y / (panel_rows_/2 )) * (panel_rows_/4 ) + y % (panel_rows_/4 );
182
- }
183
- }
184
- };
185
-
186
- class Kaler2ScanMapper : public MultiplexMapperBase {
187
- public:
188
- Kaler2ScanMapper () : MultiplexMapperBase(" Kaler2Scan" , 4 ) {}
189
-
190
- void MapSinglePanel (int x, int y, int *matrix_x, int *matrix_y) const {
191
- // Now we have a 128x4 matrix
192
- int offset = ((y%4 )/2 ) == 0 ? -1 : 1 ;// Add o substract
193
- int deltaOffset = offset < 0 ? 7 :8 ;
194
- int deltaColumn = ((y%8 )/4 )== 0 ? 64 : 0 ;
195
-
196
- *matrix_y = (y%2 +(y/8 )*2 );
197
- *matrix_x = deltaColumn + (16 * (x/8 )) + deltaOffset + ((x%8 ) * offset);
198
-
199
- }
200
- };
201
-
202
- class P10MapperZ : public MultiplexMapperBase {
203
- public:
204
- P10MapperZ () : MultiplexMapperBase(" P10-128x4-Z" , 4 ) {}
205
- // supports this panel: https://www.aliexpress.com/item/2017-Special-Offer-P10-Outdoor-Smd-Full-Color-Led-Display-Module-320x160mm-1-2-Scan-Outdoor/32809267439.html?spm=a2g0s.9042311.0.0.Ob0jEw
206
- // with --led-row-addr-type=2 flag
207
- void MapSinglePanel (int x, int y, int *matrix_x, int *matrix_y) const {
208
- int yComp = 0 ;
209
- if (y == 0 || y == 1 || y == 8 || y == 9 ) {
210
- yComp = 127 ;
211
- }
212
- else if (y == 2 || y == 3 || y == 10 || y == 11 ) {
213
- yComp = 112 ;
214
- }
215
- else if (y == 4 || y == 5 || y == 12 || y == 13 ) {
216
- yComp = 111 ;
217
- }
218
- else if (y == 6 || y == 7 || y == 14 || y == 15 ) {
219
- yComp = 96 ;
220
- }
111
+ };
221
112
222
- if (y == 0 || y == 1 || y == 4 || y == 5 ||
223
- y == 8 || y == 9 || y == 12 || y == 13 ) {
224
- *matrix_x = yComp - x;
225
- *matrix_x -= (24 * ((int )(x / 8 )));
226
- }
227
- else {
228
- *matrix_x = yComp + x;
229
- *matrix_x -= (40 * ((int )(x / 8 )));
230
- }
113
+ class CheckeredMultiplexMapper : public MultiplexMapperBase
114
+ {
115
+ public:
116
+ CheckeredMultiplexMapper () : MultiplexMapperBase(" Checkered" , 2 ) {}
117
+
118
+ void MapSinglePanel (int x, int y, int *matrix_x, int *matrix_y) const
119
+ {
120
+ const bool is_top_check = (y % (panel_rows_ / 2 )) < panel_rows_ / 4 ;
121
+ const bool is_left_check = (x < panel_cols_ / 2 );
122
+ if (is_top_check)
123
+ {
124
+ *matrix_x = is_left_check ? x + panel_cols_ / 2 : x + panel_cols_;
125
+ }
126
+ else
127
+ {
128
+ *matrix_x = is_left_check ? x : x + panel_cols_ / 2 ;
129
+ }
130
+ *matrix_y = ((y / (panel_rows_ / 2 )) * (panel_rows_ / 4 ) + y % (panel_rows_ / 4 ));
131
+ }
132
+ };
231
133
232
- if (y == 0 || y == 2 || y == 4 || y == 6 ) {
233
- *matrix_y = 3 ;
234
- }
235
- else if (y == 1 || y == 3 || y == 5 || y == 7 ) {
236
- *matrix_y = 2 ;
237
- }
238
- else if (y == 8 || y == 10 || y == 12 || y == 14 ) {
239
- *matrix_y = 1 ;
240
- }
241
- else if (y == 9 || y == 11 || y == 13 || y == 15 ) {
242
- *matrix_y = 0 ;
243
- }
244
- }
245
- };
246
-
247
- class QiangLiQ8 : public MultiplexMapperBase {
248
- public:
249
- QiangLiQ8 () : MultiplexMapperBase(" QiangLiQ8" , 2 ) {}
250
-
251
- void MapSinglePanel (int x, int y, int *matrix_x, int *matrix_y) const {
252
- const int column = x + (4 + 4 *(x/4 ));
253
- *matrix_x = column;
254
- if ((y >= 15 && y <=19 ) || (y >= 5 && y <= 9 )) {
255
- const int reverseColumn = x + (4 *(x/4 ));
256
- *matrix_x = reverseColumn;
257
- }
258
- *matrix_y = y % 5 + (y/10 ) *5 ;
259
- }
260
- };
134
+ class SpiralMultiplexMapper : public MultiplexMapperBase
135
+ {
136
+ public:
137
+ SpiralMultiplexMapper () : MultiplexMapperBase(" Spiral" , 2 ) {}
138
+
139
+ void MapSinglePanel (int x, int y, int *matrix_x, int *matrix_y) const
140
+ {
141
+ const bool is_top_stripe = (y % (panel_rows_ / 2 )) < panel_rows_ / 4 ;
142
+ const int panel_quarter = panel_cols_ / 4 ;
143
+ const int quarter = x / panel_quarter;
144
+ const int offset = x % panel_quarter;
145
+ *matrix_x = ((2 * quarter * panel_quarter) + (is_top_stripe
146
+ ? panel_quarter - 1 - offset
147
+ : panel_quarter + offset));
148
+ *matrix_y = ((y / (panel_rows_ / 2 )) * (panel_rows_ / 4 ) + y % (panel_rows_ / 4 ));
149
+ }
150
+ };
261
151
262
- class InversedZStripe : public MultiplexMapperBase {
263
- public:
264
- InversedZStripe () : MultiplexMapperBase(" InversedZStripe" , 2 ) {}
152
+ class ZStripeMultiplexMapper : public MultiplexMapperBase
153
+ {
154
+ public:
155
+ ZStripeMultiplexMapper (const char *name, int even_vblock_offset, int odd_vblock_offset)
156
+ : MultiplexMapperBase(name, 2 ),
157
+ even_vblock_offset_ (even_vblock_offset),
158
+ odd_vblock_offset_(odd_vblock_offset) {}
265
159
266
- void MapSinglePanel (int x, int y, int *matrix_x, int *matrix_y) const {
267
- static const int tile_width = 8 ;
268
- static const int tile_height = 4 ;
160
+ void MapSinglePanel (int x, int y, int *matrix_x, int *matrix_y) const
161
+ {
162
+ static const int tile_width = 8 ;
163
+ static const int tile_height = 4 ;
269
164
270
- const int vert_block_is_odd = ((y / tile_height) % 2 );
271
- const int evenOffset[8 ] = {7 , 5 , 3 , 1 , -1 , -3 , -5 , -7 };
165
+ const int vert_block_is_odd = ((y / tile_height) % 2 );
272
166
273
- if (vert_block_is_odd) {
274
- *matrix_x = x + (x / tile_width) * tile_width;
275
- } else {
276
- *matrix_x = x + (x / tile_width) * tile_width + 8 + evenOffset[x % 8 ];
277
- }
278
- *matrix_y = (y % tile_height) + tile_height * (y / (tile_height * 2 ));
279
- }
280
- };
167
+ const int even_vblock_shift = (1 - vert_block_is_odd) * even_vblock_offset_;
168
+ const int odd_vblock_shitf = vert_block_is_odd * odd_vblock_offset_;
281
169
170
+ *matrix_x = x + ((x + even_vblock_shift) / tile_width) * tile_width + odd_vblock_shitf;
171
+ *matrix_y = (y % tile_height) + tile_height * (y / (tile_height * 2 ));
172
+ }
173
+
174
+ private:
175
+ const int even_vblock_offset_;
176
+ const int odd_vblock_offset_;
177
+ };
178
+
179
+ class CoremanMapper : public MultiplexMapperBase
180
+ {
181
+ public:
182
+ CoremanMapper () : MultiplexMapperBase(" coreman" , 2 ) {}
183
+
184
+ void MapSinglePanel (int x, int y, int *matrix_x, int *matrix_y) const
185
+ {
186
+ const bool is_left_check = (x < panel_cols_ / 2 );
187
+
188
+ if ((y <= 7 ) || ((y >= 16 ) && (y <= 23 )))
189
+ {
190
+ *matrix_x = ((x / (panel_cols_ / 2 )) * panel_cols_) + (x % (panel_cols_ / 2 ));
191
+ if ((y & (panel_rows_ / 4 )) == 0 )
192
+ {
193
+ *matrix_y = (y / (panel_rows_ / 2 )) * (panel_rows_ / 4 ) + (y % (panel_rows_ / 4 ));
194
+ }
195
+ }
196
+ else
197
+ {
198
+ *matrix_x = is_left_check ? x + panel_cols_ / 2 : x + panel_cols_;
199
+ *matrix_y = (y / (panel_rows_ / 2 )) * (panel_rows_ / 4 ) + y % (panel_rows_ / 4 );
200
+ }
201
+ }
202
+ };
282
203
283
- /*
204
+ class Kaler2ScanMapper : public MultiplexMapperBase
205
+ {
206
+ public:
207
+ Kaler2ScanMapper () : MultiplexMapperBase(" Kaler2Scan" , 4 ) {}
208
+
209
+ void MapSinglePanel (int x, int y, int *matrix_x, int *matrix_y) const
210
+ {
211
+ // Now we have a 128x4 matrix
212
+ int offset = ((y % 4 ) / 2 ) == 0 ? -1 : 1 ; // Add o substract
213
+ int deltaOffset = offset < 0 ? 7 : 8 ;
214
+ int deltaColumn = ((y % 8 ) / 4 ) == 0 ? 64 : 0 ;
215
+
216
+ *matrix_y = (y % 2 + (y / 8 ) * 2 );
217
+ *matrix_x = deltaColumn + (16 * (x / 8 )) + deltaOffset + ((x % 8 ) * offset);
218
+ }
219
+ };
220
+
221
+ class P10MapperZ : public MultiplexMapperBase
222
+ {
223
+ public:
224
+ P10MapperZ () : MultiplexMapperBase(" P10-128x4-Z" , 4 ) {}
225
+ // supports this panel: https://www.aliexpress.com/item/2017-Special-Offer-P10-Outdoor-Smd-Full-Color-Led-Display-Module-320x160mm-1-2-Scan-Outdoor/32809267439.html?spm=a2g0s.9042311.0.0.Ob0jEw
226
+ // with --led-row-addr-type=2 flag
227
+ void MapSinglePanel (int x, int y, int *matrix_x, int *matrix_y) const
228
+ {
229
+ int yComp = 0 ;
230
+ if (y == 0 || y == 1 || y == 8 || y == 9 )
231
+ {
232
+ yComp = 127 ;
233
+ }
234
+ else if (y == 2 || y == 3 || y == 10 || y == 11 )
235
+ {
236
+ yComp = 112 ;
237
+ }
238
+ else if (y == 4 || y == 5 || y == 12 || y == 13 )
239
+ {
240
+ yComp = 111 ;
241
+ }
242
+ else if (y == 6 || y == 7 || y == 14 || y == 15 )
243
+ {
244
+ yComp = 96 ;
245
+ }
246
+
247
+ if (y == 0 || y == 1 || y == 4 || y == 5 ||
248
+ y == 8 || y == 9 || y == 12 || y == 13 )
249
+ {
250
+ *matrix_x = yComp - x;
251
+ *matrix_x -= (24 * ((int )(x / 8 )));
252
+ }
253
+ else
254
+ {
255
+ *matrix_x = yComp + x;
256
+ *matrix_x -= (40 * ((int )(x / 8 )));
257
+ }
258
+
259
+ if (y == 0 || y == 2 || y == 4 || y == 6 )
260
+ {
261
+ *matrix_y = 3 ;
262
+ }
263
+ else if (y == 1 || y == 3 || y == 5 || y == 7 )
264
+ {
265
+ *matrix_y = 2 ;
266
+ }
267
+ else if (y == 8 || y == 10 || y == 12 || y == 14 )
268
+ {
269
+ *matrix_y = 1 ;
270
+ }
271
+ else if (y == 9 || y == 11 || y == 13 || y == 15 )
272
+ {
273
+ *matrix_y = 0 ;
274
+ }
275
+ }
276
+ };
277
+
278
+ class QiangLiQ8 : public MultiplexMapperBase
279
+ {
280
+ public:
281
+ QiangLiQ8 () : MultiplexMapperBase(" QiangLiQ8" , 2 ) {}
282
+
283
+ void MapSinglePanel (int x, int y, int *matrix_x, int *matrix_y) const
284
+ {
285
+ const int column = x + (4 + 4 * (x / 4 ));
286
+ *matrix_x = column;
287
+ if ((y >= 15 && y <= 19 ) || (y >= 5 && y <= 9 ))
288
+ {
289
+ const int reverseColumn = x + (4 * (x / 4 ));
290
+ *matrix_x = reverseColumn;
291
+ }
292
+ *matrix_y = y % 5 + (y / 10 ) * 5 ;
293
+ }
294
+ };
295
+
296
+ class InversedZStripe : public MultiplexMapperBase
297
+ {
298
+ public:
299
+ InversedZStripe () : MultiplexMapperBase(" InversedZStripe" , 2 ) {}
300
+
301
+ void MapSinglePanel (int x, int y, int *matrix_x, int *matrix_y) const
302
+ {
303
+ static const int tile_width = 8 ;
304
+ static const int tile_height = 4 ;
305
+
306
+ const int vert_block_is_odd = ((y / tile_height) % 2 );
307
+ const int evenOffset[8 ] = {7 , 5 , 3 , 1 , -1 , -3 , -5 , -7 };
308
+
309
+ if (vert_block_is_odd)
310
+ {
311
+ *matrix_x = x + (x / tile_width) * tile_width;
312
+ }
313
+ else
314
+ {
315
+ *matrix_x = x + (x / tile_width) * tile_width + 8 + evenOffset[x % 8 ];
316
+ }
317
+ *matrix_y = (y % tile_height) + tile_height * (y / (tile_height * 2 ));
318
+ }
319
+ };
320
+
321
+ /*
284
322
* Vairous P10 1R1G1B Outdoor implementations for 16x16 modules with separate
285
323
* RGB LEDs, e.g.:
286
324
* https://www.ledcontrollercard.com/english/p10-outdoor-rgb-led-module-160x160mm-dip.html
287
325
*
288
326
*/
289
- class P10Outdoor1R1G1BMultiplexBase : public MultiplexMapperBase {
290
- public:
291
- P10Outdoor1R1G1BMultiplexBase (const char *name)
292
- : MultiplexMapperBase(name, 2 ) {}
293
-
294
- void MapSinglePanel (int x, int y, int *matrix_x, int *matrix_y) const {
295
- const int vblock_is_odd = (y / tile_height_) % 2 ;
296
- const int vblock_is_even = 1 - vblock_is_odd;
297
- const int even_vblock_shift = vblock_is_even * even_vblock_offset_;
298
- const int odd_vblock_shift = vblock_is_odd * odd_vblock_offset_;
299
-
300
- MapPanel (x, y, matrix_x, matrix_y,
301
- vblock_is_even, vblock_is_odd,
302
- even_vblock_shift, odd_vblock_shift);
303
- }
304
-
305
- protected:
306
- virtual void MapPanel (int x, int y, int *matrix_x, int *matrix_y,
307
- int vblock_is_even, int vblock_is_odd,
308
- int even_vblock_shift, int odd_vblock_shift) const = 0;
309
-
310
- static const int tile_width_ = 8 ;
311
- static const int tile_height_ = 4 ;
312
- static const int even_vblock_offset_ = 0 ;
313
- static const int odd_vblock_offset_ = 8 ;
314
- };
315
-
316
- class P10Outdoor1R1G1BMultiplexMapper1 : public P10Outdoor1R1G1BMultiplexBase {
317
- public:
318
- P10Outdoor1R1G1BMultiplexMapper1 ()
319
- : P10Outdoor1R1G1BMultiplexBase(" P10Outdoor1R1G1-1" ) {}
320
-
321
- protected:
322
- void MapPanel (int x, int y, int *matrix_x, int *matrix_y,
323
- const int vblock_is_even, const int vblock_is_odd,
324
- const int even_vblock_shift, const int odd_vblock_shift) const {
325
- *matrix_x = tile_width_ * (1 + vblock_is_even + 2 * (x / tile_width_))
326
- - (x % tile_width_) - 1 ;
327
- *matrix_y = (y % tile_height_) + tile_height_ * (y / (tile_height_ * 2 ));
328
- }
329
- };
330
-
331
- class P10Outdoor1R1G1BMultiplexMapper2 : public P10Outdoor1R1G1BMultiplexBase {
332
- public:
333
- P10Outdoor1R1G1BMultiplexMapper2 ()
334
- : P10Outdoor1R1G1BMultiplexBase(" P10Outdoor1R1G1-2" ) {}
335
-
336
- protected:
337
- void MapPanel (int x, int y, int *matrix_x, int *matrix_y,
338
- const int vblock_is_even, const int vblock_is_odd,
339
- const int even_vblock_shift, const int odd_vblock_shift) const {
340
- *matrix_x = vblock_is_even
341
- ? tile_width_ * (1 + 2 * (x / tile_width_)) - (x % tile_width_) - 1
342
- : x + ((x + even_vblock_shift) / tile_width_) * tile_width_ + odd_vblock_shift;
343
- *matrix_y = (y % tile_height_) + tile_height_ * (y / (tile_height_ * 2 ));
344
- }
345
- };
346
-
347
- class P10Outdoor1R1G1BMultiplexMapper3 : public P10Outdoor1R1G1BMultiplexBase {
348
- public:
349
- P10Outdoor1R1G1BMultiplexMapper3 ()
350
- : P10Outdoor1R1G1BMultiplexBase(" P10Outdoor1R1G1-3" ) {}
351
-
352
- protected:
353
- void MapPanel (int x, int y, int *matrix_x, int *matrix_y,
354
- const int vblock_is_even, const int vblock_is_odd,
355
- const int even_vblock_shift, const int odd_vblock_shift) const {
356
- *matrix_x = vblock_is_odd
357
- ? tile_width_ * (2 + 2 * (x / tile_width_)) - (x % tile_width_) - 1
358
- : x + ((x + even_vblock_shift) / tile_width_) * tile_width_ + odd_vblock_shift;
359
- *matrix_y = (y % tile_height_) + tile_height_ * (y / (tile_height_ * 2 ));
360
- }
361
- };
362
-
363
- class P10CoremanMapper : public MultiplexMapperBase {
364
- public:
365
- P10CoremanMapper () : MultiplexMapperBase(" P10CoremanMapper" , 4 ) {}
366
-
367
- void MapSinglePanel (int x, int y, int *matrix_x, int *matrix_y) const {
368
- // Row offset 8,8,8,8,0,0,0,0,8,8,8,8,0,0,0,0
369
- int mulY = (y & 4 ) > 0 ? 0 : 8 ;
370
-
371
- // Row offset 9,9,8,8,1,1,0,0,9,9,8,8,1,1,0,0
372
- mulY += (y & 2 ) > 0 ? 0 : 1 ;
373
- mulY += (x >> 2 ) & ~1 ; // Drop lsb
374
-
375
- *matrix_x = (mulY << 3 ) + x % 8 ;
376
- *matrix_y = (y & 1 ) + ((y >> 2 ) & ~1 );
377
- }
378
- };
379
-
380
- class P8KryQMapper : public MultiplexMapperBase
381
- {
382
- public:
383
- P8KryQMapper () : MultiplexMapperBase(" P8KryQMapper" , 2 ) {}
327
+ class P10Outdoor1R1G1BMultiplexBase : public MultiplexMapperBase
328
+ {
329
+ public:
330
+ P10Outdoor1R1G1BMultiplexBase (const char *name)
331
+ : MultiplexMapperBase(name, 2 ) {}
332
+
333
+ void MapSinglePanel (int x, int y, int *matrix_x, int *matrix_y) const
334
+ {
335
+ const int vblock_is_odd = (y / tile_height_) % 2 ;
336
+ const int vblock_is_even = 1 - vblock_is_odd;
337
+ const int even_vblock_shift = vblock_is_even * even_vblock_offset_;
338
+ const int odd_vblock_shift = vblock_is_odd * odd_vblock_offset_;
339
+
340
+ MapPanel (x, y, matrix_x, matrix_y,
341
+ vblock_is_even, vblock_is_odd,
342
+ even_vblock_shift, odd_vblock_shift);
343
+ }
384
344
385
- void MapSinglePanel ( int x, int y, int *matrix_x, int *matrix_y) const
386
- {
387
- static const int tile_width = 8 ;
388
- static const int tile_height = 5 ;
345
+ protected:
346
+ virtual void MapPanel ( int x, int y, int *matrix_x, int *matrix_y,
347
+ int vblock_is_even, int vblock_is_odd,
348
+ int even_vblock_shift, int odd_vblock_shift) const = 0 ;
389
349
390
- const int vert_block_is_odd = ((y / tile_height) % 2 );
391
- const int evenOffset[8 ] = {7 , 5 , 3 , 1 , -1 , -3 , -5 , -7 };
350
+ static const int tile_width_ = 8 ;
351
+ static const int tile_height_ = 4 ;
352
+ static const int even_vblock_offset_ = 0 ;
353
+ static const int odd_vblock_offset_ = 8 ;
354
+ };
392
355
393
- if (!vert_block_is_odd)
356
+ class P10Outdoor1R1G1BMultiplexMapper1 : public P10Outdoor1R1G1BMultiplexBase
394
357
{
395
- x = x + (x / tile_width) * tile_width;
396
- }
397
- else
358
+ public:
359
+ P10Outdoor1R1G1BMultiplexMapper1 ()
360
+ : P10Outdoor1R1G1BMultiplexBase(" P10Outdoor1R1G1-1" ) {}
361
+
362
+ protected:
363
+ void MapPanel (int x, int y, int *matrix_x, int *matrix_y,
364
+ const int vblock_is_even, const int vblock_is_odd,
365
+ const int even_vblock_shift, const int odd_vblock_shift) const
366
+ {
367
+ *matrix_x = tile_width_ * (1 + vblock_is_even + 2 * (x / tile_width_)) - (x % tile_width_) - 1 ;
368
+ *matrix_y = (y % tile_height_) + tile_height_ * (y / (tile_height_ * 2 ));
369
+ }
370
+ };
371
+
372
+ class P10Outdoor1R1G1BMultiplexMapper2 : public P10Outdoor1R1G1BMultiplexBase
398
373
{
399
- x = x + (x / tile_width) * tile_width + 8 + evenOffset[x % 8 ];
400
- }
374
+ public:
375
+ P10Outdoor1R1G1BMultiplexMapper2 ()
376
+ : P10Outdoor1R1G1BMultiplexBase(" P10Outdoor1R1G1-2" ) {}
377
+
378
+ protected:
379
+ void MapPanel (int x, int y, int *matrix_x, int *matrix_y,
380
+ const int vblock_is_even, const int vblock_is_odd,
381
+ const int even_vblock_shift, const int odd_vblock_shift) const
382
+ {
383
+ *matrix_x = vblock_is_even
384
+ ? tile_width_ * (1 + 2 * (x / tile_width_)) - (x % tile_width_) - 1
385
+ : x + ((x + even_vblock_shift) / tile_width_) * tile_width_ + odd_vblock_shift;
386
+ *matrix_y = (y % tile_height_) + tile_height_ * (y / (tile_height_ * 2 ));
387
+ }
388
+ };
389
+
390
+ class P10Outdoor1R1G1BMultiplexMapper3 : public P10Outdoor1R1G1BMultiplexBase
391
+ {
392
+ public:
393
+ P10Outdoor1R1G1BMultiplexMapper3 ()
394
+ : P10Outdoor1R1G1BMultiplexBase(" P10Outdoor1R1G1-3" ) {}
395
+
396
+ protected:
397
+ void MapPanel (int x, int y, int *matrix_x, int *matrix_y,
398
+ const int vblock_is_even, const int vblock_is_odd,
399
+ const int even_vblock_shift, const int odd_vblock_shift) const
400
+ {
401
+ *matrix_x = vblock_is_odd
402
+ ? tile_width_ * (2 + 2 * (x / tile_width_)) - (x % tile_width_) - 1
403
+ : x + ((x + even_vblock_shift) / tile_width_) * tile_width_ + odd_vblock_shift;
404
+ *matrix_y = (y % tile_height_) + tile_height_ * (y / (tile_height_ * 2 ));
405
+ }
406
+ };
407
+
408
+ class P10CoremanMapper : public MultiplexMapperBase
409
+ {
410
+ public:
411
+ P10CoremanMapper () : MultiplexMapperBase(" P10CoremanMapper" , 4 ) {}
412
+
413
+ void MapSinglePanel (int x, int y, int *matrix_x, int *matrix_y) const
414
+ {
415
+ // Row offset 8,8,8,8,0,0,0,0,8,8,8,8,0,0,0,0
416
+ int mulY = (y & 4 ) > 0 ? 0 : 8 ;
401
417
418
+ // Row offset 9,9,8,8,1,1,0,0,9,9,8,8,1,1,0,0
419
+ mulY += (y & 2 ) > 0 ? 0 : 1 ;
420
+ mulY += (x >> 2 ) & ~1 ; // Drop lsb
402
421
403
- *matrix_x = ((x/tile_width)+ 1 )*tile_width-(x%tile_width)- 1 ;
404
- *matrix_y = (y % tile_height ) + tile_height * (y / (tile_height * 2 ) );
405
- }
406
- };
422
+ *matrix_x = (mulY << 3 ) + x % 8 ;
423
+ *matrix_y = (y & 1 ) + ((y >> 2 ) & ~ 1 );
424
+ }
425
+ };
407
426
408
- /*
427
+ class P8KryQMapper : public MultiplexMapperBase
428
+ {
429
+ public:
430
+ P8KryQMapper () : MultiplexMapperBase(" P8KryQMapper" , 2 ) {}
431
+
432
+ void MapSinglePanel (int x, int y, int *matrix_x, int *matrix_y) const
433
+ {
434
+ static const int tile_width = 8 ;
435
+ static const int tile_height = 5 ;
436
+
437
+ const int vert_block_is_odd = ((y / tile_height) % 2 );
438
+ const int evenOffset[8 ] = {7 , 5 , 3 , 1 , -1 , -3 , -5 , -7 };
439
+
440
+ if (!vert_block_is_odd)
441
+ {
442
+ x = x + (x / tile_width) * tile_width;
443
+ }
444
+ else
445
+ {
446
+ x = x + (x / tile_width) * tile_width + 8 + evenOffset[x % 8 ];
447
+ }
448
+
449
+ *matrix_x = ((*matrix_x / 8 ) + 1 ) * 8 - (*matrix_x % 8 ) - 1 ;
450
+ *matrix_y = (y % tile_height) + tile_height * (y / (tile_height * 2 ));
451
+ }
452
+ };
453
+
454
+ /*
409
455
* Here is where the registration happens.
410
456
* If you add an instance of the mapper here, it will automatically be
411
457
* made available in the --led-multiplexing commandline option.
412
458
*/
413
- static MuxMapperList *CreateMultiplexMapperList () {
414
- MuxMapperList *result = new MuxMapperList ();
415
-
416
- // Here, register all multiplex mappers from above.
417
- result->push_back (new StripeMultiplexMapper ());
418
- result->push_back (new CheckeredMultiplexMapper ());
419
- result->push_back (new SpiralMultiplexMapper ());
420
- result->push_back (new ZStripeMultiplexMapper (" ZStripe" , 0 , 8 ));
421
- result->push_back (new ZStripeMultiplexMapper (" ZnMirrorZStripe" , 4 , 4 ));
422
- result->push_back (new CoremanMapper ());
423
- result->push_back (new Kaler2ScanMapper ());
424
- result->push_back (new ZStripeMultiplexMapper (" ZStripeUneven" , 8 , 0 ));
425
- result->push_back (new P10MapperZ ());
426
- result->push_back (new QiangLiQ8 ());
427
- result->push_back (new InversedZStripe ());
428
- result->push_back (new P10Outdoor1R1G1BMultiplexMapper1 ());
429
- result->push_back (new P10Outdoor1R1G1BMultiplexMapper2 ());
430
- result->push_back (new P10Outdoor1R1G1BMultiplexMapper3 ());
431
- result->push_back (new P10CoremanMapper ());
432
- result->push_back (new P8KryQMapper ());
433
- return result;
434
- }
435
-
436
- const MuxMapperList &GetRegisteredMultiplexMappers () {
437
- static const MuxMapperList *all_mappers = CreateMultiplexMapperList ();
438
- return *all_mappers;
439
- }
440
- } // namespace internal
441
- } // namespace rgb_matrix
459
+ static MuxMapperList *CreateMultiplexMapperList ()
460
+ {
461
+ MuxMapperList *result = new MuxMapperList ();
462
+
463
+ // Here, register all multiplex mappers from above.
464
+ result->push_back (new StripeMultiplexMapper ());
465
+ result->push_back (new CheckeredMultiplexMapper ());
466
+ result->push_back (new SpiralMultiplexMapper ());
467
+ result->push_back (new ZStripeMultiplexMapper (" ZStripe" , 0 , 8 ));
468
+ result->push_back (new ZStripeMultiplexMapper (" ZnMirrorZStripe" , 4 , 4 ));
469
+ result->push_back (new CoremanMapper ());
470
+ result->push_back (new Kaler2ScanMapper ());
471
+ result->push_back (new ZStripeMultiplexMapper (" ZStripeUneven" , 8 , 0 ));
472
+ result->push_back (new P10MapperZ ());
473
+ result->push_back (new QiangLiQ8 ());
474
+ result->push_back (new InversedZStripe ());
475
+ result->push_back (new P10Outdoor1R1G1BMultiplexMapper1 ());
476
+ result->push_back (new P10Outdoor1R1G1BMultiplexMapper2 ());
477
+ result->push_back (new P10Outdoor1R1G1BMultiplexMapper3 ());
478
+ result->push_back (new P10CoremanMapper ());
479
+ result->push_back (new P8KryQMapper ());
480
+ return result;
481
+ }
482
+
483
+ const MuxMapperList &GetRegisteredMultiplexMappers ()
484
+ {
485
+ static const MuxMapperList *all_mappers = CreateMultiplexMapperList ();
486
+ return *all_mappers;
487
+ }
488
+ } // namespace internal
489
+ } // namespace rgb_matrix
0 commit comments