]> begriffs open source - cmsis-freertos/blob - Demo/CORTEX_STM32F103_Primer_GCC/ST_Code/pointer.c
Update README.md - branch main is now the base branch
[cmsis-freertos] / Demo / CORTEX_STM32F103_Primer_GCC / ST_Code / pointer.c
1 /********************* (C) COPYRIGHT 2007 RAISONANCE S.A.S. *******************/
2 /**
3 *
4 * @file     pointer.c
5 * @brief    Various utilities for the pointer management for STM32-primer.
6 * @author   FL
7 * @date     07/2007
8 * @version  1.1
9 * @date     10/2007
10 * @version  1.5 various corrections reported by Ron Miller to suppress jittery
11 *
12 *
13 **/
14 /******************************************************************************/
15
16 /* Includes ------------------------------------------------------------------*/
17 #include "circle.h"
18
19 /// @cond Internal
20
21 /* Private define ------------------------------------------------------------*/
22 #define POS_MIN                     0
23 #define POS_MAX                     (SCREEN_WIDTH - POINTER_WIDTH - 1)
24 #define POINTER_DIVIDER             50
25 #define POINTER_DEFAULT_COLOR       RGB_BLUE
26
27 // defines for pointer move
28 #define ANGLEPAUSE                  500 
29 #define DEFAULT_ANGLESTART          25
30 #define MIN_ANGLE_FOR_SHIFT_UP      (ANGLEPAUSE+CurrentAngleStart)
31 #define MIN_ANGLE_FOR_SHIFT_DOWN    (ANGLEPAUSE-CurrentAngleStart)
32 #define MIN_ANGLE_FOR_SHIFT_RIGHT   (signed)(0+CurrentAngleStart)
33 #define MIN_ANGLE_FOR_SHIFT_LEFT    (signed)(0-CurrentAngleStart)
34 #define DEFAULT_SPEED_ON_ANGLE      60
35
36 /* Private variables ---------------------------------------------------------*/
37 static int           divider                          = 0;
38
39 unsigned char        BallPointerBmp[ POINTER_WIDTH ]  = { 0x38, 0x7C, 0xFF, 0xFF, 0xFF, 0x7C, 0x38 } ;
40 unsigned char        locbuf[ POINTER_WIDTH ];
41 unsigned char        DefaultAreaStore[ 2 * POINTER_WIDTH * POINTER_WIDTH ];
42
43 // Variables for pointer.
44 u8*                  CurrentPointerBmp                = 0;
45 u8                   CurrentPointerWidth              = 0;
46 u8                   CurrentPointerHeight             = 0;
47 u16                  CurrentSpeedOnAngle              = DEFAULT_SPEED_ON_ANGLE;
48 u32                  CurrentAngleStart                = DEFAULT_ANGLESTART  ;
49 unsigned char*       ptrAreaStore                     = DefaultAreaStore;
50 u16                  CurrentPointerColor              = POINTER_DEFAULT_COLOR;
51 enum POINTER_mode    Pointer_Mode                     = POINTER_UNDEF;
52 enum POINTER_state   Pointer_State                    = POINTER_S_UNDEF;
53
54 s16                  OUT_X;
55 s16                  OUT_Y;
56
57 // Init pointer Info Structure (structure definition in circle.h)
58 tPointer_Info POINTER_Info = {
59          SCREEN_WIDTH - POINTER_WIDTH / 2,
60          SCREEN_WIDTH - POINTER_WIDTH / 2,
61          0,
62          0} ;
63
64 /* Private function prototypes -----------------------------------------------*/
65 static int   POINTER_Move ( void );
66
67 /* Private functions ---------------------------------------------------------*/
68
69 /*******************************************************************************
70 *
71 *                                Pointer_Move
72 *
73 *******************************************************************************/
74 /**
75 *  Moves LCD pointer according to Mems indications.
76 *
77 *  @retval  0  The pointer resides in the screen
78 *  @retval  -1 The pointer touche the screen edges.
79 *
80 **/
81 /******************************************************************************/
82 static int POINTER_Move( void )
83    {
84    int res                    = 0;
85    s16 oldPointer_xPos        = POINTER_Info.xPos;
86    s16 oldPointer_yPos        = POINTER_Info.yPos;
87    s16 unmodied_shift_PosX;
88    s16 unmodied_shift_PosY;
89    signed outx                = MEMS_Info.OutX_F16 >> 4;
90    signed outy                = MEMS_Info.OutY_F16 >> 4;
91
92    POINTER_Info.shift_PosX  =  POINTER_Info.shift_PosY  = 0;
93
94    // The move depends on the screen orientation
95    switch( LCD_GetScreenOrientation() )
96       {
97       // north
98       case V12 :
99          MEMS_Info.RELATIVE_X = outx;
100          MEMS_Info.RELATIVE_Y = outy;
101
102          if( outx > MIN_ANGLE_FOR_SHIFT_RIGHT )
103             {
104             POINTER_Info.shift_PosX = ( outx - MIN_ANGLE_FOR_SHIFT_RIGHT );
105             }
106          else if( outx < MIN_ANGLE_FOR_SHIFT_LEFT )
107             {
108             POINTER_Info.shift_PosX  = ( outx - MIN_ANGLE_FOR_SHIFT_LEFT );
109             }               
110
111          if( outy < -MIN_ANGLE_FOR_SHIFT_UP )
112             {
113             POINTER_Info.shift_PosY = ( outy + MIN_ANGLE_FOR_SHIFT_UP  );
114             }
115          else if( outy > -MIN_ANGLE_FOR_SHIFT_DOWN )
116             {
117             POINTER_Info.shift_PosY = ( outy + MIN_ANGLE_FOR_SHIFT_DOWN );
118             }
119          break;
120
121       // West
122       case V9 :   
123          MEMS_Info.RELATIVE_X = -( outy );
124          MEMS_Info.RELATIVE_Y = outx;
125
126          if( outy > MIN_ANGLE_FOR_SHIFT_RIGHT )
127             {
128             POINTER_Info.shift_PosX = -( outy - MIN_ANGLE_FOR_SHIFT_RIGHT );
129             }
130          else if( outy < MIN_ANGLE_FOR_SHIFT_LEFT )
131             {
132             POINTER_Info.shift_PosX = -( outy - MIN_ANGLE_FOR_SHIFT_LEFT );
133             }
134
135          if( outx < -MIN_ANGLE_FOR_SHIFT_UP )
136             {
137             POINTER_Info.shift_PosY = ( outx + MIN_ANGLE_FOR_SHIFT_UP );
138             }
139          else if( outx > -MIN_ANGLE_FOR_SHIFT_DOWN )
140             {
141             POINTER_Info.shift_PosY = ( outx + MIN_ANGLE_FOR_SHIFT_DOWN );
142             }
143          break;
144
145       // South
146       case V6 :   
147          MEMS_Info.RELATIVE_X = -( outx );
148          MEMS_Info.RELATIVE_Y = -( outy );
149
150          if( outx > MIN_ANGLE_FOR_SHIFT_RIGHT )
151             {
152             POINTER_Info.shift_PosX = ( MIN_ANGLE_FOR_SHIFT_RIGHT - outx );
153             }
154          else if( outx < MIN_ANGLE_FOR_SHIFT_LEFT )
155             {
156             POINTER_Info.shift_PosX = ( MIN_ANGLE_FOR_SHIFT_LEFT - outx );
157             }
158
159          if( outy > MIN_ANGLE_FOR_SHIFT_UP )
160             {
161             POINTER_Info.shift_PosY = -( outy - MIN_ANGLE_FOR_SHIFT_UP );
162             }
163          else if( outy < MIN_ANGLE_FOR_SHIFT_DOWN )
164             {
165             POINTER_Info.shift_PosY = +( MIN_ANGLE_FOR_SHIFT_DOWN - outy );
166             }
167          break;
168
169       // East
170       case V3 :   
171          MEMS_Info.RELATIVE_X = outy;
172          MEMS_Info.RELATIVE_Y = -( outx );
173
174          if( outy > MIN_ANGLE_FOR_SHIFT_RIGHT )
175             {
176             POINTER_Info.shift_PosX = ( outy - MIN_ANGLE_FOR_SHIFT_RIGHT );
177             }
178          else if( outy < MIN_ANGLE_FOR_SHIFT_LEFT )
179             {
180             POINTER_Info.shift_PosX = ( outy - MIN_ANGLE_FOR_SHIFT_LEFT );
181             }
182
183          if( outx > MIN_ANGLE_FOR_SHIFT_UP )
184             {
185             POINTER_Info.shift_PosY = ( MIN_ANGLE_FOR_SHIFT_UP - outx);
186             }
187          else if( outx < MIN_ANGLE_FOR_SHIFT_DOWN )
188             {
189             POINTER_Info.shift_PosY = ( MIN_ANGLE_FOR_SHIFT_DOWN - outx );
190             }
191
192       default :
193          break;
194       }
195
196    unmodied_shift_PosX = POINTER_Info.shift_PosX;
197    unmodied_shift_PosY = POINTER_Info.shift_PosY;
198
199    POINTER_Info.shift_PosX /= CurrentSpeedOnAngle;
200    POINTER_Info.shift_PosY /= CurrentSpeedOnAngle;
201
202    if( Pointer_Mode == POINTER_APPLICATION )
203       {
204       if ( Application_Pointer_Mgr )
205          {
206          Application_Pointer_Mgr( POINTER_Info.shift_PosX, POINTER_Info.shift_PosY );
207          }
208
209       return 0;
210       }
211
212    POINTER_Info.xPos += POINTER_Info.shift_PosX;
213    POINTER_Info.yPos += POINTER_Info.shift_PosY;
214
215    if( POINTER_Info.xPos < POINTER_Info.X_PosMin )
216       {
217       POINTER_Info.xPos = POINTER_Info.X_PosMin;
218       }
219
220    if( POINTER_Info.xPos > POINTER_Info.X_PosMax )
221       {
222       POINTER_Info.xPos = POINTER_Info.X_PosMax;
223       }
224
225    if( POINTER_Info.yPos < POINTER_Info.Y_PosMin )
226       {
227       POINTER_Info.yPos = POINTER_Info.Y_PosMin;
228       }
229
230    if( POINTER_Info.yPos > POINTER_Info.Y_PosMax )
231       {
232       POINTER_Info.yPos = POINTER_Info.Y_PosMax;
233       }
234
235    if( ( Pointer_Mode != POINTER_MENU ) && ( Pointer_Mode != POINTER_RESTORE_LESS ) &&
236        ( ( oldPointer_xPos != POINTER_Info.xPos ) || ( oldPointer_yPos != POINTER_Info.yPos ) )  )
237       {
238       // Use default area.
239       POINTER_SetCurrentAreaStore( 0 );
240
241       // Restore previously drawn area.
242       POINTER_Restore( oldPointer_xPos, oldPointer_yPos, POINTER_WIDTH, POINTER_WIDTH );
243
244       // Save new area and draw pointer
245       POINTER_Save( POINTER_Info.xPos, POINTER_Info.yPos, POINTER_WIDTH, POINTER_WIDTH );
246       POINTER_Draw( POINTER_Info.xPos, POINTER_Info.yPos, POINTER_WIDTH, POINTER_WIDTH, CurrentPointerBmp );
247       }
248
249    if( ( Pointer_Mode == POINTER_RESTORE_LESS ) &&
250        ( ( oldPointer_xPos != POINTER_Info.xPos ) || ( oldPointer_yPos != POINTER_Info.yPos ) )  )
251       {
252       // Use default area.
253       POINTER_SetCurrentAreaStore( 0 );
254
255       // Restore previously drawn area.
256       POINTER_Restore( oldPointer_xPos, oldPointer_yPos, CurrentPointerWidth, CurrentPointerHeight );
257
258       // Save new area and draw pointer
259       POINTER_Save( POINTER_Info.xPos, POINTER_Info.yPos, CurrentPointerWidth, CurrentPointerHeight );
260       POINTER_Draw( POINTER_Info.xPos, POINTER_Info.yPos, CurrentPointerWidth, CurrentPointerHeight, CurrentPointerBmp );
261       }
262
263    // Is the pointer touching one edge of the screen ?
264    if( ( POINTER_Info.xPos == POS_MIN ) || ( POINTER_Info.yPos == POS_MIN ) ||
265        ( POINTER_Info.xPos == POS_MAX ) || ( POINTER_Info.yPos == POS_MAX ) )
266       {
267       res = -1;
268       }
269
270    return res;
271    }
272
273 /* Public functions for CircleOS ---------------------------------------------*/
274
275 /*******************************************************************************
276 *
277 *                                POINTER_Init
278 *
279 *******************************************************************************/
280 /**
281 *  Initialize pointer. Called at CircleOS startup. Set default pointer at the
282 *  middle of the screen and allows it to move into the whole screen.
283 *
284 *  @attention  This function must <b>NOT</b> be called by the user.
285 *
286 **/
287 /******************************************************************************/
288 void POINTER_Init( void )
289    {
290    // Increase pointer sensibility.
291    POINTER_SetCurrentSpeedOnAngle( DEFAULT_SPEED_ON_ANGLE );
292    POINTER_SetCurrentAngleStart( DEFAULT_ANGLESTART );
293    POINTER_SetCurrentPointer( POINTER_WIDTH, POINTER_WIDTH, BallPointerBmp );
294    POINTER_SetMode( POINTER_ON );
295    POINTER_SetPos( 56, 56 );
296    POINTER_SetRectScreen();
297
298    CurrentPointerColor = POINTER_DEFAULT_COLOR;
299    }
300
301 /*******************************************************************************
302 *
303 *                                POINTER_Handler
304 *
305 *******************************************************************************/
306 /**
307 *
308 *  Called by the CircleOS scheduler to manage the pointer.
309 *
310 *  @attention  This function must <b>NOT</b> be called by the user.
311 *
312 **/
313 /******************************************************************************/
314 void POINTER_Handler( void )
315    {
316    switch( Pointer_Mode )
317       {
318       // Nothing to do!
319       case POINTER_OFF  :
320       case POINTER_UNDEF:
321          return;
322       }
323
324    // Where is the MEMS ?
325    MEMS_GetPosition( &OUT_X, &OUT_Y );
326
327    POINTER_Move();
328    }
329
330 /// @endcond
331
332 /* Public functions ----------------------------------------------------------*/
333
334 /*******************************************************************************
335 *
336 *                                POINTER_SetCurrentPointer
337 *
338 *******************************************************************************/
339 /**
340 *
341 *  Set the dimension and the bitmap of the pointer.
342 *  @note The bitmap is a monochrome one!
343 *
344 *  @param[in]  width    width of the pointer  (u8)
345 *  @param[in]  height   height of the pointer (u8)
346 *  @param[in]  bmp      pointer to an array of width * height bits.
347 *
348 **/
349 /********************************************************************************/
350 void POINTER_SetCurrentPointer( u8 width, u8 height, u8* bmp )
351    {
352    if( !bmp )
353       {
354       bmp = BallPointerBmp;
355       }
356
357    CurrentPointerWidth  = width;
358    CurrentPointerHeight = height;
359    CurrentPointerBmp    = bmp;
360    }
361
362 /*******************************************************************************
363 *
364 *                                POINTER_GetCurrentAngleStart
365 *
366 *******************************************************************************/
367 /**
368 *
369 *  Get the current minimal angle to move pointer
370 *
371 *  @return  current minimal angle.
372 *
373 **/
374 /******************************************************************************/
375 u16 POINTER_GetCurrentAngleStart( void )
376    {
377    return CurrentAngleStart;
378    }
379
380 /*******************************************************************************
381 *
382 *                                POINTER_SetCurrentAngleStart
383 *
384 *******************************************************************************/
385 /**
386 *
387 *  Set the current minimal angle to move pointer
388 *
389 *  @param[in]  newangle The new minimal angle to move pointer.
390 *
391 **/
392 /******************************************************************************/
393 void POINTER_SetCurrentAngleStart( u16 newangle )
394    {
395    CurrentAngleStart = newangle;
396    }
397
398 /*******************************************************************************
399 *
400 *                                POINTER_GetCurrentSpeedOnAngle
401 *
402 *******************************************************************************/
403 /**
404 *
405 *  Return the current speed/angle ratio.
406 *
407 *  @return  current ratio.
408 *
409 **/
410 /******************************************************************************/
411 u16 POINTER_GetCurrentSpeedOnAngle( void )
412    {
413    return CurrentSpeedOnAngle;
414    }
415
416 /*******************************************************************************
417 *
418 *                                POINTER_SetCurrentSpeedOnAngle
419 *
420 *******************************************************************************/
421 /**
422 *
423 *  Set the current speed/angle ratio.
424 *
425 *  @param[in]  newspeed New speed/angle ratio.
426 *
427 **/
428 /******************************************************************************/
429 void POINTER_SetCurrentSpeedOnAngle( u16 newspeed )
430    {
431    CurrentSpeedOnAngle = newspeed;
432    }
433
434 /*******************************************************************************
435 *
436 *                                POINTER_SetCurrentAreaStore
437 *
438 *******************************************************************************/
439 /**
440 *
441 *  Change the current storage area. If the provided value is NULL, the default
442 *  storage area will be used.
443 *
444 *  @param[in]  ptr New storage area (may be null).
445 *
446 *  @warning    Memory space pointed by the provided pointer must be large enough
447 *              to store a color bitmap corresponding to the pointer area.
448 *              In other words, space must be width * height * 2 large.
449 *
450 **/
451 /******************************************************************************/
452 void POINTER_SetCurrentAreaStore( u8* ptr )
453    {
454    ptrAreaStore = ( ptr == 0 ) ? DefaultAreaStore : ptr;
455    }
456
457 /*******************************************************************************
458 *
459 *                                POINTER_SetMode
460 *
461 *******************************************************************************/
462 /**
463 *
464 *  Change the current mode of the pointer management.
465 *
466 *  @note Must be called only ONCE!!
467 *
468 *  @param[in]  mode New pointer management mode.
469 *
470 **/
471 /******************************************************************************/
472 void POINTER_SetMode( enum POINTER_mode mode )
473    {
474    u16*  ptr;
475    u16   i;
476    u16   color;
477
478    switch( mode )
479       {
480       case POINTER_APPLICATION:
481          ptr   = (u16*)DefaultAreaStore;
482          color = DRAW_GetBGndColor();
483
484          for ( i = 0; i < (CurrentPointerWidth*CurrentPointerHeight) ; i++ )
485             {
486             *ptr++ = color;
487             }
488
489          POINTER_Draw( POINTER_Info.xPos, POINTER_Info.yPos, CurrentPointerWidth, CurrentPointerHeight, CurrentPointerBmp );
490          break;
491
492       case POINTER_RESTORE_LESS:
493          POINTER_Draw( POINTER_Info.xPos, POINTER_Info.yPos, CurrentPointerWidth, CurrentPointerHeight, CurrentPointerBmp );
494          break;
495
496       case POINTER_ON:
497          POINTER_SetCurrentAreaStore( 0 );
498          POINTER_Save( POINTER_Info.xPos, POINTER_Info.yPos, POINTER_WIDTH, POINTER_WIDTH );
499          POINTER_Draw( POINTER_Info.xPos, POINTER_Info.yPos, CurrentPointerWidth, CurrentPointerHeight,CurrentPointerBmp );
500          break;
501
502       case POINTER_OFF:
503          POINTER_Info.xPos = ( SCREEN_WIDTH - POINTER_WIDTH ) / 2;
504          POINTER_Info.yPos = ( SCREEN_WIDTH - POINTER_WIDTH ) / 2;
505
506       case POINTER_MENU:
507          if( Pointer_Mode == POINTER_ON )
508             {
509             POINTER_SetCurrentAreaStore( 0 );
510             POINTER_Restore( POINTER_Info.xPos, POINTER_Info.yPos, POINTER_WIDTH, POINTER_WIDTH );
511             }
512          break;
513       }
514
515    Pointer_Mode = mode;
516    }
517
518 /*******************************************************************************
519 *
520 *                                POINTER_GetMode
521 *
522 *******************************************************************************/
523 /**
524 *
525 *  Return the current mode of the pointer management
526 *
527 *  @return  Current pointer management mode.
528 *
529 **/
530 /******************************************************************************/
531 enum POINTER_mode POINTER_GetMode( void )
532    {
533    return Pointer_Mode;
534    }
535
536 /*******************************************************************************
537 *
538 *                                POINTER_GetState
539 *
540 *******************************************************************************/
541 /**
542 *
543 *  Return current pointer state.
544 *
545 *  @return  Current pointer state.
546 *
547 **/
548 /******************************************************************************/
549 enum POINTER_state POINTER_GetState( void )
550    {
551    return Pointer_State;
552    }
553
554 /*******************************************************************************
555 *
556 *                                POINTER_SetRect
557 *
558 *******************************************************************************/
559 /**
560 *
561 *  Set new limits for the move of the pointer
562 *
563 *  @param[in]  x        Horizontal coordinate of the bottom left corner of the new area.
564 *  @param[in]  y        Vertical coordinate of the bottom left corner of the new are.
565 *  @param[in]  width    New area width.
566 *  @param[in]  height   New area height.
567 *
568 *  @warning       The (0x0) point in on the low left corner.
569 *
570 **/
571 /******************************************************************************/
572 void POINTER_SetRect( s16 x, s16 y, s16 width, s16 height )
573    {
574    POINTER_Info.X_PosMin = x;
575
576    if( POINTER_Info.xPos < POINTER_Info.X_PosMin )
577       {
578       POINTER_Info.xPos = POINTER_Info.X_PosMin;
579       }
580
581    POINTER_Info.X_PosMax = x + width - 1;
582
583    if( POINTER_Info.xPos > POINTER_Info.X_PosMax )
584       {
585       POINTER_Info.xPos = POINTER_Info.X_PosMax;
586       }
587
588    POINTER_Info.Y_PosMin = y;
589
590    if( POINTER_Info.yPos < POINTER_Info.Y_PosMin )
591       {
592       POINTER_Info.yPos = POINTER_Info.Y_PosMin;
593       }
594
595    POINTER_Info.Y_PosMax = y + height - 1;
596
597    if( POINTER_Info.yPos > POINTER_Info.Y_PosMax )
598       {
599       POINTER_Info.yPos = POINTER_Info.Y_PosMax;
600       }
601    }
602
603 /*******************************************************************************
604 *
605 *                                POINTER_SetRectScreen
606 *
607 *******************************************************************************/
608 /**
609 *
610 *  Allow the pointer to move on the whole screen.
611 *
612 **/
613 /******************************************************************************/
614 void POINTER_SetRectScreen( void )
615    {
616    POINTER_SetRect( 0, 0, POS_MAX, POS_MAX );
617    }
618
619 /*******************************************************************************
620 *
621 *                                POINTER_GetPos
622 *
623 *******************************************************************************/
624 /**
625 *
626 *  Return the current position of the pointer (on the screen).
627 *
628 *  @return  The current pointer screen position with X in the LSB and Y in the MSB.
629 *
630 *  @warning       The (0x0) point in on the low left corner.
631 **/
632 /******************************************************************************/
633 u16 POINTER_GetPos( void )
634    {
635    return ( POINTER_Info.xPos | ( POINTER_Info.yPos << 8 ) );
636    }
637
638 /*******************************************************************************
639 *
640 *                                POINTER_SetPos
641 *
642 *******************************************************************************/
643 /**
644 *
645 *  Force the screen position of the pointer.
646 *
647 *  @param[in]  x  New horizontal coordinate.
648 *  @param[in]  y  New vertical coordinate.
649 *
650 *  @warning       The (0x0) point in on the low left corner.
651 *
652 **/
653 /******************************************************************************/
654 void POINTER_SetPos( u16 x, u16 y )
655    {
656    POINTER_Info.xPos = x;
657    POINTER_Info.yPos = y;
658    }
659
660 /*******************************************************************************
661 *
662 *                                POINTER_Draw
663 *
664 *******************************************************************************/
665 /**
666 *
667 *  Draw pointer.
668 *
669 *  @param[in]  x        Horizontal coordinate of the bottom left corner of the pointer.
670 *  @param[in]  y        Vertical coordinate of the bottom left corner of the pointer.
671 *  @param[in]  width    Pointer bitmap width.
672 *  @param[in]  height   Pointer bitmap height.
673 *  @param[in]  bmp      Pointer to width * height bit array. If null used default
674 *                       pointer bitmap.
675 *
676 *  @note          The provided bitmap is a monochrome one.
677 *  @warning       The (0x0) point in on the low left corner.
678 *
679 **/
680 /******************************************************************************/
681 void POINTER_Draw( u8 x, u8 y, u8 width, u8 height, u8* bmp )
682    {
683    int   i     = 0;
684    int   l     = 0;
685    int   n     = 0;
686    char* ptr   = ptrAreaStore;
687    char  c;
688    u16   val;
689
690    // No bitmap provided, use the default one!
691    if( bmp == 0 )
692       {
693       bmp = BallPointerBmp;
694       }
695
696    // Select the screen area were going to take care about!
697    LCD_SetRect_For_Cmd( x, y, width, height );
698
699    // Let draw to the LCD screen.
700    LCD_SendLCDCmd( ST7637_RAMWR );
701
702    while( n < ( width * height ) )
703       {
704       if( Pointer_Mode != POINTER_RESTORE_LESS )
705          {
706          // Draw pixel using current storage area data for background pixels.
707          c = *ptr++;
708          LCD_SendLCDData( ( bmp[ l + ( i / 8 ) ] & ( 1 << ( 7 - ( i % 8 ) ) ) ) ? ( POINTER_GetColor() & 255 ) : c );
709
710          c = *ptr++;
711          LCD_SendLCDData( ( bmp[ l + ( i / 8 ) ] & ( 1 << ( 7 - ( i % 8 ) ) ) ) ? ( POINTER_GetColor() >> 8 )  : c );
712          }
713       else
714          {
715          // POINTER_RESTORE_LESS: use current background color for background color.
716          c = DRAW_GetBGndColor();
717          val = ( bmp[ l + ( i / 8 ) ] & ( 1 << ( 7 - ( i % 8 ) ) ) ) ? POINTER_GetColor() : c;
718
719          LCD_SendLCDData( val & 255 );
720          LCD_SendLCDData( val >> 8 );
721          }
722
723       n++;
724
725       i++;
726
727       // End of line ?
728       if( i == width )
729          {
730          // Next line!
731          l++;
732          i=0;
733          }
734       }
735    }
736
737 /*******************************************************************************
738 *
739 *                                POINTER_Save
740 *
741 *******************************************************************************/
742 /**
743 *
744 *  Save the background of the pointer.
745 *
746 *  @param[in]  x        Horizontal coordinate of the bottom left corner of the area to save.
747 *  @param[in]  y        Vertical coordinate of the bottom left corner of the area to save.
748 *  @param[in]  width    Width of the area to save.
749 *  @param[in]  height   Height of the area to save.
750 *
751 *  @note          The store area must be large enough to store all the pixels (16 bits).
752 *  @warning       The (0x0) point in on the low left corner.
753 *  @see  POINTER_Restore
754 *  @see  POINTER_SetCurrentAreaStore
755 *
756 **/
757 /******************************************************************************/
758 void POINTER_Save( u8 x, u8 y, u8 width, u8 height )
759    {
760    int   i;
761    char* ptr      = ptrAreaStore;
762    int   bytesize = ( width * height ) * 2;                // 2 bytes per pixel.
763
764    // Is this pointer management mode, don't save pointer background!
765    if( Pointer_Mode == POINTER_RESTORE_LESS )
766       {
767       return;
768       }
769
770    // Select the LCD screen area to read.
771    LCD_SetRect_For_Cmd ( x, y, width, height );
772
773    // Send the memory read command to the LCD controller.
774    LCD_SendLCDCmd( ST7637_RAMRD );
775
776    // First returned byte is a dummy!
777    LCD_ReadLCDData();
778
779    for( i = 0; i < bytesize; i++ )
780       {
781       *ptr++ = LCD_ReadLCDData();
782       }
783    }
784
785 /*******************************************************************************
786 *
787 *                                POINTER_Restore
788 *
789 *******************************************************************************/
790 /**
791 *
792 *  Restore the background of the pointer with data saved in the current store area.
793 *
794 *  @param[in]  x        Horizontal coordinate of the bottom left corner of the area to restore.
795 *  @param[in]  y        Vertical coordinate of the bottom left corner of the area to restore.
796 *  @param[in]  width    Width of the area to restore.
797 *  @param[in]  height   Height of the area to restore.
798 *
799 *  @warning       The (0x0) point in on the low left corner.
800 *  @see  POINTER_Save
801 *  @see  POINTER_SetCurrentAreaStore
802 *
803 **/
804 /******************************************************************************/
805 void POINTER_Restore( u8 x, u8 y, u8 width, u8 height )
806    {
807    int   i;
808    char* ptr      = ptrAreaStore;
809    int   bytesize = ( width * height ) * 2;                // 2 bytes per pixel.
810
811    // Select the screen area to write.
812    LCD_SetRect_For_Cmd( x, y, width, height );
813
814    // Send the memory write command to the LCD controller.
815    LCD_SendLCDCmd( ST7637_RAMWR );
816
817    for( i = 0; i < bytesize; i++ )
818       {
819       // In this mode, use background color (no data was previously saved).
820       if ( Pointer_Mode == POINTER_RESTORE_LESS )
821          {
822          LCD_SendLCDData( DRAW_GetBGndColor() );
823          }
824       else
825          {
826          LCD_SendLCDData( *ptr++ );
827          }
828       }
829    }
830
831 /*******************************************************************************
832 *
833 *                                POINTER_SetApplication_Pointer_Mgr
834 *
835 *******************************************************************************/
836 /**
837 *
838 *  Provides an user defined pointer manager.
839 *
840 *  @param[in]  mgr Pointer to the user defined pointer manager.
841 *
842 **/
843 /******************************************************************************/
844 void POINTER_SetApplication_Pointer_Mgr( tAppPtrMgr mgr )
845    {
846    Application_Pointer_Mgr = mgr;
847    }
848
849 /*******************************************************************************
850 *
851 *                                POINTER_SetColor
852 *
853 *******************************************************************************/
854 /**
855 *
856 *  Set the pointer color.
857 *
858 *  @param[in]  color The new pointer color.
859 *
860 **/
861 /******************************************************************************/
862 void POINTER_SetColor( u16 color )
863    {
864    CurrentPointerColor = color;
865    }
866
867 /*******************************************************************************
868 *
869 *                                POINTER_GetColor
870 *
871 *******************************************************************************/
872 /**
873 *
874 *  Return the current pointer color.
875 *
876 *  @return  Current pointer color.
877 *
878 **/
879 /******************************************************************************/
880 u16 POINTER_GetColor( void )
881    {
882    return CurrentPointerColor;
883    }
884
885 /*******************************************************************************
886 *
887 *                                POINTER_GetInfo
888 *
889 *******************************************************************************/
890 /**
891 *
892 *  Get pointer informations.
893 *
894 *  @return  A pointer to a pointer information structure.
895 *
896 **/
897 /******************************************************************************/
898 tPointer_Info* POINTER_GetInfo( void )
899    {
900    return &POINTER_Info;
901    }