⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 r2d.c

📁 是一个手机功能的模拟程序
💻 C
📖 第 1 页 / 共 5 页
字号:
//07/16/2002 zhangzg modified r2d_draw_bmp. So it has the function of display a inverted bmp
//6.13,chenjun &zym change
/**
                                                                          
  @file       r2d.c   
  
  @author     Christophe Favergeon

  @version    0.5
                                                                          
  Function    Riviera 2D system implementation
              (higher software layer)                       
     
*/

/*
  Date        Modification                                                 
  ------------------------                                                 
  06/12/2001    Create    
  10/18/2001    Version 0.5 for first integration with Riviera database
  06/12/2002    Version 0.6 add the scrEnabled variable to prevent send event before
                            all LCD data is prepared
 **************************************************************************
  History       
                                                                          
*/

  
#include "general.h"
#include "rvf_api.h"
#include "r2d_config.h"
#include "r2d.h"
#include "r2d_i.h"
#include "r2d_independance_layer.h"
#include "r2d_convertion_table.h"
#include "r2d_env.h"
#include "rvm_use_id_list.h"
#include <string.h>
// modified by clrobert from
//#include "nucleus.h" 
// to
#ifndef _INNOVATION_EMULATOR_
#include "nucleus.h"
#elif defined(_INNOVATION_EMULATOR_)
#include "windows.h"
#endif
//modify end

#if R2D_SUBLCD_SUPPORT
extern char bSubRefresh;
//glowing, 2004-05-10, define sub_scrEnabled to pass link
extern char sub_scrEnabled;
//int sub_scrEnabled = 0;              /* sub screen update enable */
#endif

#ifndef _DEBUG
   #define _DEBUG
#endif

//glowing, 2004-05-10, define scrEnabled to pass link
extern int scrEnabled;
//int scrEnabled=1;   

/*ljq added it to control trace command 2003/1/9*/
#ifndef _INNOVATION_EMULATOR_
extern UNSIGNED RivieraTraceFlag;
#endif

//#define r2d_check_and_send_event(gc)  if(scrEnabled || sub_scrEnabled)r2d_check_and_send_event_New(gc);
#define r2d_check_and_send_event(gc)  if(scrEnabled )r2d_check_and_send_event_New(gc);
									  	
extern int g_test;///zym modified 11/11

int g_keypadnum = 0;
/***************************************

     IMPORTANT INFORMATION

***************************************/

/*

Clipping is done on original coordinates.
Then those coordinates are modified to take into account a possible
mirror symetry of the LCD. 
Then the scanning algorithm is applied on those transformed and clipped
coordinates. It assumes a vertical scanning (column per column).
If it is not the case. The high level coordinates (x,y) are swapped
after clipping and mirroring. The scanning is done on the swapped coordinates
so that coulmns are mapped to lines.

Subroutine's comment use following rule:
H -> High level user coordinates
L -> LCD coordinates (mirroring or not and local_to_global applied)
S -> Scanning coordinates (vertical or horizontal)
*/

/***************************************

     CONSTANTS

***************************************/

// Used for char drawing algorithm with unicode
typedef enum K_R2D_CHAR_DRAWING_MODE
{
R2D_COMBINING_CHAR=1
} T_R2D_CHAR_DRAWING_MODE;


/***************************************

     REFRESH TASK RELATED GLOBALS

***************************************/

extern INT16 r2d_update_ul_x,r2d_update_ul_y,r2d_update_br_x,r2d_update_br_y;


/***************************************

     STATIC INTERNAL FUNCTIONS
	 AND GLOBALS

***************************************/


#define IND_r2d_write_lcd_line r2d_write_lcd_line
#define IND_r2d_write_lcd_pixel r2d_new_write_lcd_pixel   ///zym modified 10/24
#define IND_r2d_blit_lcd_to_lcd r2d_blit_lcd_to_lcd
#define IND_r2d_blit_lcd_to_color r2d_blit_lcd_to_color
#define IND_r2d_blit_color_to_lcd r2d_blit_color_to_lcd
#define IND_r2d_blit_color_to_color r2d_blit_color_to_color
#define IND_r2d_get_color_pixel_value r2d_get_color_pixel_value

static T_R2D_GC_PTR r2d_new_font_buffer_context(T_RVF_MB_ID bank,
												T_R2D_FRAMEBUFFER_KIND kind,
												UINT16 max_width,
												UINT16 ascent);
static T_R2D_FONT_CACHE_FRAMEBUFFER* r2d_new_font_framebuffer(T_RVF_MB_ID bank,
															  T_R2D_FRAMEBUFFER_KIND the_kind,UINT16 width, UINT16 height);
static T_R2D_SHAPE_PTR r2d_s_level(T_R2D_GC_PTR gc,T_R2D_SHAPE_PTR self);
static void r2d_mirror_rectangle(T_R2D_GC_PTR gc,T_R2D_SHAPE_PTR rectangle);
static void r2d_mirror_clip_rectangle(T_R2D_GC_PTR gc,T_R2D_SHAPE_PTR rectangle);
static void r2d_diagonal_mirror(T_R2D_SHAPE_PTR rectangle);

static void r2d_update_region(INT16 ul_x,INT16 ul_y,INT16 br_x,INT16 br_y);

void r2d_translate_shape(T_R2D_SHAPE_PTR self,INT16 dx,INT16 dy);

// Used for pen_size != 1. It computes the bounding rect and calls
// fillrectangle
static void r2d_s_fill_point(T_R2D_GC_PTR gc,INT16 x,INT16 y,INT16 pen_size);

static void           r2d_df_rectangle(T_R2D_GC_PTR gc,
                  INT16 ul_x,INT16 ul_y,INT16 br_x, INT16 br_y,BOOLEAN background);
static void           r2d_s_fill_rectangle(T_R2D_GC_PTR gc,
                  INT16 ul_x,INT16 ul_y,INT16 br_x, INT16 br_y,BOOLEAN background);

const INT16 r2d_dash[8*8]=
{
	1,1,1,1,1,1,0,0,
	1,1,1,1,1,1,0,0,
	1,1,1,1,1,1,0,0,
	1,1,1,1,1,1,0,0,
	1,1,1,1,1,1,0,0,
	1,1,1,1,1,1,0,0,
	0,0,0,0,0,0,0,0,
	0,0,0,0,0,0,0,0,
};

#define R2D_SQUARE_P(x) (x*x)
#define R2D_SWAP(x,y) tmp=x; x=y; y=tmp

////////////////////////////////////////
//
// Utility functions
//


// L COORDINATES
void r2d_update_region(INT16 ul_x,INT16 ul_y,INT16 br_x,INT16 br_y)
{

	if (ul_x < r2d_update_ul_x)
		r2d_update_ul_x=ul_x;
    if (ul_y < r2d_update_ul_y)
		r2d_update_ul_y=ul_y;
	if (br_x > r2d_update_br_x)
		r2d_update_br_x=br_x;
	if (br_y > r2d_update_br_y)
		r2d_update_br_y=br_y;

	if (r2d_update_ul_x<0)
       r2d_update_ul_x=0;
    if (r2d_update_ul_y<0)
       r2d_update_ul_y=0;
    if (r2d_update_br_x>=R2D_WIDTH)
       r2d_update_br_x=R2D_WIDTH-1;
    if (r2d_update_br_y>=R2D_HEIGHT)
       r2d_update_br_y=R2D_HEIGHT-1;
}


void r2d_check_and_send_event_New(T_R2D_GC_PTR gc)
{
	  // If routine has drawn into the LCD framebuffer
	  // then refresh may be required
	  // If LCD framebuffer ONLY

	if(gc == r2d_g_lcd_gc && scrEnabled)
	{
		g_keypadnum++;
		
		if (((T_R2D_FRAMEBUFFER*)(((T_R2D_GC*)gc)->p_frame_buffer))->kind==0)  ///here we know lcd kind is zero
		{
			if ((r2d_g_event_was_sent == FALSE) && (r2d_g_refresh_disabled == 0))
			{
			#ifdef _DEBUG
			rvf_send_trace("R2D refresh main LCD",strlen("R2D refresh main LCD"),NULL_PARAM, 
							RV_TRACE_LEVEL_DEBUG_HIGH, R2D_USE_ID );
			#endif 	   

			r2d_g_event_was_sent = TRUE;

			 /* send event to r2d core */
			#ifndef _INNOVATION_EMULATOR_
				rvf_send_event( (UINT8)(r2d_addr_id & 0xFF), EVENT_MASK(RVF_APPL_EVT_0) );
			#else
				GUI_LCD_Fresh();
				r2d_g_event_was_sent = FALSE;	
			#endif 
			}
		}	  
	}
	#if 1
	else if(gc == r2d_g_sublcd_gc && sub_scrEnabled)
	{
		if (((T_R2D_FRAMEBUFFER*)(((T_R2D_GC*)gc)->p_frame_buffer))->kind == 0)  ///here we know lcd kind is zero
		{			
			#ifdef _DEBUG
			rvf_send_trace("R2D refresh sub LCD",strlen("R2D refresh sub LCD"),NULL_PARAM, 
							RV_TRACE_LEVEL_DEBUG_HIGH, R2D_USE_ID );
			#endif 	   			

			#ifndef _INNOVATION_EMULATOR_
				bSubRefresh = 1;
				rvf_send_event( (UINT8)(r2d_addr_id & 0xFF), EVENT_MASK(RVF_APPL_EVT_0) );
			#else
				 GUI_LCD_Fresh();
				 r2d_g_event_was_sent=FALSE;	
			#endif 
			
		}
	 }
	#endif
	 else
	 {
	  //#ifdef _DEBUG
	  #if 0
	  if(gc == r2d_g_lcd_gc)
	  {
	   rvf_send_trace("R2D SEND EVENT para error, gc!",strlen("R2D SEND EVENT para error, gc!"),NULL_PARAM, 
			  RV_TRACE_LEVEL_DEBUG_HIGH, R2D_USE_ID );
	  }
	  else if(gc == r2d_g_sublcd_gc)
	  {
	  rvf_send_trace("R2D SEND EVENT para error, sub_gc!",strlen("R2D SEND EVENT para error, sub_gc!"),NULL_PARAM, 
			  RV_TRACE_LEVEL_DEBUG_HIGH, R2D_USE_ID );
	  }
	  else if(gc == NULL)
	  {
	  rvf_send_trace("R2D SEND EVENT para error, gc null!",strlen("R2D SEND EVENT para error, gc null!"),NULL_PARAM, 
			  RV_TRACE_LEVEL_DEBUG_HIGH, R2D_USE_ID );
	  }
	  else
	  {
	  rvf_send_trace("R2D SEND EVENT para error, other!",strlen("R2D SEND EVENT para error, other!"),NULL_PARAM, 
			  RV_TRACE_LEVEL_DEBUG_HIGH, R2D_USE_ID );
	  }
      #endif 
	  	return;
	 }
	

	 #if 0
	 if(scrEnabled == 0)
	  return;
	  
	 g_keypadnum++;
	  #ifdef _DEBUG
	   rvf_send_trace("R2D SEND EVENT TRY",strlen("R2D SEND EVENT TRY"),NULL_PARAM, 
			  RV_TRACE_LEVEL_DEBUG_HIGH, R2D_USE_ID );
      #endif 
	  if (((T_R2D_FRAMEBUFFER*)(((T_R2D_GC*)gc)->p_frame_buffer))->kind==0)  ///here we know lcd kind is zero
	  {
	  if ((r2d_g_event_was_sent==FALSE) && (r2d_g_refresh_disabled==0))
      {
       #ifdef _DEBUG
		  rvf_send_trace("R2D SEND EVENT",strlen("R2D SEND EVENT"), NULL_PARAM, 
			   RV_TRACE_LEVEL_DEBUG_HIGH, R2D_USE_ID );
	   #endif	   
		     r2d_g_event_was_sent=TRUE;

		    #ifndef _INNOVATION_EMULATOR_
			 rvf_send_event( (UINT8)(r2d_addr_id & 0xFF), EVENT_MASK(RVF_APPL_EVT_0) );
			#else
			 GUI_LCD_Fresh();
			 r2d_g_event_was_sent=FALSE;	
			#endif 
	  }
	  }
	#endif
}

// WILL HAVE TO BE IMPROVED

INT32 r2d_fixed_division(INT32 a,INT32 b)
{
    INT16 k;
    UINT32 q,nb;
    INT16 right_shift=0;
    INT16 sign=0;

	// Convert to positive values
    if ((b<0) && (a<0))
	{
		b=-b;
		a=-a;
	}
	if ((b<0) && (a>=0))
	{
		b=-b;
		sign=1;
	}
	if ((a<0) && (b>=0))
	{
		a=-a;
		sign=1;
	}


    // Normalize b between in [0.5,1[
    

    nb=b;

    if (nb>=0x10000)
    {
      //printf("%08X/%08X\n",a,nb);
      while(((nb>>16)&0x0FFFF)!=0)
      {
         nb>>=1;
         right_shift++;
         //printf("%08X\n",nb);
      }
    } else if (nb<0x8000)
    {
      while((nb&0x8000)==0)
      {
         nb<<=1;
         right_shift--;
         //printf("%08X\n",nb);
      }
    }
    //printf("right_shift=%d\n",right_shift);
    if (nb==0x8000)
    {
      //printf("nb=0x8000, return %08X\n",((a>>right_shift)<<1));
      if (sign)
        return (-((a>>right_shift)<<1));
      else
        return (((a>>right_shift)<<1));
    }


    

    // Newton method used to compute 1/nb with
    // q=q(2-nb * q)

    // Which first choice for q and which accuracies for intermediate
    // computations ?

    
    // nb being in ]0.5,1[ one must has q in ]0.5, 3[
    // And one must check that the function is contracting
    // Derivative is nul for q*nb = 1. Below, sign of
    // derivatuve (relatively to q) is positive if a<1 and
    // the derivative is between 2 and 0
    // <1 is got for q>1/(2 nb) and q must be < 1/nb
    // One can take q=1 as starting value. It solves
    // for the bounds except for nb=1 or nb=0.5

    // if q in ]1/2nb, 1/nb[ one can check that qnew
    // will at most reach 3/2nb at next iteration and then will
    // fall back into the intervall
    // So, one needs to represents values up to 3 for q
    // and 2 bits are required for integer part
    
    // So, q is 2.16, nb is 0.16
    // q*nb is 2.32 which cannot be represented and one needs
    // to shift value by 1 bit
    // nb will be 0.15 and q 2.15 sor nb*q is 2.30
    // It must be multiplied by a format 2.16
    // so both intermediate result must be shifted to
    // 2.15 (1 for q and 15 for np*q)
    
    

    q=(1<<16);
    //printf("-- q=%08X\n",q);

    
    for(k=0;k<5;k++)
    {
       q=((q>>1) * ((2 << 15) - (((nb>>1) * (q>>1))  >> 15))) >> 14;
       //printf("-- q=%08X\n",q);
    }
    
    // a is known to be an integer and q is know to be less than 1
    // so a 64 bits product is not required

    //printf("a=%08X, q=%08X\n",a,q);

    q>>=right_shift;

    q=((a>>16)*q) ;


    //printf("right_shift=%d, q=%08X\n",right_shift,q);

    if (sign)
     return(-((INT32)q));
    else
     return(q);

    
}

////////////////////////////////////////
//
// Texture
//

T_R2D_FREE_TEXTURE_PTR r2d_new_free_texture(T_RVF_MB_ID bank,INT16 size,T_R2D_ARGB_COLOR *pattern)
{
   T_R2D_FREE_TEXTURE *t;

   R2D_MALLOC(bank,T_R2D_FREE_TEXTURE,sizeof(T_R2D_FREE_TEXTURE),t);

   if (t)
   {
	   t->refcount=1;
	   t->size=size;
	   t->pattern=pattern;
   }

   return(t);
}

T_R2D_FREE_TEXTURE_PTR r2d_new_const_free_texture(T_RVF_MB_ID bank,INT16 size,T_R2D_ARGB_COLOR *pattern)
{
   T_R2D_FREE_TEXTURE *t;

   R2D_MALLOC(bank,T_R2D_FREE_TEXTURE,sizeof(T_R2D_FREE_TEXTURE),t);

   if (t)
   {
	   t->refcount=-1;
	   t->size=size;
	   t->pattern=pattern;
   }

   return(t);
}

void              r2d_release_free_texture(T_R2D_FREE_TEXTURE_PTR texture)
{
	if (texture)
    {
      // Remove the array of words if needed
      // (refcount must be 1 else the array should not be deleted)
      if (R2D_REFCOUNT(texture)==1) 
	  {
		if (((T_R2D_FREE_TEXTURE*)texture)->pattern)
          R2D_FREE(((T_R2D_FREE_TEXTURE*)texture)->pattern);
	  }
    }
    // Autorelease
    r2d_release(texture);
}

T_R2D_ANCHORED_TEXTURE_PTR r2d_new_anchored_texture(T_RVF_MB_ID bank,T_R2D_GC_PTR gc,T_R2D_FREE_TEXTURE_PTR texture)
{

  UINT32 length;
  T_R2D_FREE_TEXTURE *ft;
  T_R2D_ANCHORED_TEXTURE *at;
  INT16 i,j,x,y,ni,nj,pos;
  UINT32 *p;

		 T_R2D_ARGB_COLOR b;

   // If a new texture is installed,
   // one must recompute p_background
   if (texture==NULL)
	  goto erroranchored;

   
     
   ft=(T_R2D_FREE_TEXTURE *)texture;

   length=1<<(ft->size);

   R2D_MALLOC(bank,T_R2D_ANCHORED_TEXTURE,sizeof(T_R2D_ANCHORED_TEXTURE),at);

   if (at==NULL)
	   goto erroranchored;

   at->refcount=1;

   at->size=ft->size;

   R2D_MALLOC(bank,UINT32,sizeof(UINT32)*length*length,at->pattern);

   if (at->pattern==NULL)
   {
	   R2D_FREE(at);
	   goto erroranchored;
   }
     
	 
   p=at->pattern;
   b=r2d_get_background_color(gc);

   if (((T_R2D_FRAMEBUFFER*)(((T_R2D_GC*)gc)->p_frame_buffer))->kind==R2D_FULL_KIND)
   {
			 x=0;

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -