@@ -14,16 +14,29 @@ pub enum Action {
14
14
DrawCircleHollow ,
15
15
DrawTriangleNormal ,
16
16
DrawTriangleHollow ,
17
+ DrawHexagonNormal ,
18
+ DrawHexagonHollow ,
17
19
}
18
20
19
21
const RESOLUTION : usize = RESOLUTION_WIDTH * RESOLUTION_HEIGHT ;
20
22
const RESOLUTION_HEIGHT : usize = 1000 ;
21
23
const RESOLUTION_WIDTH : usize = 1920 ;
22
24
23
25
// binary format:
24
- // 0-0: action (3b) + height (5b)
25
- // 1-3: x (12b) + y (12b)
26
- // 4-6: color
26
+ // (4b) action | byte 1
27
+ // (4b) height | byte 1
28
+ //
29
+ // (3b) height | byte 2
30
+ // (5b) x | byte 2
31
+ //
32
+ // (6b) x | byte 3
33
+ // (2b) y | byte 3
34
+ //
35
+ // (8b) y | byte 4
36
+ //
37
+ // (8b) color[0]| byte 5
38
+ // (8b) color[1]| byte 6
39
+ // (8b) color[2]| byte 7
27
40
28
41
#[ derive( Debug ) ]
29
42
pub struct ClientMessage {
@@ -37,61 +50,32 @@ pub struct ClientMessage {
37
50
}
38
51
39
52
impl ClientMessage {
40
- fn decode_u12 ( data : & [ u8 ] ) -> [ u16 ; 2 ] {
41
- let mut buf: [ u16 ; 2 ] = [ 0 ; 2 ] ;
42
-
43
- buf[ 0 ] = ( data[ 0 ] as u16 ) | ( ( data[ 1 ] as u16 & 0xf ) << 8 ) ;
44
- buf[ 1 ] = ( ( data[ 1 ] as u16 ) >> 4 ) | ( ( data[ 2 ] as u16 ) << 4 ) ;
45
-
46
- buf
47
- }
48
-
49
- fn encode_u12 ( data : [ u16 ; 2 ] ) -> [ u8 ; 3 ] {
50
- let mut buf = [ 0 ; 3 ] ;
51
-
52
- buf[ 0 ] = ( data[ 0 ] & 0xff ) as u8 ;
53
- buf[ 1 ] = ( ( data[ 0 ] >> 8 ) | ( data[ 1 ] << 4 ) ) as u8 ;
54
- buf[ 2 ] = ( data[ 1 ] >> 4 ) as u8 ;
55
-
56
- buf
57
- }
58
-
59
- fn decode_u3 ( data : u8 ) -> u8 {
60
- data & 0b111
61
- }
62
-
63
- fn encode_u3 ( data : u8 ) -> u8 {
64
- data & 0b111
65
- }
66
-
67
- fn decode_u5 ( data : u8 ) -> u8 {
68
- data >> 3
69
- }
70
-
71
- fn encode_u5 ( data : u8 ) -> u8 {
72
- data << 3
73
- }
74
-
75
53
pub fn decode ( data : & [ u8 ] ) -> Option < Self > {
76
54
if data. len ( ) != 7 {
77
55
return None ;
78
56
}
79
57
80
- let action_height = data[ 0 ] ;
81
- let action = match Self :: decode_u3 ( action_height) {
58
+ let action = match ( data[ 0 ] >> 4 ) & 0xF {
82
59
0 => Action :: Erase ,
83
60
1 => Action :: DrawCubeNormal ,
84
61
2 => Action :: DrawCubeHollow ,
85
62
3 => Action :: DrawCircleNormal ,
86
63
4 => Action :: DrawCircleHollow ,
87
64
5 => Action :: DrawTriangleNormal ,
88
65
6 => Action :: DrawTriangleHollow ,
66
+ 7 => Action :: DrawHexagonNormal ,
67
+ 8 => Action :: DrawHexagonHollow ,
89
68
_ => return None ,
90
69
} ;
91
70
92
- let height = Self :: decode_u5 ( action_height) ;
93
-
94
- let [ x, y] = Self :: decode_u12 ( & data[ 1 ..4 ] ) ;
71
+ let height_high = data[ 0 ] & 0xF ;
72
+ let height_low = ( data[ 1 ] >> 5 ) & 0x7 ;
73
+ let height = ( height_high << 3 ) | height_low;
74
+ let x_high = data[ 1 ] & 0x1F ;
75
+ let x_low = ( data[ 2 ] >> 2 ) & 0x3F ;
76
+ let x = ( ( x_high as u16 ) << 6 ) | ( x_low as u16 ) ;
77
+ let y_high = data[ 2 ] & 0x3 ;
78
+ let y = ( ( y_high as u16 ) << 8 ) | ( data[ 3 ] as u16 ) ;
95
79
let color = [ data[ 4 ] , data[ 5 ] , data[ 6 ] ] ;
96
80
97
81
if height == 0 || x >= RESOLUTION_WIDTH as u16 || y >= RESOLUTION_HEIGHT as u16 {
@@ -110,17 +94,23 @@ impl ClientMessage {
110
94
pub fn encode ( & self ) -> [ u8 ; 7 ] {
111
95
let mut buf = [ 0 ; 7 ] ;
112
96
113
- buf [ 0 ] = Self :: encode_u3 ( match self . action {
97
+ let action_value = match self . action {
114
98
Action :: Erase => 0 ,
115
99
Action :: DrawCubeNormal => 1 ,
116
100
Action :: DrawCubeHollow => 2 ,
117
101
Action :: DrawCircleNormal => 3 ,
118
102
Action :: DrawCircleHollow => 4 ,
119
103
Action :: DrawTriangleNormal => 5 ,
120
104
Action :: DrawTriangleHollow => 6 ,
121
- } ) | Self :: encode_u5 ( self . height ) ;
122
- buf[ 1 ..4 ] . copy_from_slice ( & Self :: encode_u12 ( [ self . x , self . y ] ) ) ;
123
- buf[ 4 ..7 ] . copy_from_slice ( & self . color ) ;
105
+ Action :: DrawHexagonNormal => 7 ,
106
+ Action :: DrawHexagonHollow => 8 ,
107
+ } ;
108
+
109
+ buf[ 0 ] = ( action_value << 4 ) | ( ( self . height >> 3 ) & 0xF ) ;
110
+ buf[ 1 ] = ( ( self . height & 0x7 ) << 5 ) | ( ( self . x >> 6 ) as u8 & 0x1F ) ;
111
+ buf[ 2 ] = ( ( ( self . x & 0x3F ) << 2 ) | ( ( self . y >> 8 ) & 0x3 ) ) as u8 ;
112
+ buf[ 3 ] = self . y as u8 ;
113
+ buf[ 4 ..] . copy_from_slice ( & self . color ) ;
124
114
125
115
if std:: env:: var ( "DEBUG" ) . is_ok ( ) {
126
116
println ! ( "encoded: {:?}" , & self ) ;
@@ -206,7 +196,7 @@ impl Data {
206
196
for message in data {
207
197
match message. action {
208
198
Action :: Erase => {
209
- let height = ( message. height as f64 ) * 1.5 * 4.0 ;
199
+ let height = ( message. height as f64 ) * 1.5 ;
210
200
211
201
let start_x = message. x . saturating_sub ( height as u16 ) as usize ;
212
202
let end_x =
@@ -226,7 +216,7 @@ impl Data {
226
216
}
227
217
}
228
218
Action :: DrawCubeNormal => {
229
- let height = message. height as usize * 4 ;
219
+ let height = message. height as usize ;
230
220
231
221
let start_x = message. x as usize ;
232
222
let end_x =
@@ -244,7 +234,7 @@ impl Data {
244
234
}
245
235
}
246
236
Action :: DrawCubeHollow => {
247
- let height = message. height as usize * 4 ;
237
+ let height = message. height as usize ;
248
238
249
239
let start_x = message. x as usize ;
250
240
let end_x =
@@ -285,7 +275,7 @@ impl Data {
285
275
}
286
276
}
287
277
Action :: DrawCircleNormal | Action :: DrawCircleHollow => {
288
- let radius = message. height as usize * 4 ;
278
+ let radius = message. height as usize ;
289
279
let is_hollow = matches ! ( message. action, Action :: DrawCircleHollow ) ;
290
280
291
281
let start_x = message. x . saturating_sub ( radius as u16 ) as usize ;
@@ -337,7 +327,7 @@ impl Data {
337
327
}
338
328
}
339
329
Action :: DrawTriangleNormal | Action :: DrawTriangleHollow => {
340
- let height = message. height as usize * 4 ;
330
+ let height = message. height as usize ;
341
331
let is_hollow = matches ! ( message. action, Action :: DrawTriangleHollow ) ;
342
332
343
333
let x1 = message. x as i32 ;
@@ -370,6 +360,78 @@ impl Data {
370
360
}
371
361
}
372
362
}
363
+ Action :: DrawHexagonNormal | Action :: DrawHexagonHollow => {
364
+ let is_hollow = matches ! ( message. action, Action :: DrawHexagonHollow ) ;
365
+ let size = message. height as f32 ;
366
+ let center_x = message. x as f32 ;
367
+ let center_y = message. y as f32 ;
368
+
369
+ let points: [ ( f32 , f32 ) ; 6 ] = ( 0 ..6 )
370
+ . map ( |i| {
371
+ let angle = ( i as f32 ) * std:: f32:: consts:: PI / 3.0 ;
372
+ let x = center_x + size * angle. cos ( ) ;
373
+ let y = center_y + size * angle. sin ( ) ;
374
+ ( x, y)
375
+ } )
376
+ . collect :: < Vec < _ > > ( )
377
+ . try_into ( )
378
+ . unwrap ( ) ;
379
+
380
+ if is_hollow {
381
+ for i in 0 ..6 {
382
+ let start = points[ i] ;
383
+ let end = points[ ( i + 1 ) % 6 ] ;
384
+ draw_line_fast (
385
+ & mut self_data,
386
+ start. 0 as i32 ,
387
+ start. 1 as i32 ,
388
+ end. 0 as i32 ,
389
+ end. 1 as i32 ,
390
+ & message. color ,
391
+ ) ;
392
+ }
393
+ } else {
394
+ let min_y = points. iter ( ) . map ( |( _, y) | * y as i32 ) . min ( ) . unwrap ( ) ;
395
+ let max_y = points. iter ( ) . map ( |( _, y) | * y as i32 ) . max ( ) . unwrap ( ) ;
396
+
397
+ for y in min_y..=max_y {
398
+ let mut intersections = Vec :: new ( ) ;
399
+
400
+ for i in 0 ..6 {
401
+ let start = points[ i] ;
402
+ let end = points[ ( i + 1 ) % 6 ] ;
403
+
404
+ if ( start. 1 <= y as f32 && end. 1 > y as f32 )
405
+ || ( end. 1 <= y as f32 && start. 1 > y as f32 )
406
+ {
407
+ let x = if start. 1 == end. 1 {
408
+ start. 0
409
+ } else {
410
+ start. 0
411
+ + ( y as f32 - start. 1 ) * ( end. 0 - start. 0 )
412
+ / ( end. 1 - start. 1 )
413
+ } ;
414
+ intersections. push ( x as i32 ) ;
415
+ }
416
+ }
417
+
418
+ intersections. sort_unstable ( ) ;
419
+
420
+ for chunk in intersections. chunks ( 2 ) {
421
+ if chunk. len ( ) == 2 {
422
+ let start_x = chunk[ 0 ] . max ( 0 ) . min ( RESOLUTION_WIDTH as i32 - 1 ) ;
423
+ let end_x = chunk[ 1 ] . max ( 0 ) . min ( RESOLUTION_WIDTH as i32 - 1 ) ;
424
+
425
+ for x in start_x..=end_x {
426
+ let index =
427
+ ( y as usize * RESOLUTION_WIDTH + x as usize ) * 3 ;
428
+ self_data[ index..index + 3 ] . copy_from_slice ( & message. color ) ;
429
+ }
430
+ }
431
+ }
432
+ }
433
+ }
434
+ }
373
435
}
374
436
}
375
437
0 commit comments