/*NEO SDK V2.1.90 For DOS
  Copyleft Cker Home 2003-2006.

  Open Source Obey NEO_PL.TXT.
  http://neo.coderlife.net
  ckerhome@yahoo.com.cn

  文件名称 : nshow.h
  摘    要 : 本头文件中包含了NEO SDK里有关各种图形文件处理,显示的函数、结构、全局变量的声明定义
             目前支持格式:1.标准(即静态,766字节)的32x32x16(色)*.cur和*.ico光标、图标文件

  当前版本 : V2.01
  作    者 : 凌晨一点
  完成日期 : 2006.02.01

  取代版本 : V2.00
  原 作 者 : 凌晨一点
  完成日期 : 2005.12.12
*/

#ifndef  __NICO_H__
#define  __NICO_H__

/*======================================================*
 *　　　 宏和结构的定义(Macro & type definitions)  　　 *
 *======================================================*/
#if defined NEO_icon_support_unused
#define NEO_mouse_icon_unused
#endif


typedef struct Cursor_type
{
   #ifndef NEO_icon_support_unused
   PIC_RGB  palette[16];
   unsigned color64k[16];
   unsigned char fir_cur_col;
   unsigned char map[512];
   unsigned char mask[128];
   unsigned char buffer[CUR_SIDE];
   #else
   PIC_RGB  palette[1];
   unsigned color64k[1];
   unsigned char fir_cur_col;
   unsigned char map[1];
   unsigned char mask[1];
   unsigned char buffer[1];
   #endif
}Cursor, *Cursor_ptr;


/*======================================================*
 *              函数声明(Function declare)              *
 *======================================================*/
int  fir_icon_color_pos(int firstcolorindex);
void show_icon(char *curfile, int x, int y);
Cursor_ptr load_icon(char *filename);
void blit_icon(Cursor_ptr cur_p, int x, int y);

/*======================================================*
 *            函数定义(Function definitions)            *
 *======================================================*/
/*---------------------------------------------------*
 *函数功能: 定位光标调色盘的在系统调色盘中的位置.　  *
 *参数说明: fircol_index:光标调色盘第一个颜色在系 　 *
 *          统调色盘中的位置(默认在240号颜色处，即从 *
 *          240~255这16种颜色为光标显示所用)注意:　　*
 *          fircol_index必须为小于241的整数.当       *
 *       fircol_index为负数时只返回当前光标调色盘首颜*
 *          色在系统调色盘中的位置.                  *
 *返回说明: 返回当前光标调色盘首颜色在系统调色盘中的 *
 *          位置.            　　　　　　　　　　　  *
 *备    注: 用户程序可以直接调用.          　　　    *
 *---------------------------------------------------*/
#ifndef NEO_icon_support_unused
int fir_icon_color_pos(int fircol_index)
{
   static unsigned char colorindex = /*239*/240;
   if (!g_color_depth)
   {
      #ifndef NEO_sys_report_error_unused
      Errinfo_t error = {"fir_icon_color_pos", ERR_VIDEO_MODE, 0};
      throw_error(error);
      #endif
   }
   if ((fircol_index>=0) && (fircol_index<=240))
   {
      colorindex = fircol_index;
      return colorindex;
   }
   else if (fircol_index < 0)
   {
      return colorindex;
   }
   else
   {
      return -1;
   }
}


void show_icon(char *curfile, int x, int y)
{
   Cursor_ptr cur_p;

   cur_p = load_icon(curfile);
   blit_icon(cur_p,x,y);
   free(cur_p);
}


/*---------------------------------------------------*
 *函数功能: 将图标文件读入内存.　　　  　　　　　　　*
 *参数说明: filename:图标文件名.　                   *
 *          Cursor_ptr cur_p:结构Cursor_type声明的结 *
 *          构体cur_p                                *
 *返回说明: 无.              　　　　　　　　　　　  *
 *备    注: 用户程序可以直接调用.　　　　　　　　    *
 *---------------------------------------------------*/
Cursor_ptr load_icon(char *filename)
{
   int k = 0;
   int x = 0;
   int y = 0;
   int i, j, offset;
   Cursor_ptr cursor_p = NULL;
   FILE *fp;

   if ((cursor_p = (Cursor_ptr)malloc( sizeof (Cursor) ))==NULL)
   {
      #ifndef NEO_sys_report_error_unused
      Errinfo_t error = {"load_icon", NO_MEMORY, 0};
      throw_error(error);
      #endif
   }

   fp = fopen(filename, "rb");
   if (fp == NULL)
   return FALSE;

   cursor_p->fir_cur_col = fir_icon_color_pos(-1);
   fseek(fp, 62, SEEK_SET);
   _FREAD(&cursor_p->palette, sizeof(PIC_RGB), 16, fp);
   _FREAD(&cursor_p->map, 512, 1, fp);
   _FREAD(&cursor_p->mask, 128, 1, fp);
   fclose(fp);

   memset(cursor_p->color64k, 0, 32);
   for(offset=0; offset<16; ++offset)
   {
      #ifndef NEO_color_depth_8_unused
      set_color(cursor_p->fir_cur_col + offset, (cursor_p->palette[offset]).red>>g_dac_size_fix,
                                        (cursor_p->palette[offset]).green>>g_dac_size_fix,
                                         (cursor_p->palette[offset]).blue>>g_dac_size_fix );
      #endif
      #ifndef NEO_color_depth_16_unused
      cursor_p->color64k[offset] += ((cursor_p->palette[offset]).red>>3);
      cursor_p->color64k[offset] <<= g_green_mask;
      cursor_p->color64k[offset] += ((cursor_p->palette[offset]).green>>g_green_bit);
      cursor_p->color64k[offset] <<= 5;
      cursor_p->color64k[offset] += (cursor_p->palette[offset]).blue>>3;
      #endif
   }

   if (g_color_depth == 8)
   {
      #ifndef NEO_color_depth_8_unused
      for(i=31; i>=0; --i)
      {
         for(j=0; j<32; j+=2)
         {
            cursor_p->buffer[( i<<5 )+j] = (cursor_p->map[k]>>4) + cursor_p->fir_cur_col;
            cursor_p->buffer[( i<<5 )+j+1] = (cursor_p->map[k++]&0x0f) + cursor_p->fir_cur_col;
         }
      }
      #endif
   }
   else if (g_color_depth == 15 || g_color_depth == 16)
   {
      #ifndef NEO_color_depth_16_unused
      for(i = 31; i >= 0; --i)
      {
         for(j = 0; j < 32; j += 2)
         {
            cursor_p->buffer[( i<<5 ) + j] = (cursor_p->map[k] >> 4);
            cursor_p->buffer[( i<<5 ) + j + 1] = (cursor_p->map[k++] & 0x0f);
         }
      }
      #endif
   }

   for(i = 124; i >= 0; i -= 4)
   {
      for(j = i; j <= i + 3; ++j)
      {
         unsigned char m = 0x80;

         for(k = 0; k < 8; ++k)
         {
            if(cursor_p->mask[j] & m)
            {
               cursor_p->buffer[( y<<5 )+x] = (TPT8 + 16);
            }
            ++x;
            m >>= 1;
         }
      }
      ++y;
      x = 0;
   }
   fir_icon_color_pos(cursor_p->fir_cur_col);

   return cursor_p;
}


/*---------------------------------------------------*
 *函数功能: 绘制(显示)已读入内存的光(图)标文件.      *
 *参数说明: Cursor_ptr cursor_p:指向                 *
 *          构体cursor_p                             *
 *          x,y:要显示的位置坐标                     *
 *返回说明: 无.              　　　　　　　　　　　  *
 *备    注: 用户程序可以直接调用.　　　    　　　    *
 *---------------------------------------------------*/
void blit_icon(Cursor_ptr cursor_p, int x, int y)
{
   int i, j;
   unsigned int color;

   if (g_color_depth == 8)
   {
      #ifndef NEO_color_depth_8_unused
      for(i=0; i<32; ++i)
      {
         for(j=0; j<32; j+=2)
         {
            if ((color=cursor_p->buffer[(i<<5)+j])  != (TPT8 + 16)) dot(x + j, y + i, color);
            if ((color=cursor_p->buffer[(i<<5)+j+1])!=(TPT8 + 16)) dot(x + j + 1,y + i, color);
         }
      }
      #else
      x += 0;
      y += 0;
      cursor_p += 0;
      #endif
   }
   #ifndef NEO_color_depth_16_unused
   else if (g_color_depth == 15 || g_color_depth == 16)
   {
      for(i = 0; i < 32; ++i)
      {
         for(j = 0; j < 32; ++j)
         {
            if ((cursor_p->buffer[(i<<5)+j]) != (TPT8 + 16))
            {
               dot(x + j, y + i, cursor_p->color64k[cursor_p->buffer[(i << 5) + j]]);
            }
         }
      }
   }
   #else
   x += 0;
   y += 0;
   cursor_p += 0;
   #endif
}
#endif


#endif
