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

📄 c_cmd_drawing.inc

📁 乐高机器人的源码,开发平台是IAR_for_AVR.
💻 INC
📖 第 1 页 / 共 2 页
字号:
//
// Date init       14.12.2004
//
// Revision date   $Date:: 8/26/05 4:17p                                     $
//
// Filename        $Workfile:: c_cmd.c                                       $
//
// Version         $Revision:: 35                                            $
//
// Archive         $Archive:: /LMS2006/Sys01/Main/Firmware/Source/c_cmd_drawing.c $
//
// Platform        C
//

//absolute value of a
#define ABS(a)    (((a)<0) ? -(a) : (a))

//take binary sign of a, either -1, or 1 if >= 0
#define SGN(a)    (((a)<0) ? -1 : 1)

#define DISP_BUFFER_P ((UBYTE*)&(pMapDisplay->Normal))

//------------------------------------------------------------------
// cCmdClearScreenIfNeeded - Clear entire sceen buffer if explicitly requested or implicitly required.
void cCmdClearScreenIfNeeded(ULONG DrawOptions);

//------------------------------------------------------------------
// cCmdRestorDefaultScreen - Restore screen to default 'Running' screen
void cCmdRestoreDefaultScreen(void);

//------------------------------------------------------------------
// cCmdDrawString - Draw string to display buffer
void cCmdDrawString(UBYTE *pString, ULONG X, ULONG Y);

// OP codes supported by RIC files
enum {
  IMG_DESCRIPTION_ID = 0, // Ignored at this time
  IMG_SPRITE_ID = 1,
  IMG_VARMAP_ID = 2,
  IMG_COPYBITS_ID = 3,
  IMG_PIXEL_ID = 4,
  IMG_LINE_ID = 5,
  IMG_RECTANGLE_ID = 6,
  IMG_CIRCLE_ID = 7,
  IMG_NUMBOX_ID = 8
};

#define IMG_SYMB_USEARGS(_v) (_v & (SWORD)0xF000)
#define IMG_SYMB_MAP(_v)  ((_v & 0x0F00) >> 8)
#define IMG_SYMB_ARG(_v)  (_v & 0x000F)

// DrawingOptions
#define DRAW_OPT_CLEAR_WHOLE_SCREEN     (0x0001)
#define DRAW_OPT_CLEAR_EXCEPT_STATUS_SCREEN     (0x0002)
#define DRAW_OPT_CLEAR_MODE(_v)     ((_v) & 0x0003)


// Clear Before Drawing Modes for Draw functions
enum {
  DO_NOT_CLEAR = 0,
  CLEAR_B4_DRAW = 1
};

// Screen Modes for SetScreenMode function
enum {
  RESTORE_NXT_SCREEN = 0
};

#define IMG_COMMON_FIELDS  UWORD OpSize; UWORD OpCode;

#define TRANSLATE_Y(_y) ((DISPLAY_HEIGHT-1) - (_y))

typedef struct
{
  SWORD X, Y;
} IMG_PT;

typedef struct
{
  IMG_PT Pt;
  SWORD Width, Height;
} IMG_RECT;

typedef struct
{
  IMG_COMMON_FIELDS
} IMG_OP_CORE;

typedef struct
{
  IMG_COMMON_FIELDS
  UWORD Options;
  UWORD Width;
  UWORD Height;
} IMG_OP_DESCRIPTION;

typedef struct
{
  IMG_COMMON_FIELDS
  UWORD   DataAddr;    //Address sprite handle will be stored in.
  UWORD   Rows;        //Second deminsion of the array below.
  UWORD   RowBytes;    //The actual size of the following array. Must be even.
  UBYTE   Bytes[2];    //Minimum of two for alignment purposes
} IMG_OP_SPRITE;

typedef struct
{
  IMG_COMMON_FIELDS
  UWORD   DataAddr;    //Address sprite handle will be stored in.
  UWORD   MapCount;    //The actual size of the following array. Must be even.
  struct
  {    //Minimum of two for alignment purposes
    UWORD   Domain;
    UWORD   Range;
  }       MapElt[1];
} IMG_OP_VARMAP;

typedef struct
{
  IMG_COMMON_FIELDS
  UWORD     CopyOptions;  // Copy, CopyNot, Or, BitClear;
  UWORD     DataAddr;   // Address of an already defined sprite
  IMG_RECT  Src;    // Source rectangle
  IMG_PT Dst;    // Destination left top
} IMG_OP_COPYBITS;

typedef struct
{
  IMG_COMMON_FIELDS
  UWORD   CopyOptions;
  IMG_PT  Pt;
  UWORD   Value; // typically mapped to an argument
} IMG_OP_PIXEL;

typedef struct
{
  IMG_COMMON_FIELDS
  UWORD   CopyOptions;
  IMG_PT  Pt1;
  IMG_PT  Pt2;
} IMG_OP_LINE;

typedef struct
{
  IMG_COMMON_FIELDS
  UWORD   CopyOptions;
  IMG_PT  Pt;
  SWORD  Width, Height;
} IMG_OP_RECT;

typedef struct
{
  IMG_COMMON_FIELDS
  UWORD   CopyOptions;
  IMG_PT  Pt;
  UWORD   Radius;
} IMG_OP_CIRCLE;

typedef struct
{
  IMG_COMMON_FIELDS
  UWORD   CopyOptions;
  IMG_PT  Pt;
  UWORD   Value; // typically mapped to an argument
} IMG_OP_NUMBOX;

typedef union
{ IMG_OP_CORE      Core;
  IMG_OP_DESCRIPTION Desc;
  IMG_OP_SPRITE    Sprite;
  IMG_OP_VARMAP    VarMap;
  IMG_OP_COPYBITS  CopyBits;
  IMG_OP_PIXEL     Pixel;
  IMG_OP_LINE      Line;
  IMG_OP_RECT      Rect;
  IMG_OP_CIRCLE    Circle;
  IMG_OP_NUMBOX    NumBox;
} IMG_OP_UNION;

// Variables for DrawImage
#define IMG_MAX_DATA 11
IMG_OP_UNION  * gpImgData[IMG_MAX_DATA];
SLONG         * gpPassedImgVars;
SWORD   gPassedVarsCount;

// Private Prototypes
void cCmdDrawLine(SLONG x1, SLONG y1, SLONG x2, SLONG y2);
void cCmdDrawRect(SLONG left, SLONG bottom, SLONG width, SLONG hieght);
void cCmdCopyBitMapBits(SLONG dst_x, SLONG dst_y,
                        SLONG src_x, SLONG src_y, SLONG src_width, SLONG src_height,
                        IMG_OP_SPRITE * pSprite);
SLONG cCmdResolveValue(SWORD Value);
void cCmdSetPixel(SLONG X, SLONG Y, ULONG Val);

//-----------------------------------------------------------------
//cCmdWrapDrawText
//ArgV[0]: (Function return) Status byte, SBYTE
//ArgV[1]: Location (IMG_PT *)
//ArgV[2]: Text (CStr)
//ArgV[3]: Options (ULONG)
//
NXT_STATUS cCmdWrapDrawText(UBYTE * ArgV[])
{
  IMG_PT * pPt = (IMG_PT*) ArgV[1];

  ArgV[2] = (UBYTE*)cCmdDVPtr(*(DV_INDEX *)(ArgV[2]));   //Resolve array argument

  cCmdClearScreenIfNeeded(*(ULONG*)ArgV[3]);

  // Display the String
  cCmdDrawString(ArgV[2], (UBYTE)pPt->X, (UBYTE)(pPt->Y));
  pMapDisplay->UpdateMask |= SCREEN_BIT(SCREEN_BACKGROUND);

  // Set return value
  *((SBYTE*)(ArgV[0])) = NO_ERR;

  return NO_ERR;
}

//-----------------------------------------------------------------
//cCmdWrapDrawPoint
//ArgV[0]: (Function return) Status byte, SBYTE
//ArgV[1]: Location (IMG_PT *)
//ArgV[2]: Options (ULONG)
NXT_STATUS cCmdWrapDrawPoint(UBYTE * ArgV[])
{
  IMG_PT * pPt = (IMG_PT*) ArgV[1];

  cCmdClearScreenIfNeeded(*(ULONG*)ArgV[2]);

  // Display the String
  cCmdSetPixel(pPt->X, pPt->Y, TRUE);

  pMapDisplay->UpdateMask |= SCREEN_BIT(SCREEN_BACKGROUND);

  // Set return value
  *((SBYTE*)(ArgV[0])) = NO_ERR;

  return NO_ERR;
}

//-----------------------------------------------------------------
//cCmdWrapDrawLine
//ArgV[0]: (Function return) Status byte, SBYTE
//ArgV[1]: Start Location (IMG_PT *)
//ArgV[2]: End Location (IMG_PT *)
//ArgV[3]: Options (ULONG)
NXT_STATUS cCmdWrapDrawLine(UBYTE * ArgV[])
{
  IMG_PT * pPt1 = (IMG_PT*) ArgV[1];
  IMG_PT * pPt2 = (IMG_PT*) ArgV[2];

  cCmdClearScreenIfNeeded(*(ULONG*)ArgV[3]);

  cCmdDrawLine(pPt1->X, pPt1->Y, pPt2->X, pPt2->Y);

  pMapDisplay->UpdateMask |= SCREEN_BIT(SCREEN_BACKGROUND);

  // Set return value
  *((SBYTE*)(ArgV[0])) = NO_ERR;

  return NO_ERR;
}

//-----------------------------------------------------------------
//cCmdWrapDrawCircle
//ArgV[0]: (Function return) Status byte, SBYTE
//ArgV[1]: Start Location (IMG_PT *)
//ArgV[2]: Radius (U8)
//ArgV[3]: Options (ULONG)
NXT_STATUS cCmdWrapDrawCircle(UBYTE * ArgV[])
{
  SLONG x, x1, y1, y, dp, delta;
  IMG_PT * pPt = (IMG_PT*) ArgV[1];
  SLONG radius = *(UBYTE*)ArgV[2];

  cCmdClearScreenIfNeeded(*(ULONG*)ArgV[3]);

  x1 = pPt->X;
  y1 = pPt->Y;
  x = 0;
  y = radius;
  dp=2*(1-radius);
  while(y >= 0)
  {
    cCmdSetPixel((x+x1), (y+y1),  TRUE);
    cCmdSetPixel((-x+x1),(-y+y1), TRUE);
    cCmdSetPixel((x+x1), (-y+y1), TRUE);
    cCmdSetPixel((-x+x1),(y+y1),  TRUE);
    if(dp<0)
    {
      delta = 2*dp + 2*y - 1;
      if (delta > 0)
      {
        x++;
        y--;
        dp += 2*x - 2*y + 2;
      }
      else
      {
        x++;
        dp += 2*x + 1;
      }
    }
    else if (dp > 0)
    {
      delta = 2*dp - 2*x - 1;
      if (delta > 0)
      {
        y--;
        dp += 1 - 2*y;
      }
      else
      {
        x++;
        y--;
        dp += 2*x - 2*y + 2;
      }
    }
    else
    {
      x++;
      y--;
      dp += 2*x - 2*y +2;
    }
  }

  pMapDisplay->UpdateMask |= SCREEN_BIT(SCREEN_BACKGROUND);

  // Set return value
  *((SBYTE*)(ArgV[0])) = NO_ERR;

  return NO_ERR;
}

//-----------------------------------------------------------------
//cCmdWrapDrawRect
//ArgV[0]: (Function return) Status byte, SBYTE
//ArgV[1]: TopLeft (IMG_PT *)
//ArgV[2]: BottomRight (IMG_PT *)
//ArgV[3]: Options (ULONG)
NXT_STATUS cCmdWrapDrawRect(UBYTE * ArgV[])
{
  IMG_PT * pPt1 = (IMG_PT*) ArgV[1];
  IMG_PT * pPt2 = (IMG_PT*) ArgV[2];  // Second point is actually (width, height)

  cCmdClearScreenIfNeeded(*(ULONG*)ArgV[3]);

  cCmdDrawRect(pPt1->X, pPt1->Y, pPt2->X, pPt2->Y);

  pMapDisplay->UpdateMask |= SCREEN_BIT(SCREEN_BACKGROUND);

  // Set return value
  *((SBYTE*)(ArgV[0])) = NO_ERR;

  return NO_ERR;
}

//-----------------------------------------------------------------
IMG_OP_UNION * cCmdGetIMGData(ULONG DataAddr)
{
  if (DataAddr >= IMG_MAX_DATA)
    return NULL;
  else
    return gpImgData[DataAddr];
}

//-----------------------------------------------------------------
void cCmdSetIMGData(ULONG DataAddr, IMG_OP_UNION * pSprite)
{
  if ((DataAddr >= 1) && (DataAddr < IMG_MAX_DATA))
    gpImgData[DataAddr] = pSprite;
}

//-----------------------------------------------------------------
SLONG cCmdResolveValue(SWORD Value)
{
  if (!IMG_SYMB_USEARGS(Value))
  {
    return Value;
  }
  else
  {
    IMG_OP_VARMAP * pVarMap;
    SLONG Arg;

    pVarMap = (IMG_OP_VARMAP *) cCmdGetIMGData((SWORD)IMG_SYMB_MAP(Value));
    Arg = gpPassedImgVars[IMG_SYMB_ARG(Value)];

    if (!pVarMap)
    {
      // No map, this implies a 1:1 mapping.
      return Arg;
    }
    else
    {
      // Scan through the list finding the pair the Arg lies between
      // Then linearly interpolate the mapping.
      SLONG i, DCur, RCur, DSpread, VSpread, RSpread;
      SLONG Count = pVarMap->MapCount;
      SLONG DPrev = pVarMap->MapElt[0].Domain;
      SLONG RPrev = pVarMap->MapElt[0].Range;
      if (Arg <= DPrev)
      {
        // Too small, map it to the first point
        return RPrev;
      }

      for (i = 1; i < Count; i++)
      {
        DCur = pVarMap->MapElt[i].Domain;
        RCur = pVarMap->MapElt[i].Range;
        if (Arg < DCur)
        {
          DSpread = DCur - DPrev;
          VSpread = Arg - DPrev;
          RSpread = RCur - RPrev;
          // Found the point and mapped, it return.
          return  (RPrev+((VSpread*RSpread)/DSpread));
        }
        DPrev = DCur;
        RPrev = RCur;
      }
      // If we get this far then it is too large, map it to the last point.
      return  RCur;
    }
  }
}


//-----------------------------------------------------------------
//cCmdWrapDrawGraphic
//ArgV[0]: (Function return) Status Byte, SBYTE
//ArgV[1]: Left Top (IMG_PT *)
//ArgV[2]: Filename, CStr
//ArgV[3]: Variables, array of I32
//ArgV[4]: Options (ULONG)
NXT_STATUS cCmdWrapDrawPicture(UBYTE * ArgV[])
{
  SBYTE * pReturnVal = (SBYTE*)(ArgV[0]);
  LOADER_STATUS LStatus;
  NXT_STATUS    DStatus = NO_ERR;
  ULONG         DataSize;
  SLONG         OpSize;
  IMG_PT        Pt;     // Where to draw the picture at (up and to the right)
  UBYTE   ImageHandle;
  IMG_OP_UNION  * pImage;

⌨️ 快捷键说明

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