CircleOS  1
pointer.c
Go to the documentation of this file.
1 /****************** COPYRIGHT (C) 2007-2013 KEOLABS S.A.S. ********************/
18 /******************************************************************************/
19 
20 /* Includes ------------------------------------------------------------------*/
21 #include "circle.h"
22 
24 
25 /* Private define ------------------------------------------------------------*/
26 #define POS_MIN 0
27 #define POS_MAX (Screen_Width - POINTER_WIDTH - 1)
28 //~ #define POINTER_DIVIDER 50
29 #define POINTER_DEFAULT_COLOR RGB_BLUE
30 
31 // defines for pointer move
32 #define ANGLEPAUSE 500
33 #define DEFAULT_ANGLESTART 25
34 #define MIN_ANGLE_FOR_SHIFT_UP (ANGLEPAUSE+CurrentAngleStart)
35 #define MIN_ANGLE_FOR_SHIFT_DOWN (ANGLEPAUSE-CurrentAngleStart)
36 #define MIN_ANGLE_FOR_SHIFT_RIGHT (signed)(0+CurrentAngleStart)
37 #define MIN_ANGLE_FOR_SHIFT_LEFT (signed)(0-CurrentAngleStart)
38 #define DEFAULT_SPEED_ON_ANGLE 60
39 
40 // define for joystick management
41 #define JOY_MAXBTIME 20
42 #define JOY_HIGH_SPEED 5
43 #define JOY_LOW_SPEED 1
44 
45 /* Private variables ---------------------------------------------------------*/
46 CONST_DATA u8 BallPointerBmp[POINTER_WIDTH] = { 0x38, 0x7C, 0xFF, 0xFF, 0xFF, 0x7C, 0x38 } ;
47 
48 tAppPtrMgr Application_Pointer_Mgr = 0;
49 
50 u8 DefaultAreaStore[2 * POINTER_WIDTH* POINTER_WIDTH];
51 
52 // Variables for pointer.
53 const u8* CurrentPointerBmp = 0;
54 coord_t CurrentPointerWidth = 0;
55 coord_t CurrentPointerHeight = 3;
56 s16 CurrentSpeedOnAngle = DEFAULT_SPEED_ON_ANGLE;
57 s32 CurrentAngleStart = DEFAULT_ANGLESTART;
58 u8* ptrAreaStore = DefaultAreaStore;
59 color_t CurrentPointerColor = POINTER_DEFAULT_COLOR;
60 enum POINTER_mode Pointer_Mode = POINTER_UNDEF;
61 enum POINTER_state Pointer_State = POINTER_S_UNDEF;
62 
63 coord_t OUT_X;
64 coord_t OUT_Y;
65 
66 // Variables for joystick
67 enum JOYSTICK_state JoyPos;
68 u16 JoyDelay = 0;
69 u16 JoyInc = 1;
70 
71 // Init pointer Info Structure (structure definition in circle.h)
72 tPointer_Info POINTER_Info;
73 
74 /* Private function prototypes -----------------------------------------------*/
75 
76 /* Private functions ---------------------------------------------------------*/
77 
78 /*******************************************************************************
79 *
80 * POINTER_JoyTch
81 *
82 *******************************************************************************/
90 /******************************************************************************/
91 NODEBUG2 s32 POINTER_JoyTch( void )
92 {
93 #if JOYSTICK_AVAIL
94  //-- Option management of the pointer by the joystick
95  if ( JoystickAsInput )
96  {
97  JoyPos = JOYSTICK_GetState();
98  switch ( JoyPos )
99  {
100  case JOYSTICK_DOWN:
101  POINTER_Info.shift_PosX = 0;
102  POINTER_Info.shift_PosY = -JoyInc ;
103  break;
104  case JOYSTICK_UP:
105  POINTER_Info.shift_PosX = 0;
106  POINTER_Info.shift_PosY = JoyInc;
107  break;
108  case JOYSTICK_LEFT:
109  POINTER_Info.shift_PosX = -JoyInc;
110  POINTER_Info.shift_PosY = 0;
111  break;
112  case JOYSTICK_RIGHT_UP:
113  POINTER_Info.shift_PosX = JoyInc;
114  POINTER_Info.shift_PosY = JoyInc;
115  break;
116  case JOYSTICK_RIGHT:
117  POINTER_Info.shift_PosX = JoyInc;
118  POINTER_Info.shift_PosY = 0;
119  break;
120  case JOYSTICK_RIGHT_DOWN:
121  POINTER_Info.shift_PosX = JoyInc;
122  POINTER_Info.shift_PosY = -JoyInc;
123  break;
124  case JOYSTICK_LEFT_UP:
125  POINTER_Info.shift_PosX = -JoyInc;
126  POINTER_Info.shift_PosY = JoyInc;
127  break;
128  case JOYSTICK_LEFT_DOWN:
129  POINTER_Info.shift_PosX = -JoyInc;
130  POINTER_Info.shift_PosY = -JoyInc;
131  break;
132  default:
133  break;
134  }
135 
136  if ( JoyPos != JOYSTICK_RELEASED )
137  JoyDelay++;
138  else
139  JoyDelay = 0;
140 
141  if ( JoyDelay >= WEIGHTED_TIME( JOY_MAXBTIME ) )
142  JoyInc = JOY_HIGH_SPEED;
143  else
144  JoyInc = JOY_LOW_SPEED;
145  }
146 #endif //JOYSTICK_AVAIL
147 
148 #if TOUCHSCREEN_AVAIL
149 
150  //-- Option management of the pointer by the Touchscreen
151  if ( TchscrAsInput )
152  {
153  if ( ( TOUCHSCR_Info.xPos > 2 ) || ( TOUCHSCR_Info.yPos > 2 ) )
154  {
155  switch ( LCD_GetScreenOrientation() )
156  {
157  case V3 :
158  if ( TOUCHSCR_Info.xPos < PHYS_SCREEN_WIDTH + CurrentPointerWidth )
159  {
160  TOUCHSCR_SetMode( TS_POINTER );
161  POINTER_Info.xPos = TOUCHSCR_Info.xPos - 2 * POINTER_WIDTH / 3 ; // To have the bottom left hand corner point of the pointer
162  POINTER_Info.yPos = TOUCHSCR_Info.yPos - 2 * POINTER_WIDTH / 3 ; // To have the bottom left hand corner point of the pointer
163  }
164  break;
165  case V6 :
166  if ( TOUCHSCR_Info.yPos > 0 )
167  {
168  TOUCHSCR_SetMode( TS_POINTER );
169  POINTER_Info.xPos = TOUCHSCR_Info.xPos - 2 * POINTER_WIDTH / 3 ; // To have the bottom left hand corner point of the pointer
170  POINTER_Info.yPos = TOUCHSCR_Info.yPos - 2 * POINTER_WIDTH / 3 ; // To have the bottom left hand corner point of the pointer
171  }
172  break;
173  case V9 :
174  if ( TOUCHSCR_Info.xPos > 0 )
175  {
176  TOUCHSCR_SetMode( TS_POINTER );
177  POINTER_Info.xPos = TOUCHSCR_Info.xPos - 2 * POINTER_WIDTH / 3 ; // To have the bottom left hand corner point of the pointer
178  POINTER_Info.yPos = TOUCHSCR_Info.yPos - 2 * POINTER_WIDTH / 3 ; // To have the bottom left hand corner point of the pointer
179  }
180  break;
181 
182  case V12 :
183  if ( TOUCHSCR_Info.yPos < PHYS_SCREEN_HEIGHT + CurrentPointerHeight )
184  {
185  TOUCHSCR_SetMode( TS_POINTER );
186  POINTER_Info.xPos = TOUCHSCR_Info.xPos - 2 * POINTER_WIDTH / 3 ; // To have the bottom left hand corner point of the pointer
187  POINTER_Info.yPos = TOUCHSCR_Info.yPos - 2 * POINTER_WIDTH / 3 ; // To have the bottom left hand corner point of the pointer
188  }
189  break;
190 
191  default:
192  break;
193  }
194  }
195  }
196 
197 #endif //TOUCHSCREEN_AVAIL
198 
199  //-- Option management of the pointer also by the mems
200  if ( ( ( MEMSASINPUT && ( JoyPos == JOYSTICK_RELEASED ) ) || !JoystickAsInput ) && !( TchscrAsInput ) )
201  {
202  return TRUE;
203  }
204 
205 #if JOYSTICK_AVAIL
206  return FALSE;
207 #else
208  return TRUE;
209 #endif
210 }
211 
212 
213 /*******************************************************************************
214 *
215 * Pointer_Move
216 *
217 *******************************************************************************/
225 /******************************************************************************/
226 static bool POINTER_Move( void )
227 {
228  s16 oldPointer_xPos = POINTER_Info.xPos;
229  s16 oldPointer_yPos = POINTER_Info.yPos;
230  signed outx = MEMS_Info.OutX;
231  signed outy = MEMS_Info.OutY;
232 
233  POINTER_Info.shift_PosX = POINTER_Info.shift_PosY = 0;
234 
235  if ( POINTER_JoyTch() != 0 ) // If Joystick used as input
236  {
237  // The move depends on the screen orientation
238  switch ( LCD_GetScreenOrientation() )
239  {
240  // north
241  case V12 :
242  MEMS_Info.RELATIVE_X = outx;
243  MEMS_Info.RELATIVE_Y = outy;
244 
245  if ( outx > MIN_ANGLE_FOR_SHIFT_RIGHT )
246  {
247  POINTER_Info.shift_PosX = ( outx - MIN_ANGLE_FOR_SHIFT_RIGHT );
248  }
249  else if ( outx < MIN_ANGLE_FOR_SHIFT_LEFT )
250  {
251  POINTER_Info.shift_PosX = ( outx - MIN_ANGLE_FOR_SHIFT_LEFT );
252  }
253 
254  if ( outy < -MIN_ANGLE_FOR_SHIFT_UP )
255  {
256  POINTER_Info.shift_PosY = ( outy + MIN_ANGLE_FOR_SHIFT_UP );
257  }
258  else if ( outy > -MIN_ANGLE_FOR_SHIFT_DOWN )
259  {
260  POINTER_Info.shift_PosY = ( outy + MIN_ANGLE_FOR_SHIFT_DOWN );
261  }
262  break;
263 
264  // West
265  case V9 :
266  MEMS_Info.RELATIVE_X = -( outy );
267  MEMS_Info.RELATIVE_Y = outx;
268 
269  if ( outy > MIN_ANGLE_FOR_SHIFT_RIGHT )
270  {
271  POINTER_Info.shift_PosX = -( outy - MIN_ANGLE_FOR_SHIFT_RIGHT );
272  }
273  else if ( outy < MIN_ANGLE_FOR_SHIFT_LEFT )
274  {
275  POINTER_Info.shift_PosX = -( outy - MIN_ANGLE_FOR_SHIFT_LEFT );
276  }
277 
278  if ( outx < -MIN_ANGLE_FOR_SHIFT_UP )
279  {
280  POINTER_Info.shift_PosY = ( outx + MIN_ANGLE_FOR_SHIFT_UP );
281  }
282  else if ( outx > -MIN_ANGLE_FOR_SHIFT_DOWN )
283  {
284  POINTER_Info.shift_PosY = ( outx + MIN_ANGLE_FOR_SHIFT_DOWN );
285  }
286  break;
287 
288  // South
289  case V6 :
290  MEMS_Info.RELATIVE_X = -( outx );
291  MEMS_Info.RELATIVE_Y = -( outy );
292 
293  if ( outx > MIN_ANGLE_FOR_SHIFT_RIGHT )
294  {
295  POINTER_Info.shift_PosX = ( MIN_ANGLE_FOR_SHIFT_RIGHT - outx );
296  }
297  else if ( outx < MIN_ANGLE_FOR_SHIFT_LEFT )
298  {
299  POINTER_Info.shift_PosX = ( MIN_ANGLE_FOR_SHIFT_LEFT - outx );
300  }
301 
302  if ( outy > MIN_ANGLE_FOR_SHIFT_UP )
303  {
304  POINTER_Info.shift_PosY = -( outy - MIN_ANGLE_FOR_SHIFT_UP );
305  }
306  else if ( outy < MIN_ANGLE_FOR_SHIFT_DOWN )
307  {
308  POINTER_Info.shift_PosY = +( MIN_ANGLE_FOR_SHIFT_DOWN - outy );
309  }
310  break;
311 
312  // East
313  case V3 :
314  MEMS_Info.RELATIVE_X = outy;
315  MEMS_Info.RELATIVE_Y = -( outx );
316 
317  if ( outy > MIN_ANGLE_FOR_SHIFT_RIGHT )
318  {
319  POINTER_Info.shift_PosX = ( outy - MIN_ANGLE_FOR_SHIFT_RIGHT );
320  }
321  else if ( outy < MIN_ANGLE_FOR_SHIFT_LEFT )
322  {
323  POINTER_Info.shift_PosX = ( outy - MIN_ANGLE_FOR_SHIFT_LEFT );
324  }
325 
326  if ( outx > MIN_ANGLE_FOR_SHIFT_UP )
327  {
328  POINTER_Info.shift_PosY = ( MIN_ANGLE_FOR_SHIFT_UP - outx );
329  }
330  else if ( outx < MIN_ANGLE_FOR_SHIFT_DOWN )
331  {
332  POINTER_Info.shift_PosY = ( MIN_ANGLE_FOR_SHIFT_DOWN - outx );
333  }
334 
335  default :
336  break;
337  }
338 
339  POINTER_Info.shift_PosX /= CurrentSpeedOnAngle;
340  POINTER_Info.shift_PosY /= CurrentSpeedOnAngle;
341  }
342 
343  if ( Pointer_Mode == POINTER_APPLICATION )
344  {
345  if ( Application_Pointer_Mgr )
346  {
347  Application_Pointer_Mgr( POINTER_Info.shift_PosX, POINTER_Info.shift_PosY );
348  }
349 
350  return 0;
351  }
352 
353  POINTER_Info.xPos += POINTER_Info.shift_PosX;
354  POINTER_Info.yPos += POINTER_Info.shift_PosY;
355 
356  if ( POINTER_Info.xPos < POINTER_Info.X_PosMin )
357  {
358  POINTER_Info.xPos = POINTER_Info.X_PosMin;
359  }
360 
361  if ( POINTER_Info.xPos > POINTER_Info.X_PosMax )
362  {
363  POINTER_Info.xPos = POINTER_Info.X_PosMax;
364  }
365 
366  if ( POINTER_Info.yPos < POINTER_Info.Y_PosMin )
367  {
368  POINTER_Info.yPos = POINTER_Info.Y_PosMin;
369  }
370 
371  if ( POINTER_Info.yPos > POINTER_Info.Y_PosMax )
372  {
373  POINTER_Info.yPos = POINTER_Info.Y_PosMax;
374  }
375 
376  if ( ( Pointer_Mode != POINTER_MENU ) && ( Pointer_Mode != POINTER_RESTORE_LESS ) &&
377  ( ( oldPointer_xPos != POINTER_Info.xPos ) || ( oldPointer_yPos != POINTER_Info.yPos ) ) )
378  {
379  // Use default area.
381 
382  // Restore previously drawn area.
383  POINTER_Restore( oldPointer_xPos, oldPointer_yPos, POINTER_WIDTH, POINTER_WIDTH );
384 
385  // Save new area and draw pointer
386  POINTER_Save( POINTER_Info.xPos, POINTER_Info.yPos, POINTER_WIDTH, POINTER_WIDTH );
387  POINTER_Draw( POINTER_Info.xPos, POINTER_Info.yPos, POINTER_WIDTH, POINTER_WIDTH, CurrentPointerBmp );
388  }
389 
390  if ( ( Pointer_Mode == POINTER_RESTORE_LESS ) &&
391  ( ( oldPointer_xPos != POINTER_Info.xPos ) || ( oldPointer_yPos != POINTER_Info.yPos ) ) )
392  {
393  // Use default area.
395 
396  // Restore previously drawn area.
397  POINTER_Restore( oldPointer_xPos, oldPointer_yPos, CurrentPointerWidth, CurrentPointerHeight );
398 
399  // Save new area and draw pointer
400  POINTER_Save( POINTER_Info.xPos, POINTER_Info.yPos, CurrentPointerWidth, CurrentPointerHeight );
401  POINTER_Draw( POINTER_Info.xPos, POINTER_Info.yPos, CurrentPointerWidth, CurrentPointerHeight, CurrentPointerBmp );
402  }
403 
404  // Is the pointer touching one edge of the screen ?
405  if ( ( POINTER_Info.xPos == POS_MIN ) || ( POINTER_Info.yPos == POS_MIN ) ||
406  ( POINTER_Info.xPos == POS_MAX ) || ( POINTER_Info.yPos == POS_MAX ) )
407  {
408  return -1;
409  }
410 
411  return 0;
412 }
413 
414 /* Public functions for CircleOS ---------------------------------------------*/
415 
416 /*******************************************************************************
417 *
418 * POINTER_Init
419 *
420 *******************************************************************************/
428 /******************************************************************************/
429 NODEBUG void POINTER_Init( void )
430 {
431  POINTER_Info.xPos = ( Screen_Width / 2 ) - ( POINTER_WIDTH / 2 ) - 1;
432  POINTER_Info.yPos = ( Screen_Width / 2 ) - ( POINTER_WIDTH / 2 ) - 1;
433  POINTER_Info.shift_PosX = 0;
434  POINTER_Info.shift_PosY = 0;
435 
436  // Increase pointer sensibility.
437  POINTER_SetCurrentSpeedOnAngle( DEFAULT_SPEED_ON_ANGLE );
438  POINTER_SetCurrentAngleStart( DEFAULT_ANGLESTART );
440  POINTER_SetCurrentPointer( POINTER_WIDTH, POINTER_WIDTH, BallPointerBmp );
442 // POINTER_SetPos( 0x3c, 0x3c ); //FL081103 very first drawing was dirty!
443  // YRT091120 : second pointer appears
444 
445  CurrentPointerColor = POINTER_DEFAULT_COLOR;
446 }
447 
448 /*******************************************************************************
449 *
450 * POINTER_Handler
451 *
452 *******************************************************************************/
460 /******************************************************************************/
461 void POINTER_Handler( void )
462 {
463  //~ static divider_t dividr = 0; //YRT130718 divider is now managed by the scheduler
464 
465  //~ // Goes into handler only every POINTER_DIVIDER calls.
466  //~ if ( ++dividr % WEIGHTED_TIME( POINTER_DIVIDER ) )
467  //~ {
468  //~ return;
469  //~ }
470 
471  switch ( Pointer_Mode )
472  {
473  // Nothing to do!
474  case POINTER_OFF :
475  case POINTER_UNDEF:
476  return;
477 
478  default:
479  break;
480  }
481 
482 #if MEMS_POINTER // Not necessary if no MEMS menu handling
483  // Where is the MEMS ?
484  MEMS_GetPosition( &OUT_X, &OUT_Y );
485 #endif
486 
487  /*
488  DRAW_DisplayString ( 20, 200, "X=" , 3);
489  UTIL_int2str ( buffer, OUT_X, 4, 0);
490  DRAW_DisplayString ( 40, 200, buffer , 4);
491 
492  DRAW_DisplayString ( 20, 180, "Y=" , 3);
493  UTIL_int2str ( buffer, OUT_Y, 4, 0);
494  DRAW_DisplayString ( 40, 180, buffer , 4);
495  */
496 
497  POINTER_Move();
498 }
499 
501 
502 /* Public functions ----------------------------------------------------------*/
503 
504 /*******************************************************************************
505 *
506 * POINTER_SetCurrentPointer
507 *
508 *******************************************************************************/
519 /********************************************************************************/
520 void POINTER_SetCurrentPointer( coord_t width, coord_t height, const u8* bmp )
521 {
522  if ( !bmp )
523  {
524  bmp = BallPointerBmp;
525  }
526 
527  // Update the area limits for the new pointer depending on its size
528  POINTER_SetRect( POINTER_Info.X_PosMin, POINTER_Info.Y_PosMin,
529  POINTER_Info.X_PosMax - POINTER_Info.X_PosMin + CurrentPointerWidth - width,
530  POINTER_Info.Y_PosMax - POINTER_Info.Y_PosMin + CurrentPointerHeight - height );
531 
532  CurrentPointerWidth = width;
533  CurrentPointerHeight = height;
534  CurrentPointerBmp = bmp;
535 }
536 
537 /*******************************************************************************
538 *
539 * POINTER_GetCurrentAngleStart
540 *
541 *******************************************************************************/
549 /******************************************************************************/
551 {
552  return CurrentAngleStart;
553 }
554 
555 /*******************************************************************************
556 *
557 * POINTER_SetCurrentAngleStart
558 *
559 *******************************************************************************/
567 /******************************************************************************/
568 void POINTER_SetCurrentAngleStart( u16 newangle )
569 {
570  CurrentAngleStart = newangle;
571 }
572 
573 /*******************************************************************************
574 *
575 * POINTER_GetCurrentSpeedOnAngle
576 *
577 *******************************************************************************/
585 /******************************************************************************/
587 {
588  return CurrentSpeedOnAngle;
589 }
590 
591 /*******************************************************************************
592 *
593 * POINTER_SetCurrentSpeedOnAngle
594 *
595 *******************************************************************************/
603 /******************************************************************************/
604 void POINTER_SetCurrentSpeedOnAngle( u16 newspeed )
605 {
606  CurrentSpeedOnAngle = newspeed;
607 }
608 
609 /*******************************************************************************
610 *
611 * POINTER_SetCurrentAreaStore
612 *
613 *******************************************************************************/
626 /******************************************************************************/
628 {
629  ptrAreaStore = ( ptr == 0 ) ? DefaultAreaStore : ptr;
630 }
631 
632 /*******************************************************************************
633 *
634 * POINTER_SetMode
635 *
636 *******************************************************************************/
646 /******************************************************************************/
647 void POINTER_SetMode( enum POINTER_mode mode )
648 {
649  u16* ptr;
650  u16 i;
651  u16 color;
652 
653  if ( Pointer_Mode == mode )
654  return;
655 
656  switch ( mode )
657  {
658  case POINTER_APPLICATION:
659  ptr = ( u16* )DefaultAreaStore;
660  color = DRAW_GetBGndColor();
661 
662  for ( i = 0; i < ( CurrentPointerWidth * CurrentPointerHeight ) ; i++ )
663  {
664  *ptr++ = color;
665  }
666 
667  POINTER_Draw( POINTER_Info.xPos, POINTER_Info.yPos, CurrentPointerWidth, CurrentPointerHeight, CurrentPointerBmp );
668  break;
669 
671  POINTER_Draw( POINTER_Info.xPos, POINTER_Info.yPos, CurrentPointerWidth, CurrentPointerHeight, CurrentPointerBmp );
672  break;
673 
674  case POINTER_ON:
676  POINTER_Save( POINTER_Info.xPos, POINTER_Info.yPos, POINTER_WIDTH, POINTER_WIDTH );
677  POINTER_Draw( POINTER_Info.xPos, POINTER_Info.yPos, CurrentPointerWidth, CurrentPointerHeight, CurrentPointerBmp );
678  POINTER_Draw( POINTER_Info.xPos, POINTER_Info.yPos, CurrentPointerWidth, CurrentPointerHeight, CurrentPointerBmp );
679  break;
680 
681  case POINTER_OFF:
682  POINTER_Info.xPos = ( Screen_Width - POINTER_WIDTH ) / 2;
683  POINTER_Info.yPos = ( Screen_Width - POINTER_WIDTH ) / 2;
684 
685  case POINTER_MENU:
686  if ( Pointer_Mode == POINTER_ON )
687  {
689  POINTER_Restore( POINTER_Info.xPos, POINTER_Info.yPos, POINTER_WIDTH, POINTER_WIDTH );
690  }
691  break;
692 
693  default:
694  break;
695  }
696 
697  Pointer_Mode = mode;
698 }
699 
700 /*******************************************************************************
701 *
702 * POINTER_GetMode
703 *
704 *******************************************************************************/
712 /******************************************************************************/
714 {
715  return Pointer_Mode;
716 }
717 
718 /*******************************************************************************
719 *
720 * POINTER_GetState
721 *
722 *******************************************************************************/
730 /******************************************************************************/
732 {
733  return Pointer_State;
734 }
735 
736 /*******************************************************************************
737 *
738 * POINTER_SetRect
739 *
740 *******************************************************************************/
753 /******************************************************************************/
754 void POINTER_SetRect( coord_t x, coord_t y, coord_t width, coord_t height )
755 {
756  POINTER_Info.X_PosMin = x;
757 
758  if ( POINTER_Info.xPos < POINTER_Info.X_PosMin )
759  {
760  POINTER_Info.xPos = POINTER_Info.X_PosMin;
761  }
762 
763  POINTER_Info.X_PosMax = x + width;
764 
765  if ( POINTER_Info.xPos > POINTER_Info.X_PosMax )
766  {
767  POINTER_Info.xPos = POINTER_Info.X_PosMax;
768  }
769 
770  POINTER_Info.Y_PosMin = y;
771 
772  if ( POINTER_Info.yPos < POINTER_Info.Y_PosMin )
773  {
774  POINTER_Info.yPos = POINTER_Info.Y_PosMin;
775  }
776 
777  POINTER_Info.Y_PosMax = y + height;
778 
779  if ( POINTER_Info.yPos > POINTER_Info.Y_PosMax )
780  {
781  POINTER_Info.yPos = POINTER_Info.Y_PosMax;
782  }
783 }
784 
785 /*******************************************************************************
786 *
787 * POINTER_SetRectScreen
788 *
789 *******************************************************************************/
795 /******************************************************************************/
797 {
798  POINTER_SetRect( 0, 0, Screen_Width - CurrentPointerWidth, Screen_Height - CurrentPointerHeight );
799 }
800 
801 /*******************************************************************************
802 *
803 * POINTER_GetPos
804 *
805 *******************************************************************************/
814 /******************************************************************************/
815 u16 POINTER_GetPos( void )
816 {
817  return ( POINTER_Info.xPos | ( POINTER_Info.yPos << 8 ) );
818 }
819 
820 /*******************************************************************************
821 *
822 * POINTER_SetPos
823 *
824 *******************************************************************************/
835 /******************************************************************************/
836 void POINTER_SetPos( coord_t x, coord_t y ) //TODO GetPos uses a single u16 (u8+u8), why does SetPos use 2 u16?
837 {
838  POINTER_Info.xPos = x;
839  POINTER_Info.yPos = y;
840 }
841 
842 /*******************************************************************************
843 *
844 * POINTER_Draw
845 *
846 *******************************************************************************/
862 /******************************************************************************/
863 void POINTER_Draw( coord_t x, coord_t y, coord_t width, coord_t height, const u8* bmp )
864 {
865  s32 i = 0;
866  s32 l = 0;
867  s32 n = 0;
868  u8* ptr = ptrAreaStore;
869  u8 c;
870  u16 val;
871 
872  // No bitmap provided, use the default one!
873  if ( !bmp )
874  {
875  bmp = BallPointerBmp;
876  }
877 
878  // Select the screen area were going to take care about!
879  LCD_SetRect_For_Cmd( x, y, width, height );
880 
881  /* Send LCD RAM write command. */
882  LCD_SendLCDCmd_RAM_Access();
883 
884  while ( n < ( width * height ) )
885  {
886  if ( Pointer_Mode != POINTER_RESTORE_LESS )
887  {
888  // Draw pixel using current storage area data for background pixels.
889  c = *ptr++;
890 
891  LCD_SendLCDData( ( bmp[l + ( i / 8 )] & ( 1 << ( 7 - ( i % 8 ) ) ) ) ? ( POINTER_GetColor() & 255 ) : c );
892 
893  c = *ptr++;
894  LCD_SendLCDData( ( bmp[l + ( i / 8 )] & ( 1 << ( 7 - ( i % 8 ) ) ) ) ? ( POINTER_GetColor() >> 8 ) : c );
895  }
896  else
897  {
898  // POINTER_RESTORE_LESS: use current background color for background color.
899  c = DRAW_GetBGndColor();
900  val = ( bmp[l + ( i / 8 )] & ( 1 << ( 7 - ( i % 8 ) ) ) ) ? POINTER_GetColor() : c;
901 
902  LCD_SendLCDData( val & 255 );
903  LCD_SendLCDData( val >> 8 );
904  }
905 
906  n++;
907 
908  i++;
909 
910  // End of line ?
911  if ( i == width )
912  {
913  // Next line!
914  l++;
915  i = 0;
916  }
917  }
918 
919  /* End of select screen area to access.*/
920  LCD_SendLCDCmd_RAM_Access_End();
921 
922 }
923 
924 /*******************************************************************************
925 *
926 * POINTER_Save
927 *
928 *******************************************************************************/
944 /******************************************************************************/
945 void POINTER_Save( coord_t x, coord_t y, coord_t width, coord_t height )
946 {
947  // Is this pointer management mode, don't save pointer background!
948  if ( Pointer_Mode == POINTER_RESTORE_LESS )
949  {
950  return;
951  }
952 
953  //Use standard graphic function
954  LCD_RectRead( x, y, width, height, ptrAreaStore );
955 }
956 
957 /*******************************************************************************
958 *
959 * POINTER_Restore
960 *
961 *******************************************************************************/
976 /******************************************************************************/
977 void POINTER_Restore( coord_t x, coord_t y, coord_t width, coord_t height )
978 {
979  u16 i;
980  u8* ptr = ptrAreaStore;
981  u16 bytesize = ( width * height ) * 2; // 2 bytes per pixel
982 
983  // Select the screen area to write.
984  LCD_SetRect_For_Cmd( x, y, width, height );
985 
986  // Send the memory write command to the LCD controller.
987  LCD_SendLCDCmd_RAM_Access();
988 
989  for ( i = 0; i < bytesize; i++ )
990  {
991  // In this mode, use background color (no data was previously saved).
992  if ( Pointer_Mode == POINTER_RESTORE_LESS )
993  {
995  }
996  else
997  {
998  LCD_SendLCDData( *ptr++ );
999  }
1000  }
1001 
1002  /* End of select screen area to access.*/
1003  LCD_SendLCDCmd_RAM_Access_End();
1004 
1005 }
1006 
1007 /*******************************************************************************
1008 *
1009 * POINTER_SetApplication_Pointer_Mgr
1010 *
1011 *******************************************************************************/
1019 /******************************************************************************/
1021 {
1022  Application_Pointer_Mgr = mgr;
1023 }
1024 
1025 /*******************************************************************************
1026 *
1027 * POINTER_SetColor
1028 *
1029 *******************************************************************************/
1037 /******************************************************************************/
1038 void POINTER_SetColor( color_t color )
1039 {
1040  CurrentPointerColor = color;
1041 }
1042 
1043 /*******************************************************************************
1044 *
1045 * POINTER_GetColor
1046 *
1047 *******************************************************************************/
1055 /******************************************************************************/
1056 color_t POINTER_GetColor( void )
1057 {
1058  return CurrentPointerColor;
1059 }
1060 
1061 /*******************************************************************************
1062 *
1063 * POINTER_GetInfo
1064 *
1065 *******************************************************************************/
1073 /******************************************************************************/
1075 {
1076  return &POINTER_Info;
1077 }