当前位置:   article > 正文

T3D图形库(四)_t3d, 8cxvun0002

t3d, 8cxvun0002

 DDraw及图形算法库文件部分

 

  1. /*2008.9.16
  2. T3D图形库
  3. ——<<windows游戏
  4. 编程大师技巧>>
  5. */
  6. //DDraw_lib.cpp
  7. // INCLUDES ///
  8. #include <windows.h>
  9. #include <windowsx.h>
  10. #include <mmsystem.h> //多媒体API
  11. #include <iostream.h>
  12. #include <conio.h>    //控制台IO支持
  13. #include <stdlib.h>   //声明定义的一些常用标准函数库
  14. #include <malloc.h>   //声明或定义一些内存的函数
  15. #include <memory.h>   //提供了内存操作相关的一些函数及声明
  16. #include <string.h>   //字符串的一些功能
  17. #include <stdarg.h>   //应付可变参数
  18. #include <stdio.h>    //efinitions/declarations for standard I/O routines
  19. #include <math.h>     //一些数学方法
  20. #include <io.h>       //declarations for low-level file handling and I/O functions
  21. #include <fcntl.h>    //文件控制操作
  22. #include <sys/timeb.h>//附加的日期和时间定义
  23. #include <time.h>     //时间操作函数库
  24. #include <ddraw.h>
  25. #include "DDraw_lib.h"
  26. // DEFINES 
  27. // TYPES //
  28. // PROTOTYPES /
  29. // EXTERNALS /
  30. extern HWND main_window_handle;
  31. extern HINSTANCE main_instance;
  32. // GLOBALS 
  33. FILE *fp_error = NULL;
  34. char error_filename[80];
  35. //DirectDraw 接口指针
  36. LPDIRECTDRAW7         lpdd =NULL;
  37. LPDIRECTDRAWSURFACE7  lpddsprimary =NULL;
  38. LPDIRECTDRAWSURFACE7  lpddsback =NULL;
  39. LPDIRECTDRAWPALETTE   lpddpal =NULL;
  40. LPDIRECTDRAWCLIPPER   lpddclipper =NULL;
  41. LPDIRECTDRAWCLIPPER   lpddclipperwin =NULL;
  42. PALETTEENTRY          palette[MAX_COLORS_PALETTE];
  43. PALETTEENTRY          save_palette[MAX_COLORS_PALETTE];
  44. DDSURFACEDESC2        ddsd;
  45. DDBLTFX               ddbltfx;
  46. DDSCAPS2              ddscaps;
  47. HRESULT               ddrval;
  48. UCHAR                 *primary_buffer = NULL;   //主缓冲
  49. UCHAR                 *back_buffer    = NULL;   //后备缓冲
  50. int                   primary_lpitch  = 0;      //主缓冲内存行距
  51. int                   back_lpitch     = 0;      //后备缓冲内存行距
  52. BITMAP_FILE           bitmap8bit;
  53. BITMAP_FILE           bitmap16bit;
  54. BITMAP_FILE           bitmap24bit;
  55. DWORD                 start_clock_count = 0;
  56. int                   windowed_mode     = FALSE;
  57. //裁剪矩形
  58. int min_clip_x = 0,
  59.     max_clip_x = (SCREEN_WIDTH-1),
  60.     min_clip_y = 0,
  61.     max_clip_y = (SCREEN_HEIGHT-1);
  62. //屏幕相关信息,被DDraw_Init()重写
  63. int screen_width    =SCREEN_WIDTH,
  64.     screen_height   =SCREEN_HEIGHT,
  65.     screen_bpp      =SCREEN_BPP,
  66.     screen_windowed =0;
  67. int dd_pixel_format =DD_PIXEL_FORMAT565;  //默认像素格式
  68. int window_client_x0  = 0;  //DirectDraw下窗口模式客户区起始地址坐标
  69. int window_client_y0  = 0;
  70. float cos_look[361];  //存储相应角度对应的弧度
  71. float sin_look[361];
  72. //函数指针
  73. USHORT (*RGB16Bit)(int r,int g,int b) =NULL;
  74. // FUNCTIONS //
  75. USHORT RGB16Bit565(int r,int g,int b)
  76. {
  77.   r>>=3; g>>=2; b>>=3;
  78.   return(_RGB16BIT565((r),(g),(b)));
  79. }
  80. USHORT RGB16Bit555(int r, int g, int b)
  81. {
  82.   r>>=3; g>>=3; b>>=3;
  83.   return(_RGB16BIT555((r),(g),(b)));
  84. }
  85. inline void Mem_Set_WORD(void *dest,USHORT data,int count)
  86. {
  87.   //把无符号16位data数据分count次传输到dest地址
  88.   _asm
  89.   {
  90.     mov edi,dest ;
  91.     mov ecx,count;
  92.     mov ax, data ;
  93.     rep stosw    ;
  94.   }
  95. }
  96. inline void Mem_Set_QUAD(void *dest, UINT data, int count)
  97. {
  98.   //把无符号32位data数据分count次传输到dest地址
  99.   _asm
  100.   {
  101.     mov edi, dest ;
  102.     mov ecx, count;
  103.     mov eax, data ;
  104.     rep stosd     ;
  105.   }
  106. }
  107. LPDIRECTDRAWSURFACE7 DDraw_Create_Surface(int width, int height, 
  108.                                           int mem_flags/* =0 */
  109.                                           USHORT color_key_value/* =0 */)
  110. {
  111.   DDSURFACEDESC2 ddsd;
  112.   LPDIRECTDRAWSURFACE7 lpdds;
  113.   DDRAW_INIT_STRUCT(ddsd);  //初始化ddsd
  114.   ddsd.dwFlags=DDSD_CAPS | DDSD_WIDTH | DDSD_HEIGHT; //设置有效标志
  115.   
  116.   ddsd.dwWidth=width;
  117.   ddsd.dwHeight=height;
  118.   ddsd.ddsCaps.dwCaps=DDSCAPS_OFFSCREENPLAIN | mem_flags; //设置属性
  119.   
  120.   if(FAILED(lpdd->CreateSurface(&ddsd,&lpdds,NULL)))  //创造表面
  121.     return(NULL);
  122.   DDCOLORKEY color_key;
  123.   color_key.dwColorSpaceLowValue=color_key_value;
  124.   color_key.dwColorSpaceHighValue=color_key_value;
  125.   
  126.   lpdds->SetColorKey(DDCKEY_SRCBLT,&color_key);   //设置透明色键
  127.   return(lpdds);
  128. }
  129. int DDraw_Init(int width, int height, int bpp, int windowed)
  130. {
  131.   int index;
  132.   if(FAILED(DirectDrawCreateEx(NULL,(void **)&lpdd,IID_IDirectDraw7,NULL)))
  133.     return(0);
  134.   
  135.   if (windowed)
  136.   {
  137.     //设置协作模式(窗口模式)
  138.     if (FAILED(lpdd->SetCooperativeLevel(main_window_handle,DDSCL_NORMAL)))
  139.       return(0);
  140.   }
  141.   else
  142.   {
  143.     //设置协作模式(全屏模式)
  144.     if (FAILED(lpdd->SetCooperativeLevel(main_window_handle,
  145.                 DDSCL_ALLOWMODEX | DDSCL_FULLSCREEN |
  146.                 DDSCL_EXCLUSIVE | DDSCL_ALLOWMODEX | DDSCL_MULTITHREADED)))
  147.       return(0);
  148.     //设置显示模式
  149.     if (FAILED(lpdd->SetDisplayMode(width,height,bpp,0,0)))
  150.       return(0);
  151.   }
  152. //设置全局变量
  153. screen_height  =height;
  154. screen_width   =width ;
  155. screen_bpp     =bpp;
  156. screen_windowed=windowed;
  157. //初始化DDSURFACEDESC2结构体
  158. memset(&ddsd,0,sizeof(ddsd));
  159. ddsd.dwSize=sizeof(ddsd);
  160. if(!screen_windowed)
  161.   {
  162.     //全屏模式
  163.     ddsd.dwFlags = DDSD_CAPS | DDSD_BACKBUFFERCOUNT;
  164.     ddsd.ddsCaps.dwCaps = DDSCAPS_PRIMARYSURFACE | DDSCAPS_FLIP | DDSCAPS_COMPLEX;
  165.     //设置后备缓冲数——窗口模式为0,全屏模式(双缓冲)为1,三缓冲为2
  166.     ddsd.dwBackBufferCount=1;
  167.   }
  168. else
  169.   {
  170.     //窗口模式
  171.     ddsd.dwFlags=DDSD_CAPS;
  172.     ddsd.ddsCaps.dwCaps=DDSCAPS_PRIMARYSURFACE;
  173.     ddsd.dwBackBufferCount=0;
  174.   }
  175.   
  176. //创造主显示表面
  177. lpdd->CreateSurface(&ddsd,&lpddsprimary,NULL);
  178. //取得主显示表面的像素格式
  179. DDPIXELFORMAT ddpf;
  180. //初始化ddpf
  181. DDRAW_INIT_STRUCT(ddpf);
  182. //从主表面取得格式
  183. lpddsprimary->GetPixelFormat(&ddpf);
  184. dd_pixel_format=ddpf.dwRGBBitCount;
  185. Write_Error("/npixel format = %d",dd_pixel_format);
  186. //确定16位RGB格式(1.5.5.5或5.6.5)
  187. if (dd_pixel_format==DD_PIXEL_FORMAT555)
  188.   {
  189.     RGB16Bit = RGB16Bit555;
  190.     Write_Error("/npixel format = 5.5.5");
  191.   }
  192. else
  193.   {
  194.     RGB16Bit = RGB16Bit565;
  195.     Write_Error("/npixel format = 5.6.5");
  196.   }
  197. if (!screen_windowed)
  198.   {//全屏模式下需要一个后备缓冲
  199.     ddscaps.dwCaps=DDSCAPS_BACKBUFFER;
  200.     if(FAILED(lpddsprimary->GetAttachedSurface(&ddscaps,&lpddsback)))
  201.       return(0);
  202.   }
  203. else
  204.   {//否则创造一个离屏表面
  205.     lpddsback=DDraw_Create_Surface(width,height);
  206.   }
  207. //创造一个调色板(仅适用8位模式)
  208. if (screen_bpp=DD_PIXEL_FORMAT8)
  209.   {
  210.     memset(palette,0,MAX_COLORS_PALETTE*sizeof(PALETTEENTRY));
  211.     //从文件中加载调色板项到palette
  212.     Load_Palette_From_File(DEFAULT_PALETTE_FILE,palette);
  213.     if (screen_windowed)
  214.     { 
  215.       //窗口模式,则调色板前/后10个索引设置为windows桌面颜色
  216.       for (index=0;index<10;index++)
  217.         palette[index].peFlags=palette[index+246].peFlags=PC_EXPLICIT;
  218.       //创建调色板接口lpddpal(不允许256个索引)
  219.       if(FAILED(lpdd->CreatePalette(DDPCAPS_8BIT | DDPCAPS_INITIALIZE,
  220.                                     palette,&lpddpal,NULL)))
  221.         return(0);  
  222.     }
  223.     else
  224.     {
  225.       //全屏模式
  226.       if(FAILED(lpdd->CreatePalette(DDPCAPS_8BIT | DDPCAPS_INITIALIZE | DDPCAPS_ALLOW256,
  227.                                     palette,&lpddpal,NULL)))
  228.         return(0);  
  229.     }
  230.     //将调色板接口关联到主显示表面
  231.     if(FAILED(lpddsprimary->SetPalette(lpddpal)))
  232.       return(0);
  233.   }
  234.   
  235. //清空主/从显示表面
  236. if (screen_windowed)
  237.   {
  238.      DDraw_Fill_Surface(lpddsback,0);
  239.   }
  240. else
  241.   {
  242.     DDraw_Fill_Surface(lpddsprimary,0);
  243.     DDraw_Fill_Surface(lpddsback,0);
  244.   }
  245. //设置裁剪矩形(软件模拟算法时用)
  246. min_clip_x = 0;
  247. max_clip_x = screen_width-1;
  248. min_clip_y = 0;
  249. max_clip_y = screen_height-1;
  250. //设置后备缓冲裁剪矩形(用于接口)
  251. RECT screen_rect = { 0,0,screen_width,screen_height };
  252. //创建后备缓冲裁剪器
  253. if(FAILED(lpddclipper = DDraw_Attach_Clipper(lpddsback,1,&screen_rect)))
  254.   return(0);
  255. //创建窗口模式裁剪器
  256. if (screen_windowed)
  257.   {
  258.     if(FAILED(lpdd->CreateClipper(0,&lpddclipperwin,NULL)))
  259.       return(0);
  260.     if(FAILED(lpddclipperwin->SetHWnd(0,main_window_handle)))
  261.       return(0);
  262.     if(FAILED(lpddsprimary->SetClipper(lpddclipperwin)))
  263.       return(0);
  264.   }
  265. return(1);
  266. }
  267. int DDraw_Shutdown(void)
  268. {
  269.   //释放申请的directdraw资源
  270.   //首先释放裁剪器
  271.   if(lpddclipper)
  272.     lpddclipper->Release();
  273.   if(lpddclipperwin)
  274.     lpddclipperwin->Release();
  275.   //释放调色板
  276.   if(lpddpal)
  277.     lpddpal->Release();
  278.   //释放后备缓冲
  279.   if(lpddsback)
  280.     lpddsback->Release();
  281.   //释放主缓冲
  282.   if(lpddsprimary)
  283.     lpddsprimary->Release();
  284.   //释放directdraw对象
  285.   if(lpdd)
  286.     lpdd->Release();
  287.   return(1);
  288. }
  289. LPDIRECTDRAWCLIPPER DDraw_Attach_Clipper(LPDIRECTDRAWSURFACE7 lpdds, 
  290.                                          int num_rects,
  291.                                          LPRECT clip_list)
  292. {
  293.   int index;
  294.   LPDIRECTDRAWCLIPPER lpddclipper;
  295.   LPRGNDATA region_data;
  296.   
  297.   //创建裁剪器对象
  298.   if(FAILED(lpdd->CreateClipper(0,&lpddclipper,NULL)))
  299.     return(0);
  300.   //创建裁剪序列
  301.   region_data = (LPRGNDATA)malloc(sizeof(RGNDATAHEADER)+num_rects*sizeof(RECT));
  302.   memcpy(region_data->Buffer,clip_list,sizeof(RECT)*num_rects);
  303.   region_data->rdh.dwSize        =sizeof(RGNDATAHEADER);
  304.   region_data->rdh.iType         =RDH_RECTANGLES;
  305.   region_data->rdh.nCount        =num_rects;
  306.   region_data->rdh.nRgnSize      =num_rects*sizeof(RECT);
  307.   region_data->rdh.rcBound.left  =64000;
  308.   region_data->rdh.rcBound.top   =64000;
  309.   region_data->rdh.rcBound.right =-64000;
  310.   region_data->rdh.rcBound.bottom=-64000;
  311.   for (index=0; index<num_rects; index++)
  312.     {
  313.       //在所有RECT周围创建一个边界框并存储在rcBound中
  314.     if (clip_list[index].left < region_data->rdh.rcBound.left)
  315.        region_data->rdh.rcBound.left = clip_list[index].left;
  316.     if (clip_list[index].right > region_data->rdh.rcBound.right)
  317.        region_data->rdh.rcBound.right = clip_list[index].right;
  318.     if (clip_list[index].top < region_data->rdh.rcBound.top)
  319.        region_data->rdh.rcBound.top = clip_list[index].top;
  320.     if (clip_list[index].bottom > region_data->rdh.rcBound.bottom)
  321.        region_data->rdh.rcBound.bottom = clip_list[index].bottom;
  322.     } 
  323.   //将裁减序列发送给裁剪器
  324.   if (FAILED(lpddclipper->SetClipList(region_data,0)))
  325.   {
  326.     free(region_data);
  327.     return(NULL);
  328.   }
  329.   //将裁剪器与表面相关联
  330.   if (FAILED(lpdds->SetClipper(lpddclipper)))
  331.   {
  332.     free(region_data);
  333.     return(NULL);
  334.   }
  335.   free(region_data);
  336.   return(lpddclipper);
  337. }
  338. int DDraw_Flip(void)
  339. {
  340.   //此函数切换主显示表面和第二表面(这里是后备缓冲)
  341.   //测试表面是否被锁定
  342.   if (primary_buffer||back_buffer)
  343.     return(0);
  344.   if(!screen_windowed)
  345.     while (FAILED(lpddsprimary->Flip(NULL,DDFLIP_WAIT)));
  346.   else
  347.   {
  348.     RECT dest_rect;
  349.     //取得窗口矩形
  350.     GetWindowRect(main_window_handle,&dest_rect);
  351.     //确定窗口客户区坐标
  352.     dest_rect.left   +=window_client_x0;
  353.     dest_rect.top    +=window_client_y0;
  354.     dest_rect.right  +=dest_rect.left+screen_width;
  355.     dest_rect.bottom +=dest_rect.top+screen_height;
  356.     //将后备缓冲blit到主缓冲的目标矩形内
  357.     if(FAILED(lpddsprimary->Blt(&dest_rect,lpddsback,NULL,DDBLT_WAIT,NULL)))
  358.       return(0);
  359.   }
  360.   
  361.   return(1);
  362. }
  363. int DDraw_Wait_For_Vsync(void)
  364. {
  365.   //等待垂直刷新
  366.   lpdd->WaitForVerticalBlank(DDWAITVB_BLOCKEND,0);
  367.   return(1);
  368. }
  369. int DDraw_Fill_Surface(LPDIRECTDRAWSURFACE7 lpdds, USHORT color, RECT *client/* =NULL */)
  370. {
  371.   DDBLTFX ddbltfx;
  372.   DDRAW_INIT_STRUCT(ddbltfx);
  373.   ddbltfx.dwFillColor=color;
  374.   //向目标表面的目标矩形(null为整个表面)填充颜色
  375.   lpdds->Blt(client,
  376.             NULL,
  377.             NULL,
  378.             DDBLT_WAIT | DDBLT_COLORFILL,
  379.             &ddbltfx);
  380.   return(1);
  381. }
  382. UCHAR* DDraw_Lock_Surface(LPDIRECTDRAWSURFACE7 lpdds,int *lpitch)
  383. {
  384.   //锁定表面
  385.   //如果表面无效
  386.   if(!lpdds)
  387.     return(NULL);
  388.   //表面有效,则锁定之
  389.   DDRAW_INIT_STRUCT(ddsd);
  390.   lpdds->Lock(NULL,&ddsd,DDLOCK_WAIT | DDLOCK_SURFACEMEMORYPTR,NULL);
  391.   if(lpitch)
  392.     *lpitch = ddsd.lPitch;
  393.   //返回指向表面初始地址的指针
  394.   return((UCHAR*)ddsd.lpSurface);
  395. }
  396. int DDraw_Unlock_Surface(LPDIRECTDRAWSURFACE7 lpdds)
  397. {
  398.   //解锁表面
  399.   if(!lpdds)
  400.     return(0);
  401.   lpdds->Unlock(NULL);
  402.   return(1);
  403. }
  404. UCHAR* DDraw_Lock_Primary_Surface(void)
  405. {
  406.   //如果已经被锁定(主缓冲首地址存在)
  407.   if (primary_buffer)
  408.   {
  409.     return(primary_buffer);
  410.   }
  411.   DDRAW_INIT_STRUCT(ddsd);
  412.   lpddsprimary->Lock(NULL,&ddsd,DDLOCK_SURFACEMEMORYPTR | DDLOCK_WAIT,NULL);
  413.   primary_buffer = (UCHAR*)ddsd.lpSurface;
  414.   primary_lpitch = ddsd.lPitch;
  415.   return(primary_buffer);
  416. }
  417. int DDraw_Unlock_Primary_Surface(void)
  418. {
  419.   //解锁主显示表面
  420.   if (!primary_buffer)
  421.     return(0);
  422.   lpddsprimary->Unlock(NULL);
  423.   primary_buffer = NULL;
  424.   primary_lpitch = 0;
  425.   return(1);
  426. UCHAR* DDraw_Lock_Back_Surface(void)
  427. {
  428.   //锁定后备显示表面
  429.   if (back_buffer)
  430.   {
  431.     return(back_buffer);
  432.   }
  433.   DDRAW_INIT_STRUCT(ddsd);
  434.   lpddsback->Lock(NULL,&ddsd,DDLOCK_WAIT | DDLOCK_SURFACEMEMORYPTR,NULL);
  435.   back_buffer=(UCHAR*)ddsd.lpSurface;
  436.   back_lpitch=ddsd.lPitch;
  437.   return(back_buffer);
  438. }
  439. int DDraw_Unlock_Back_Surface(void)
  440. {
  441.   //解锁后备显示表面
  442.   if (!back_buffer)
  443.     return(0);
  444.   lpddsback->Unlock(NULL);
  445.   back_buffer=NULL;
  446.   back_lpitch=0;
  447.   return(1);
  448. }
  449. DWORD Get_Clock(void)
  450. {
  451.   //返回当前时间片
  452.   return(GetTickCount());
  453. }
  454. DWORD Start_Clock(void)
  455. {
  456.   //记录开始时间
  457.   return(start_clock_count=Get_Clock());
  458. }
  459. DWORD Wait_Clock(DWORD count)
  460. {
  461.   while((Get_Clock() - start_clock_count)<count);
  462.   return(Get_Clock());
  463. }
  464. Draw_Clip_Line16(int x0,int y0,int x1,int y1,int color,
  465.                  UCHAR* dest_buffer,int lpitch)
  466. {
  467.   //画经裁剪的直线(16位)
  468.   int cxs,cys,cxe,cye;
  469.   cxs=x0;
  470.   cys=y0;
  471.   cxe=x1;
  472.   cye=y1;
  473.   if(Clip_Line(cxs,cys,cxe,cye))
  474.     Draw_Line16(cxs,cys,cxe,cye,color,dest_buffer,lpitch);
  475.   return(1);
  476. }
  477. Draw_Clip_Line(int x0,int y0,int x1,int y1,int color,
  478.                  UCHAR* dest_buffer,int lpitch)
  479. {
  480.   //画经裁剪的直线(8位)
  481.   int cxs,cys,cxe,cye;
  482.   cxs=x0;
  483.   cys=y0;
  484.   cxe=x1;
  485.   cye=y1;
  486.   if(Clip_Line(cxs,cys,cxe,cye))
  487.     Draw_Line(cxs,cys,cxe,cye,color,dest_buffer,lpitch);
  488.   return(1);
  489. }
  490. Clip_Line(int &x1,int &y1,int &x2,int &y2)
  491. {
  492.   //裁剪直线
  493.   #define CLIP_CODE_C 0x0000
  494.   #define CLIP_CODE_N 0x0008
  495.   #define CLIP_CODE_S 0x0004
  496.   #define CLIP_CODE_E 0x0002
  497.   #define CLIP_CODE_W 0x0001
  498.   #define CLIP_CODE_NE 0x000a
  499.   #define CLIP_CODE_SE 0x0006
  500.   #define CLIP_CODE_NW 0x0009
  501.   #define CLIP_CODE_SW 0x0005
  502.   int xc1=x1,
  503.       yc1=y1,
  504.       xc2=x2,
  505.       yc2=y2;
  506.   
  507.   int p1_code=0,
  508.       p2_code=0;
  509.   //确定两点的位置
  510.   if(y1<min_clip_y)
  511.     p1_code|=CLIP_CODE_N;
  512.   else
  513.   if(y1>max_clip_y)
  514.     p1_code|=CLIP_CODE_S;
  515.   if(x1<min_clip_x)
  516.     p1_code|=CLIP_CODE_W;
  517.   else
  518.   if(x1>max_clip_x)
  519.     p1_code|=CLIP_CODE_E;
  520.   if(y2<min_clip_y)
  521.     p2_code|=CLIP_CODE_N;
  522.   else
  523.   if(y2>max_clip_y)
  524.     p2_code|=CLIP_CODE_S;
  525.   if(x2<min_clip_x)
  526.     p2_code|=CLIP_CODE_W;
  527.   else
  528.   if(x2>max_clip_x)
  529.     p2_code|=CLIP_CODE_E;
  530.   //若两点在剪切区域外且在同一方向
  531.   if((p1_code&p2_code))
  532.     return(0);
  533.   //若两点都在剪切区域内
  534.   if(p1_code==0&&p2_code==0)
  535.     return(1);
  536.   switch(p1_code)
  537.   {
  538.   case CLIP_CODE_C: break;
  539.   case CLIP_CODE_N:
  540.     {
  541.       yc1=min_clip_y;
  542.       xc1=x1+(min_clip_y-y1)*(x2-x1)/(y2-y1);
  543.     }break;
  544.   case CLIP_CODE_S:
  545.     {
  546.       yc1=max_clip_y;
  547.       xc1=x1+(max_clip_y-y1)*(x2-x1)/(y2-y1);
  548.     }break;
  549.   case CLIP_CODE_W:
  550.     {
  551.       xc1=min_clip_x;
  552.       yc1=y1+(min_clip_x-x1)*(y2-y1)/(x2-x1);
  553.     }break;
  554.   case CLIP_CODE_E:
  555.     {
  556.       xc1=max_clip_x;
  557.       yc1=y1+(max_clip_x-x1)*(y2-y1)/(x2-x1);
  558.     }break;
  559.   case CLIP_CODE_NE:
  560.     {
  561.       yc1=min_clip_y;
  562.       xc1=x1+(min_clip_y-y1)*(x2-x1)/(y2-y1);
  563.       if(xc1<min_clip_x||xc1>max_clip_x)
  564.       {
  565.         xc1=max_clip_x;
  566.         yc1=y1+(max_clip_x-x1)*(y2-y1)/(x2-x1);
  567.       }
  568.     }break;
  569.   case CLIP_CODE_SE:
  570.     {
  571.       yc1=max_clip_y;
  572.       xc1=x1+(max_clip_y-y1)*(x2-x1)/(y2-y1);
  573.       if(xc1<min_clip_x||xc1>max_clip_x)
  574.       {
  575.         xc1=max_clip_x;
  576.         yc1=y1+(max_clip_x-x1)*(y2-y1)/(x2-x1);
  577.       }
  578.     }break;
  579.   case CLIP_CODE_NW:
  580.     {
  581.       yc1=min_clip_y;
  582.       xc1=x1+(min_clip_y-y1)*(x2-x1)/(y2-y1);
  583.       if(xc1<min_clip_x||xc1>max_clip_x)
  584.       {
  585.         xc1=min_clip_x;
  586.         yc1=y1+(min_clip_x-x1)*(y2-y1)/(x2-x1);
  587.       }
  588.     }break;
  589.   case CLIP_CODE_SW:
  590.     {
  591.       yc1=max_clip_y;
  592.       xc1=x1+(max_clip_y-y1)*(x2-x1)/(y2-y1);
  593.       if(xc1<min_clip_x||xc2>max_clip_x)
  594.       {
  595.         xc1=min_clip_x;
  596.         yc1=y1+(min_clip_x-x1)*(y2-y1)/(x2-x1);
  597.       }
  598.     }break;
  599.     
  600.   default:break;
  601.     
  602.   }
  603.   switch(p2_code)
  604.   {
  605.   case CLIP_CODE_C: break;
  606.   case CLIP_CODE_N:
  607.     {
  608.       yc2=min_clip_y;
  609.       xc2=x2+(min_clip_y-y2)*(x2-x1)/(y2-y1);
  610.     }break;
  611.   case CLIP_CODE_S:
  612.     {
  613.       yc2=max_clip_y;
  614.       xc2=x2+(max_clip_y-y2)*(x2-x1)/(y2-y1);
  615.     }break;
  616.   case CLIP_CODE_W:
  617.     {
  618.       xc2=min_clip_x;
  619.       yc2=y2+(min_clip_x-x2)*(y2-y1)/(x2-x1);
  620.     }break;
  621.   case CLIP_CODE_E:
  622.     {
  623.       xc2=max_clip_x;
  624.       yc2=y2+(max_clip_x-x2)*(y2-y1)/(x2-x1);
  625.     }break;
  626.   case CLIP_CODE_NE:
  627.     {
  628.       yc2=min_clip_y;
  629.       xc2=x2+(min_clip_y-y2)*(x2-x1)/(y2-y1);
  630.       if(xc2<min_clip_x||xc2>max_clip_x)
  631.       {
  632.         xc2=max_clip_x;
  633.         yc2=y2+(max_clip_x-x2)*(y2-y1)/(x2-x1);
  634.       }
  635.     }break;
  636.   case CLIP_CODE_SE:
  637.     {
  638.       yc2=max_clip_y;
  639.       xc2=x2+(max_clip_y-y2)*(x2-x1)/(y2-y1);
  640.       if(xc2<min_clip_x||xc2>max_clip_x)
  641.       {
  642.         xc2=max_clip_x;
  643.         yc2=y2+(max_clip_x-x2)*(y2-y1)/(x2-x1);
  644.       }
  645.     }break;
  646.   case CLIP_CODE_NW:
  647.     {
  648.       yc2=min_clip_y;
  649.       xc2=x2+(min_clip_y-y2)*(x2-x1)/(y2-y1);
  650.       if(xc2<min_clip_x||xc2>max_clip_x)
  651.       {
  652.         xc2=min_clip_x;
  653.         yc2=y2+(min_clip_x-x2)*(y2-y1)/(x2-x1);
  654.       }
  655.     }break;
  656.   case CLIP_CODE_SW:
  657.     {
  658.       yc2=max_clip_y;
  659.       xc2=x2+(max_clip_y-y2)*(x2-x1)/(y2-y1);
  660.       if(xc2<min_clip_x||xc2>max_clip_x)
  661.       {
  662.         xc2=min_clip_x;
  663.         yc2=y2+(min_clip_x-x2)*(y2-y1)/(x2-x1);
  664.       }
  665.     }break;
  666.     
  667.   default:break;    
  668.   }
  669.   if( (xc1<min_clip_x)||(xc1>max_clip_x)||
  670.     (yc1<min_clip_y)||(yc1>max_clip_y)||
  671.     (xc2<min_clip_x)||(xc2>max_clip_x)||
  672.     (yc2<min_clip_y)||(yc2>max_clip_y) )
  673.   {//若经过裁剪仍有点在剪切区域外,
  674.    //则剪切区域内不存在要画的直线
  675.     return (0);
  676.   }
  677.   //否则修改直线的两个端点坐标
  678.   x1=xc1;
  679.   y1=yc1;
  680.   x2=xc2;
  681.   y2=yc2;
  682.   return (1);
  683. }
  684. int Draw_Line(int x0,int y0,
  685.               int x1,int y1,
  686.               int color,
  687.               UCHAR* vb_start,int lpitch)
  688. {/*Bresenham算法画线*/
  689.   int dx,
  690.       dy,
  691.       dx2,
  692.       dy2,
  693.       x_inc,
  694.       y_inc,
  695.       error,
  696.       index;
  697.   //取得直线的第一个点(像素)
  698.   vb_start=vb_start+x0+y0*lpitch;
  699.   dx=x1-x0;
  700.   dy=y1-y0;
  701.   if(dx>=0)
  702.     x_inc=1;
  703.   else
  704.   {
  705.     x_inc=-1;
  706.     dx=-dx;
  707.   }
  708.   
  709.   if(dy>=0)
  710.     y_inc=lpitch;
  711.   else
  712.   {
  713.     y_inc=-lpitch;
  714.     dy=-dy;
  715.   }
  716.   dx2=dx<<1;
  717.   dy2=dy<<1;
  718.   if(dx>dy)
  719.   {/*斜率<1的情况*/
  720.     error=dy2-dx;
  721.     for(index=0;index<=dx;index++)
  722.     {
  723.       *vb_start=color;
  724.       if(error>=0)
  725.       {
  726.         error-=dx2;
  727.         vb_start+=y_inc;  
  728.       }
  729.         error+=dy2;
  730.         vb_start+=x_inc;
  731.     }
  732.   }
  733.   else
  734.   {/*斜率>1的情况*/
  735.     error=dx2-dy;
  736.     for(index=0;index<=dy;index++)
  737.     {
  738.       *vb_start=color;
  739.       if(error>=0)
  740.       {
  741.         error-=dy2;
  742.         vb_start+=x_inc;
  743.       }
  744.       error+=dx2;
  745.       vb_start+=y_inc;
  746.     }
  747.   }
  748.   
  749.   return(1);
  750. }
  751. int Draw_Line16(int x0, int y0,
  752.                 int x1,int y1, 
  753.                 int color,
  754.                 UCHAR *vb_start,int lpitch)
  755. {
  756.   int dx,
  757.       dy,
  758.       dx2,
  759.       dy2,
  760.       x_inc,
  761.       y_inc,
  762.       error,
  763.       index;
  764.   //将字节间距转换为USHORT间距
  765.   int lpitch_2 = lpitch>>1;
  766.   //确定直线首地址
  767.   USHORT* vb_start2=(USHORT*)vb_start + x0 + y0*lpitch_2;
  768.   dx = x1 - x0;
  769.   dy = y1 - y0;
  770.   
  771.   if (dx>=0)
  772.   {
  773.     x_inc = 1;
  774.   }
  775.   else
  776.   {
  777.     x_inc = -1;
  778.     dx = -dx;
  779.   }
  780.   if (dy>=0)
  781.   {
  782.     y_inc = lpitch_2;
  783.   }
  784.   else
  785.   {
  786.     y_inc = -lpitch_2;
  787.     dy = -dy;
  788.   }
  789.   dx2 = dx<<1;
  790.   dy2 = dy<<1;
  791.   if (dx>dy)
  792.   {
  793.     //斜率小于1的情况
  794.     error = dy2 - dx;
  795.     for (index=0;index<=dx;index++)
  796.     {
  797.       //设置像素
  798.       *vb_start2 = (USHORT)color;
  799.       if (error>=0)
  800.       {
  801.         error-=dx2;
  802.         vb_start2+=y_inc;
  803.       }
  804.       error+=dy2;
  805.       vb_start2+=x_inc;
  806.     }
  807.   }
  808.   else
  809.   {
  810.     //斜率大于1的情况
  811.     error = dx2 -dy;
  812.     for (index=0;index<=dy;index++)
  813.     {
  814.       *vb_start2 = (USHORT)color;
  815.       if (error>=0)
  816.       {
  817.         error-=dy2;
  818.         vb_start2+=x_inc;
  819.       }
  820.       error+=dx2;
  821.       vb_start2+=y_inc;
  822.     }
  823.   }
  824.   return(1);
  825. }
  826. int Draw_Pixel(int x, int y,int color,
  827.                UCHAR *video_buffer, int lpitch)
  828. {
  829.   //画像素
  830.   video_buffer[x+y*lpitch] = color;
  831.   return(1);
  832. }
  833. int Draw_Pixel16(int x, int y,int color,
  834.                UCHAR *video_buffer, int lpitch)
  835. {
  836.   ((USHORT*)video_buffer)[x+y*(lpitch>>1)] = color;
  837.   return(1);
  838. }
  839. int Draw_Rectangle(int x1, int y1, int x2, int y2, int color,
  840.                    LPDIRECTDRAWSURFACE7 lpdds)
  841. {
  842.   //填充矩形
  843.   DDBLTFX ddbltfx;
  844.   //目标矩形
  845.   RECT fill_area;
  846.   DDRAW_INIT_STRUCT(ddbltfx);
  847.   //填充颜色
  848.   ddbltfx.dwFillColor = color;
  849.   //y1>y2?x1>x2?
  850.   fill_area.top    = y1;
  851.   fill_area.left   = x1;
  852.   fill_area.bottom = y2;
  853.   fill_area.right  = x2;
  854.   lpdds->Blt(&fill_area,
  855.              NULL,
  856.              NULL,
  857.              DDBLT_COLORFILL | DDBLT_WAIT,
  858.              &ddbltfx);
  859.   return(1);
  860. }
  861. int Set_Palette_Entry(int color_index, LPPALETTEENTRY color)
  862. {
  863.   //更改调色板相应索引号的颜色
  864.   lpddpal->SetEntries(0,color_index,1,color);
  865.   //更改调色板对象数组
  866.   memcpy(&palette[color_index],color,sizeof(PALETTEENTRY));
  867.   return(1);
  868. }
  869. int Get_Palette_Entry(int color_index, LPPALETTEENTRY color)
  870. {
  871.   //取得调色板索引对应的palette存放在color地址处
  872.   memcpy(color,&palette[color_index],sizeof(PALETTEENTRY));
  873.   return(1);
  874. }
  875. int Load_Palette_From_File(char *filename, LPPALETTEENTRY palette)
  876. {
  877.   FILE *fp_file;  //文件指针
  878.   if((fp_file=fopen(filename,"r"))==NULL)   //以'读'模式打开文件
  879.     return(0);
  880.   for (int index=0; index<MAX_COLORS_PALETTE;index++)
  881.   {
  882.     //从文件中读出R.G.B.F值赋给palette对象
  883.     fscanf(fp_file,"%d %d %d %d",&palette[index].peRed,
  884.                                  &palette[index].peGreen,
  885.                                  &palette[index].peBlue,
  886.                                  &palette[index].peFlags);
  887.   }
  888.   fclose(fp_file);
  889.   return(1);
  890. }
  891. int Save_Palette_To_File(char *filename, LPPALETTEENTRY palette)
  892. {
  893.   FILE* fp_file;
  894.   if((fp_file=fopen(filename,"w"))==NULL)   //以"写"方式打开文件
  895.     return(0);
  896.   for (int index=0;index<MAX_COLORS_PALETTE;index++)
  897.   {
  898.     fprintf(fp_file,"/n%d %d %d %d",palette[index].peRed,
  899.                                     palette[index].peGreen,
  900.                                     palette[index].peBlue,
  901.                                     palette[index].peFlags);
  902.   }
  903.   fclose(fp_file);
  904.   return(1);
  905. }
  906. int Save_Palette(LPPALETTEENTRY sav_palette)
  907. {
  908.   //保存palette对象至sav_palette对象
  909.   memcpy(sav_palette,palette,MAX_COLORS_PALETTE*sizeof(PALETTEENTRY));
  910.   return(1);
  911. }
  912. int Set_Palette(LPPALETTEENTRY set_palette)
  913. {
  914.   //设置调色板
  915.   //更改palette对象
  916.   memcpy(palette,set_palette,MAX_COLORS_PALETTE*sizeof(PALETTEENTRY));
  917.   //更改与显示表面关联的调色板项
  918.   lpddpal->SetEntries(0,0,MAX_COLORS_PALETTE,palette);
  919.   return(1);
  920. }
  921. int Rotate_Colors(int start_index, int end_index)
  922. {
  923.   //取得需改变的调色板项数
  924.   int colors = end_index -start_index + 1;
  925.   PALETTEENTRY work_pal[MAX_COLORS_PALETTE];
  926.   //取得需改变的调色板项存放在work_pal对象中
  927.   lpddpal->GetEntries(0,start_index,colors,work_pal);
  928.   //调色板项右移一位(最后一位放置第一位)
  929.   lpddpal->SetEntries(0,start_index+1,colors-1,work_pal);
  930.   lpddpal->SetEntries(0,start_index,1,&work_pal[colors-1]);
  931.   //更新palette对象
  932.   lpddpal->GetEntries(0,0,MAX_COLORS_PALETTE,palette);
  933.   return(1);
  934. }
  935. int Blink_Colors(int command, BLINKER_PTR new_light, int id)
  936. {
  937.   //闪烁像素
  938.   static BLINKER lights[256];
  939.   static int initialized = 0;
  940.   if (!initialized)
  941.   {
  942.     initialized = 1;
  943.     memset((void*)lights,0,sizeof(lights));
  944.   }
  945.   switch(command)
  946.   {
  947.   case BLINKER_ADD :
  948.     {
  949.       for (int index=0;index<256;index++)
  950.       {
  951.         if (lights[index].state==0)
  952.         {
  953.           lights[index] = *new_light;
  954.           lights[index].counter = 0;
  955.           lights[index].state = -1;   //初始化为关(灯)
  956.           lpddpal->SetEntries(0,lights[index].color_index,1,&lights[index].off_color);
  957.           return(index);
  958.         }
  959.       }
  960.     } break;
  961.   case BLINKER_DELETE:
  962.     {
  963.       //删除闪烁灯
  964.       if (lights[id].state!=0)
  965.       {
  966.         memset((void*)&lights[id],0,sizeof(BLINKER));
  967.         return(id);
  968.       }
  969.       else
  970.         return(-1);
  971.     } break;
  972.   case BLINKER_UPDATE:
  973.     {
  974.       //更新闪烁灯
  975.       if (lights[id].state!=0)
  976.       {
  977.         lights[id].on_color = new_light->on_color;
  978.         lights[id].off_color = new_light->off_color;
  979.         lights[id].on_time   = new_light->on_time;
  980.         lights[id].off_time  = new_light->off_time;
  981.         if (lights[id].state==-1)
  982.           lpddpal->SetEntries(0,lights[id].color_index,1,&lights[id].off_color);
  983.         else
  984.           lpddpal->SetEntries(0,lights[id].color_index,1,&lights[id].on_color);
  985.         return(id);
  986.       }
  987.       else
  988.         return(-1);
  989.     } break;
  990.   case BLINKER_RUN:
  991.     {
  992.       //运行闪烁灯
  993.       for (int index=0;index<256;index++)
  994.       {
  995.         if (lights[index].state==-1)
  996.         { 
  997.           //如果闪烁灯是关着的
  998.           if (++lights[index].counter>=lights[index].off_time)
  999.           {
  1000.             //当计数器超过预定的关灯时间
  1001.             lights[index].counter = 0;    //计数器清零
  1002.             lights[index].state = - lights[index].state;    //改变灯的开关状态
  1003.             lpddpal->SetEntries(0,lights[index].color_index,1,&lights[index].on_color);
  1004.           }
  1005.         }
  1006.         else if (lights[index].state ==1)
  1007.         {
  1008.           if (++lights[index].counter >= lights[index].on_time)
  1009.           {
  1010.             lights[index].counter = 0;
  1011.             lights[index].state = -lights[index].state;
  1012.             lpddpal->SetEntries(0,lights[index].color_index,1,&lights[index].off_color);
  1013.           }
  1014.         }
  1015.       }
  1016.     } break;
  1017.     
  1018.   }//end switch
  1019.   return(1);
  1020. }
  1021. int Draw_Text_GDI(char *text, int x,int y,COLORREF color, LPDIRECTDRAWSURFACE7 lpdds)
  1022. {
  1023.   //传入COLORREF结构
  1024.   
  1025.   HDC xdc;
  1026.   if(FAILED(lpdds->GetDC(&xdc)))
  1027.     return(0);
  1028.   SetTextColor(xdc,color);
  1029.   SetBkMode(xdc,TRANSPARENT);
  1030.   TextOut(xdc,x,y,text,strlen(text));
  1031.   lpdds->ReleaseDC(xdc);
  1032.   return(1);
  1033. }
  1034. int Draw_Text_GDI(char *text, int x,int y,int color, LPDIRECTDRAWSURFACE7 lpdds)
  1035. {
  1036.   //传入颜色索引
  1037.   
  1038.   HDC xdc;
  1039.   if(FAILED(lpdds->GetDC(&xdc)))
  1040.     return(0);
  1041.   SetTextColor(xdc,RGB(palette[color].peRed,palette[color].peGreen,palette[color].peBlue) );
  1042.   SetBkMode(xdc,TRANSPARENT);
  1043.   TextOut(xdc,x,y,text,strlen(text));
  1044.   lpdds->ReleaseDC(xdc);
  1045.   return(1);
  1046. }
  1047. int Open_Error_File(char *filename, FILE *fp_override/* =NULL */)
  1048. {
  1049.   //打开误差文件
  1050.   if (fp_override)
  1051.   { //如果误差文件是打开的
  1052.     fp_error = fp_override;
  1053.   }
  1054.   else
  1055.   { 
  1056.     //误差文件没打开,则打开它
  1057.     if ((fp_error = fopen(filename,"w"))==NULL)
  1058.       return(0);
  1059.   }
  1060.   struct _timeb timebuffer;
  1061.   char *timeline;
  1062.   char timestring[280];
  1063.   _ftime(&timebuffer);
  1064.   timeline = ctime(&(timebuffer.time));   //ctime()将本地时间格式化为字符串,保存在timeline地址处
  1065.   //先输出timeline地址处的前19位,在加上.毫秒数,最后加上年份
  1066.   sprintf(timestring,"%.19s.%hu,%s",timeline,timebuffer.millitm,&timeline[20]);
  1067.   Write_Error("/nOpening Error Output File (%s) on %s/n",filename,timestring);
  1068.   if (!fp_override)
  1069.   {
  1070.     //为什么要重新打开? 也许是想把文件指针定位在文件末尾
  1071.     fclose(fp_error);
  1072.     //'a+' 读写方式打开,将文件指针指向文件末尾。如果文件不存在则尝试创建之。
  1073.     if ((fp_error = fopen(filename,"a+"))==NULL)
  1074.       return(0);
  1075.   }
  1076.   return(1);
  1077. }
  1078. int Close_Error_File(void)
  1079. {
  1080.   //关闭误差文件
  1081.   if (fp_error)
  1082.   {
  1083.     Write_Error("/nClosing Error Output File.");
  1084.     if (fp_error!=stdout || fp_error!=stderr) //?
  1085.     {
  1086.       fclose(fp_error);
  1087.     }
  1088.     fp_error = NULL;
  1089.     return(1);
  1090.   }
  1091.   else
  1092.     return(0);
  1093. }
  1094. int Write_Error(char *string, ...)
  1095. {
  1096.   //写入误差文件
  1097.   char buffer[80];
  1098.   va_list arglist;
  1099.   if(!string || !fp_error)
  1100.     return(0);
  1101.   va_start(arglist,string);
  1102.   vsprintf(buffer,string,arglist);
  1103.   va_end(arglist);
  1104.   fprintf(fp_error,buffer);
  1105.   fflush(fp_error);
  1106.   return(1);
  1107. }
  1108. int Load_Bitmap_File(BITMAP_FILE_PTR bitmap, char *filename)
  1109. {
  1110.   int file_handle,
  1111.       index;
  1112.   UCHAR *temp_buffer = NULL;
  1113.   OFSTRUCT file_data;   
  1114.   
  1115.   if((file_handle = OpenFile(filename,&file_data,OF_READ))==-1)
  1116.     return(0);
  1117.   //读位图文件头
  1118.   _lread(file_handle,&bitmap->bitmapfileheader,sizeof(BITMAPFILEHEADER));
  1119.   //bmp文件标志 'bm'(0x4D42)
  1120.   if (bitmap->bitmapfileheader.bfType!=BITMAP_ID)
  1121.   {
  1122.     _lclose(file_handle);
  1123.     return(0);
  1124.   }
  1125.   //读信息头结构
  1126.   _lread(file_handle,&bitmap->bitmapinfoheader,sizeof(BITMAPINFOHEADER));
  1127.   //如果位图有调色板则加载它
  1128.   if (bitmap->bitmapinfoheader.biBitCount == 8)
  1129.   {
  1130.     _lread(file_handle,&bitmap->palette,MAX_COLORS_PALETTE*sizeof(PALETTEENTRY));
  1131.     for (index=0;index<MAX_COLORS_PALETTE;index++)
  1132.     {
  1133.       //位图图像调色板数据格式为(B.G.R)
  1134.       BYTE temp_color = bitmap->palette[index].peRed;
  1135.       bitmap->palette[index].peRed = bitmap->palette[index].peBlue;
  1136.       bitmap->palette[index].peBlue = temp_color;
  1137.       bitmap->palette[index].peFlags = PC_NOCOLLAPSE;
  1138.     }
  1139.   }
  1140.   
  1141.   //定位文件指针(定位到文件末再向上移动biSizeImage字节)
  1142.   _lseek(file_handle,-(int)(bitmap->bitmapinfoheader.biSizeImage),SEEK_END);
  1143.   //位图像素格式为8位或16位
  1144.   if (bitmap->bitmapinfoheader.biBitCount==8 || bitmap->bitmapinfoheader.biBitCount==16)
  1145.   {
  1146.     //16位难道不用对调 R&B ??
  1147.     if (bitmap->buffer)
  1148.     {
  1149.       free(bitmap->buffer);
  1150.     }
  1151.     if (!(bitmap->buffer = (UCHAR*)malloc(bitmap->bitmapinfoheader.biSizeImage)))
  1152.     {
  1153.       _lclose(file_handle);
  1154.       return(0);
  1155.     }
  1156.     
  1157.     //读位图数据到bitmap对象的缓冲区
  1158.     _lread(file_handle,bitmap->buffer,bitmap->bitmapinfoheader.biSizeImage);
  1159.   }
  1160.   else
  1161.   if (bitmap->bitmapinfoheader.biBitCount==24)
  1162.   {
  1163.     //取得位图数据大小并为其开辟内存 首地址置于临时缓冲区
  1164.     if (!(temp_buffer = (UCHAR*)malloc(bitmap->bitmapinfoheader.biSizeImage)))
  1165.     {
  1166.       _lclose(file_handle);
  1167.       return(0);
  1168.     }
  1169.     
  1170.     //开辟16位位图数据区首地址置于bitmap对象的缓冲区(biWidth/biHeight以像素为单位)
  1171.     if (!(bitmap->buffer=(UCHAR*)malloc(2*bitmap->bitmapinfoheader.biWidth*bitmap->bitmapinfoheader.biHeight)))
  1172.     {
  1173.       _lclose(file_handle);
  1174.       free(temp_buffer);
  1175.       return(0);
  1176.     }
  1177.     
  1178.     //位图数据copy到临时缓冲区
  1179.     _lread(file_handle,temp_buffer,bitmap->bitmapinfoheader.biSizeImage);
  1180.     for (index=0;index<bitmap->bitmapinfoheader.biWidth*bitmap->bitmapinfoheader.biHeight;index++)
  1181.     {
  1182.       USHORT color;
  1183.       //位图图像数据
  1184.       if (dd_pixel_format==DD_PIXEL_FORMAT555)
  1185.       {
  1186.         UCHAR blue  = (temp_buffer[index*3+0]>>3),
  1187.               green = (temp_buffer[index*3+1]>>3),
  1188.               red  = (temp_buffer[index*3+2]>>3);
  1189.         color = _RGB16BIT555(red,green,blue);
  1190.       } 
  1191.       else
  1192.       if (dd_pixel_format==DD_PIXEL_FORMAT565)
  1193.       {
  1194.         UCHAR blue  = (temp_buffer[index*3+0]>>3),
  1195.               green = (temp_buffer[index*3+1]>>2),
  1196.               red   = (temp_buffer[index*3+2]>>3);
  1197.         color = _RGB16BIT565(red,green,blue);
  1198.       }
  1199.       
  1200.       ((USHORT*)bitmap->buffer)[index] = color;
  1201.      }// end for index
  1202.     bitmap->bitmapinfoheader.biBitCount = 16;
  1203.     free(temp_buffer);
  1204.   }// end if 24 bit
  1205.   else
  1206.   {
  1207.     return(0);
  1208.   }
  1209. #if 0
  1210. // write the file info out 
  1211. printf("/nfilename:%s /nsize=%d /nwidth=%d /nheight=%d /nbitsperpixel=%d /ncolors=%d /nimpcolors=%d",
  1212.         filename,
  1213.         bitmap->bitmapinfoheader.biSizeImage,
  1214.         bitmap->bitmapinfoheader.biWidth,
  1215.         bitmap->bitmapinfoheader.biHeight,
  1216.         bitmap->bitmapinfoheader.biBitCount,
  1217.         bitmap->bitmapinfoheader.biClrUsed,
  1218.         bitmap->bitmapinfoheader.biClrImportant);
  1219. #endif
  1220.   _lclose(file_handle);
  1221.   //颠倒bitmap对象中的位图数据
  1222.   Flip_Bitmap(bitmap->buffer,
  1223.               bitmap->bitmapinfoheader.biWidth*(bitmap->bitmapinfoheader.biBitCount/8),
  1224.               bitmap->bitmapinfoheader.biHeight);
  1225.   return(1);
  1226. }
  1227. int Unload_Bitmap_File(BITMAP_FILE_PTR bitmap)
  1228. {
  1229.   if (bitmap->buffer)
  1230.   {
  1231.     free(bitmap->buffer);
  1232.     
  1233.     bitmap->buffer = NULL;
  1234.   }
  1235.   return(1);
  1236. }
  1237. int Flip_Bitmap(UCHAR *image, int bytes_per_line, int height)
  1238. {
  1239.   //颠倒位图数据
  1240.   UCHAR *buffer;
  1241.   int index;
  1242.   if(!(buffer = (UCHAR*)malloc(bytes_per_line*height)))
  1243.     return(0);
  1244.   memcpy(buffer,image,bytes_per_line*height);
  1245.   for (index=0;index<height;index++)
  1246.   {
  1247.     memcpy(&image[((height-1)-index)*bytes_per_line],
  1248.            &buffer[index*bytes_per_line],bytes_per_line);
  1249.   }
  1250.   free(buffer);
  1251.   buffer = NULL;
  1252.   
  1253.   return(1);
  1254. }
  1255. int Create_Bitmap(BITMAP_IMAGE_PTR image, int x, int y, int width, int height, int bpp/* =8 */)
  1256. {
  1257.   //创建一个宽width高height色深为bpp在屏幕(x,y)处的空的位图图像
  1258.   if(!(image->buffer = (UCHAR*)malloc(width*height*(bpp>>3))))
  1259.     return(0);
  1260.   image->state     = BITMAP_STATE_ALIVE;
  1261.   image->attr      = 0;
  1262.   image->width     = width;
  1263.   image->height    = height;
  1264.   image->bpp       = bpp;
  1265.   image->x         = x;
  1266.   image->y         = y;
  1267.   image->num_bytes = width*height*(bpp>>3);
  1268.   memset(image->buffer,0,image->num_bytes);
  1269.   return(1);
  1270. }
  1271. int Destroy_Bitmap(BITMAP_IMAGE_PTR image)
  1272. {
  1273.   //销毁位图图像
  1274.   
  1275.   if (image && image->buffer)
  1276.   {
  1277.     free(image->buffer);
  1278.     image->buffer = NULL;
  1279.     memset(image,0,sizeof(BITMAP_IMAGE));
  1280.     return(1);
  1281.   }
  1282.   else
  1283.     return(0);
  1284. }
  1285. int Draw_Bitmap(BITMAP_IMAGE_PTR source_bitmap,UCHAR *dest_buffer, int lpitch, int transparent)
  1286. {
  1287.   //绘制位图
  1288.   //当创建好一个大小指定内容为空的位图内存区后从位图文件的缓冲区中读入指定的位图图像数据与空内存区
  1289.   //然后将此内存区的位图图像经过本函数绘制在指定区域(dest_buffer)
  1290.   //位图是否被加载
  1291.   if (!(source_bitmap->attr & BITMAP_ATTR_LOADED))
  1292.     return(0);
  1293.   UCHAR *dest_addr,    //目标地址
  1294.         *source_addr;  //源地址
  1295.   UCHAR pixel;
  1296.   int index,
  1297.       pixel_x;
  1298.   dest_addr = dest_buffer + source_bitmap->y*lpitch + source_bitmap->x;
  1299.   source_addr =source_bitmap->buffer;
  1300.   if (transparent)
  1301.   { 
  1302.     //如果位图图像透明,则逐字节copy,此处height/width单位为像素
  1303.     for (index=0;index<source_bitmap->height;index++)
  1304.     {
  1305.       for (pixel_x=0;pixel_x<source_bitmap->width;pixel_x++)
  1306.       {
  1307.         if ((pixel = source_addr[pixel_x])!=0)
  1308.             dest_addr[pixel_x]=pixel;
  1309.       }
  1310.       dest_addr +=lpitch;                   //目标地址向下移动一行
  1311.       source_addr += source_bitmap->width;  //源地址(位图图像)向下移动一行
  1312.     }
  1313.   }
  1314.   else
  1315.   {
  1316.     //位图不透明的情况则逐行copy
  1317.     for (index=0;index<source_bitmap->height;index++)
  1318.     {
  1319.       memcpy(dest_addr,source_addr,source_bitmap->width);
  1320.       dest_addr  +=lpitch;
  1321.       source_addr+=source_bitmap->width;
  1322.     }
  1323.   }
  1324.   return(1);
  1325.     
  1326. }
  1327. int Draw_Bitmap16(BITMAP_IMAGE_PTR source_bitmap,UCHAR *dest_buffer, int lpitch, int transparent)
  1328. {
  1329.   //绘制位图(16位)
  1330.   //当创建好一个大小指定内容为空的位图内存区后从位图文件的缓冲区中读入指定的位图图像数据与空内存区
  1331.   //然后将此内存区的位图图像经过本函数绘制在指定区域(dest_buffer)
  1332.   //位图是否被加载
  1333.   if (!(source_bitmap->attr & BITMAP_ATTR_LOADED))
  1334.     return(0);
  1335.   USHORT *dest_addr,       //目标地址
  1336.          *source_addr;     //源地址
  1337.   USHORT  pixel;
  1338.   int index,
  1339.       pixel_x,
  1340.       lpitch_2 = lpitch >> 1;
  1341.   dest_addr = ((USHORT*)dest_buffer) + source_bitmap->y*lpitch_2 + source_bitmap->x;
  1342.   source_addr = (USHORT*) source_bitmap->buffer;
  1343.   if (transparent)
  1344.   { 
  1345.     //如果位图图像透明,则逐字节copy,此处height/width单位为像素
  1346.     for (index=0;index<source_bitmap->height;index++)
  1347.     {
  1348.       for (pixel_x=0;pixel_x<source_bitmap->width;pixel_x++)
  1349.       {
  1350.         if ((pixel = source_addr[pixel_x])!=0)
  1351.             dest_addr[pixel_x]=pixel;
  1352.       }
  1353.       dest_addr +=lpitch;                   //目标地址向下移动一行
  1354.       source_addr += source_bitmap->width;  //源地址(位图图像)向下移动一行
  1355.     }
  1356.   }
  1357.   else
  1358.   {
  1359.     //位图不透明的情况则逐行copy
  1360.     int source_bytes_per_line = source_bitmap->width*2;
  1361.     for (index=0;index<source_bitmap->height;index++)
  1362.     {
  1363.       memcpy(dest_addr,source_addr,source_bytes_per_line);
  1364.       dest_addr  +=lpitch_2;
  1365.       source_addr+=source_bitmap->width;
  1366.     }
  1367.   }
  1368.   return(1);
  1369.     
  1370. }
  1371. int Load_Image_Bitmap(BITMAP_IMAGE_PTR image,BITMAP_FILE_PTR bitmap,int cx,int cy,int mode)
  1372. {
  1373.   //此函数从一个位图文件对象(BITMAP_FILE)的buffer区读入位图图像数据至image对象的buffer区
  1374.   //如果没有创建位图图像内存区(BITMAP_IMAGE)
  1375.   if(!image)
  1376.     return(0);
  1377.   UCHAR *source_ptr,
  1378.         *dest_ptr;
  1379.   if (mode==BITMAP_EXTRACT_MODE_CELL)
  1380.   {
  1381.     //如果是位图图像模板模式则计算选择的目标图像的实际坐标
  1382.     cx = cx*(image->width+1) + 1;
  1383.     cy = cy*(image->height+1) +1;
  1384.   }
  1385.   source_ptr = bitmap->buffer + cy*bitmap->bitmapinfoheader.biWidth+cx;
  1386.   dest_ptr = (UCHAR*) image->buffer;
  1387.   for (int index_y=0;index_y<image->height;index_y++)
  1388.   {
  1389.     memcpy(dest_ptr,source_ptr,image->width);
  1390.     dest_ptr   += image->width;
  1391.     source_ptr += bitmap->bitmapinfoheader.biWidth;
  1392.   }
  1393.   image->attr |=BITMAP_ATTR_LOADED;
  1394.  return(1);
  1395. }
  1396. int Load_Image_Bitmap16(BITMAP_IMAGE_PTR image,BITMAP_FILE_PTR bitmap,int cx,int cy,int mode)
  1397. {
  1398.   //此函数从一个位图文件对象(BITMAP_FILE)的buffer区读入位图图像数据至image对象的buffer区(16位)
  1399.   //如果没有创建位图图像内存区(BITMAP_IMAGE)
  1400.   if(!image)
  1401.     return(0);
  1402.   USHORT *source_ptr,
  1403.          *dest_ptr;
  1404.   if (mode==BITMAP_EXTRACT_MODE_CELL)
  1405.   {
  1406.     //如果是位图图像模板模式则计算选择的目标图像的实际坐标
  1407.     cx = cx*(image->width+1) + 1;
  1408.     cy = cy*(image->height+1) +1;
  1409.   }
  1410.   source_ptr =(USHORT*)bitmap->buffer + cy*bitmap->bitmapinfoheader.biWidth+cx;
  1411.   dest_ptr = (USHORT*) image->buffer;
  1412.   int bytes_per_line = image->width*2;
  1413.   for (int index_y=0;index_y<image->height;index_y++)
  1414.   {
  1415.     memcpy(dest_ptr,source_ptr,bytes_per_line);
  1416.     dest_ptr   += image->width;
  1417.     source_ptr += bitmap->bitmapinfoheader.biWidth;
  1418.   }
  1419.   image->attr |=BITMAP_ATTR_LOADED;
  1420.  return(1);
  1421. }
  1422. int Scroll_Bitmap(BITMAP_IMAGE_PTR image, int dx, int dy/* =0 */)
  1423. {
  1424.   //卷动位图图像(自适应8位和16位)
  1425.   BITMAP_IMAGE temp_image;  //临时位图图像对象
  1426.   if (!image || (dx==0 && dy==0))
  1427.     return(0);
  1428.   if (dx!=0)
  1429.   {
  1430.     dx %= image->width;
  1431.     if (dx>0)
  1432.     {
  1433.       //向右卷动
  1434.       //创建一个宽dx,高height的位图图像
  1435.       Create_Bitmap(&temp_image,0,0,dx,image->height,image->bpp);
  1436.       
  1437.       //将源位图图像从(width-dx,0)坐标开始,copy宽为dx高为height的图像数据至临时位图图像
  1438.       Copy_Bitmap(&temp_image,0,0,
  1439.                   image,image->width-dx,0,
  1440.                   dx,image->height);
  1441.       UCHAR *source_ptr = image->buffer;
  1442.       int shift         = (image->bpp>>3)*dx;  //适应8/16位
  1443.       for (int y=0;y<image->height;y++)
  1444.       {
  1445.         //从source_ptr地址向右移动(width-dx)个像素至source_ptr+shift地址处    
  1446.         memmove(source_ptr+shift,source_ptr,(image->width-dx)*(image->bpp>>3));
  1447.         source_ptr+=((image->bpp>>3)*image->width);
  1448.       }
  1449.       
  1450.       //将临时位图图像的数据copy回源位图图像
  1451.       Copy_Bitmap(image,0,0,&temp_image,0,0,dx,image->height);
  1452.     }
  1453.     else
  1454.     {
  1455.        // 向左卷动
  1456.       dx = -dx; 
  1457.       Create_Bitmap(&temp_image, 0, 0, dx, image->height, image->bpp);
  1458.       Copy_Bitmap(&temp_image,0,0, 
  1459.                   image, 0,0, 
  1460.                   dx, image->height);
  1461.      UCHAR *source_ptr = image->buffer;  
  1462.      int shift         = (image->bpp >> 3)*dx;
  1463.      for (int y=0; y < image->height; y++)
  1464.       {
  1465.         memmove(source_ptr, source_ptr+shift, (image->width-dx)*(image->bpp >> 3));
  1466.         source_ptr+=((image->bpp >> 3)*image->width);
  1467.       } // end for
  1468.    
  1469.      Copy_Bitmap(image, image->width-dx,0, &temp_image,0,0, 
  1470.                dx, image->height);     
  1471.     }
  1472.   }
  1473.   
  1474.   return(1);
  1475. }
  1476. int Copy_Bitmap(BITMAP_IMAGE_PTR dest_bitmap, int dest_x, int dest_y, 
  1477.                 BITMAP_IMAGE_PTR source_bitmap, int source_x, int source_y,
  1478.                 int width, int height)
  1479. {
  1480.   //copy源位图指定坐标位置开始宽width高height到指定位图图像的指定位置
  1481.   //同时满足8位和16位
  1482.   if (!dest_bitmap || !source_bitmap)
  1483.     return(0);
  1484.   //每像素的字节数
  1485.   int bytes_per_pixel = (source_bitmap->bpp >> 3);
  1486.   UCHAR* source_ptr = source_bitmap->buffer + (source_x+source_y*source_bitmap->width)*bytes_per_pixel;
  1487.   UCHAR* dest_ptr = dest_bitmap->buffer + (dest_x + dest_y*dest_bitmap->width)*bytes_per_pixel;
  1488.   for (int y=0;y<height;y++)
  1489.   {
  1490.     memcpy(dest_ptr,source_ptr,bytes_per_pixel*width);
  1491.     source_ptr += (source_bitmap->width*bytes_per_pixel);
  1492.     dest_ptr   += (dest_bitmap->width*bytes_per_pixel);
  1493.   }
  1494.   return(1);
  1495. }
  1496. void HLine16(int x1,int x2,int y,int color, UCHAR *vbuffer, int lpitch)
  1497. {
  1498.   //画从(x1,y)至(x2,y)颜色为color的直线(16位)
  1499.   int temp;
  1500.   USHORT *vbuffer2 = (USHORT*)vbuffer;
  1501.   lpitch = lpitch >> 1;
  1502.   if (y>max_clip_y || y<min_clip_y)
  1503.       return;
  1504.   if (x1>x2)
  1505.   {
  1506.     temp = x1;
  1507.     x1 = x2;
  1508.     x2 = temp;
  1509.   }
  1510.   if (x1>max_clip_x || x2<min_clip_x)
  1511.     return;
  1512.   x1 = ((x1<min_clip_x)?min_clip_x:x1);
  1513.   x2 = ((x2>max_clip_x)?max_clip_x:x2);
  1514.   Mem_Set_WORD((vbuffer2+(y*lpitch)+x1),color,x2-x1+1);
  1515. }
  1516. void HLine(int x1,int x2,int y,int color, UCHAR *vbuffer, int lpitch)
  1517. {
  1518.   //画从(x1,y)至(x2,y)颜色为color的直线(8位)
  1519.   int temp;
  1520.   lpitch = lpitch >> 1;
  1521.   if (y>max_clip_y || y<min_clip_y)
  1522.       return;
  1523.   if (x1>x2)
  1524.   {
  1525.     temp = x1;
  1526.     x1 = x2;
  1527.     x2 = temp;
  1528.   }
  1529.   if (x1>max_clip_x || x2<min_clip_x)
  1530.     return;
  1531.   x1 = ((x1<min_clip_x)?min_clip_x:x1);
  1532.   x2 = ((x2>max_clip_x)?max_clip_x:x2);
  1533.   memset((UCHAR*)(vbuffer+(y*lpitch)+x1),(UCHAR)color,x2-x1+1);
  1534. }
  1535. void VLine16(int y1,int y2,int x,int color, UCHAR *vbuffer, int lpitch)
  1536. {
  1537.   //画从(x,y1)至(x,y2)的颜色为color的直线(16位)
  1538.   USHORT *start_offset;
  1539.   int index,
  1540.       temp;
  1541.   lpitch = lpitch >>1;
  1542.   if (x>max_clip_x || x<min_clip_x)
  1543.     return;
  1544.   if (y1>y2)
  1545.   {
  1546.     temp = y1;
  1547.     y1 = y2;
  1548.     y2 = temp;
  1549.   }
  1550.   if (y1>max_clip_y || y2<min_clip_y)
  1551.     return;
  1552.   y1 = ((y1<min_clip_y)?min_clip_y:y1);
  1553.   y2 = ((y2>max_clip_y)?max_clip_y:y2);
  1554.   start_offset = (USHORT*)vbuffer + (y1*lpitch) + x;
  1555.   for (index=0;index<=y2-y1;index++)
  1556.   {
  1557.     *start_offset = color;
  1558.     start_offset += lpitch;
  1559.   }
  1560. }
  1561. void VLine(int y1,int y2,int x,int color, UCHAR *vbuffer, int lpitch)
  1562. {
  1563.   //画从(x,y1)至(x,y2)的颜色为color的直线(8位)
  1564.   UCHAR *start_offset;
  1565.   int index,
  1566.       temp;
  1567.   if (x>max_clip_x || x<min_clip_x)
  1568.     return;
  1569.   if (y1>y2)
  1570.   {
  1571.     temp = y1;
  1572.     y1 = y2;
  1573.     y2 = temp;
  1574.   }
  1575.   if (y1>max_clip_y || y2<min_clip_y)
  1576.     return;
  1577.   y1 = ((y1<min_clip_y)?min_clip_y:y1);
  1578.   y2 = ((y2>max_clip_y)?max_clip_y:y2);
  1579.   start_offset = vbuffer + (y1*lpitch) + x;
  1580.   for (index=0;index<=y2-y1;index++)
  1581.   {
  1582.     *start_offset = (UCHAR)color;
  1583.     start_offset += lpitch;
  1584.   }
  1585. }
  1586. void Screen_Transitions(int effect, UCHAR *vbuffer, int lpitch)
  1587. {
  1588.   int pal_reg;      //循环变量
  1589.   int index;        //循环变量
  1590.   int red,green,blue;
  1591.   PALETTEENTRY color;
  1592.   PALETTEENTRY work_palette[MAX_COLORS_PALETTE];
  1593.   //PALETTEENTRY work_color;
  1594.   switch(effect)
  1595.   {
  1596.   case SCREEN_DARKNESS:
  1597.     { 
  1598.       //逐渐变暗
  1599.       for (index=0;index<80;index++)
  1600.       {
  1601.         Save_Palette(work_palette);
  1602.         for (pal_reg=1;pal_reg<MAX_COLORS_PALETTE;pal_reg++)
  1603.         {
  1604.           color = work_palette[pal_reg];
  1605.           if (color.peRed>4) color.peRed-=3;
  1606.           else 
  1607.             color.peRed = 0;
  1608.           if (color.peGreen>4) color.peGreen-=3;
  1609.           else
  1610.             color.peGreen = 0;
  1611.           if (color.peBlue>4) color.peBlue-=3;
  1612.           else
  1613.             color.peBlue =0;
  1614.           work_palette[pal_reg] = color;
  1615.         }
  1616.         
  1617.         Set_Palette(work_palette);
  1618.         //等一段时间(让变化看得见)
  1619.         Start_Clock();
  1620.         Wait_Clock(12);
  1621.       }
  1622.       
  1623.     } break;
  1624.   case SCREEN_WHITENESS:
  1625.     {
  1626.       //逐渐变亮    
  1627.       for (index=0;index<64;index++)
  1628.       {
  1629.         Save_Palette(work_palette);
  1630.         for (pal_reg=0;pal_reg<MAX_COLORS_PALETTE;pal_reg++)
  1631.         {
  1632.           color = work_palette[pal_reg];
  1633.           red = color.peRed;
  1634.           green = color.peGreen;
  1635.           blue =color.peBlue;
  1636.           if ((red+=4)>=255)
  1637.             red = 255;
  1638.           if ((green+=4)>=255)
  1639.             green = 255;
  1640.           if ((blue+=4)>=255)
  1641.             blue = 255;
  1642.           color.peRed = red;
  1643.           color.peGreen =green;
  1644.           color.peBlue = blue;
  1645.           work_palette[pal_reg] = color;
  1646.         }
  1647.         Set_Palette(work_palette);
  1648.         Start_Clock();
  1649.         Wait_Clock(12);
  1650.         
  1651.       }
  1652.     } break;
  1653.     
  1654.   case SCREEN_REDNESS:
  1655.     {
  1656.       //逐渐变红
  1657.       for (index=0;index<64;index++)
  1658.       {
  1659.         Save_Palette(work_palette);
  1660.         for (pal_reg=0;pal_reg<MAX_COLORS_PALETTE;pal_reg++)
  1661.         {
  1662.           color = work_palette[pal_reg];
  1663.           red = color.peRed;
  1664.           green = color.peGreen;
  1665.           blue =color.peBlue;
  1666.           if ((red+=6)>=255)
  1667.             red = 255;
  1668.           if ((green-=4)<0)
  1669.             green = 0;
  1670.           if ((blue-=4)<0)
  1671.             blue = 0;
  1672.           color.peRed = red;
  1673.           color.peGreen =green;
  1674.           color.peBlue = blue;
  1675.           work_palette[pal_reg] = color;
  1676.         }
  1677.         Set_Palette(work_palette);
  1678.         Start_Clock();
  1679.         Wait_Clock(12);
  1680.         
  1681.       }
  1682.     } break;
  1683.     
  1684.   case SCREEN_BLUENESS:
  1685.     {
  1686.       //逐渐变蓝
  1687.       for (index=0;index<64;index++)
  1688.       {
  1689.         Save_Palette(work_palette);
  1690.         for (pal_reg=0;pal_reg<MAX_COLORS_PALETTE;pal_reg++)
  1691.         {
  1692.           color = work_palette[pal_reg];
  1693.           red = color.peRed;
  1694.           green = color.peGreen;
  1695.           blue =color.peBlue;
  1696.           if ((red-=4)<0)
  1697.             red = 0;
  1698.           if ((green-=4)<0)
  1699.             green = 0;
  1700.           if ((blue+=6)>=255)
  1701.             blue = 255;
  1702.           color.peRed = red;
  1703.           color.peGreen =green;
  1704.           color.peBlue = blue;
  1705.           work_palette[pal_reg] = color;
  1706.         }
  1707.         Set_Palette(work_palette);
  1708.         Start_Clock();
  1709.         Wait_Clock(12);
  1710.         
  1711.       }
  1712.     } break;
  1713.   case SCREEN_GREENNESS:
  1714.     {
  1715.       //逐渐变绿
  1716.       for (index=0;index<64;index++)
  1717.       {
  1718.         Save_Palette(work_palette);
  1719.         for (pal_reg=0;pal_reg<MAX_COLORS_PALETTE;pal_reg++)
  1720.         {
  1721.           color = work_palette[pal_reg];
  1722.           red = color.peRed;
  1723.           green = color.peGreen;
  1724.           blue =color.peBlue;
  1725.           if ((red-=4)<0)
  1726.             red = 0;
  1727.           if ((green+=6)>=255)
  1728.             green = 255;
  1729.           if ((blue-=4)<0)
  1730.             blue = 0;
  1731.           color.peRed = red;
  1732.           color.peGreen =green;
  1733.           color.peBlue = blue;
  1734.           work_palette[pal_reg] = color;
  1735.         }
  1736.         Set_Palette(work_palette);
  1737.         Start_Clock();
  1738.         Wait_Clock(12);
  1739.         
  1740.       }
  1741.     } break;
  1742.   case SCREEN_SWIPE_X:
  1743.     {
  1744.       //纵向画线(先右后左)
  1745.       
  1746.       for (index=0;index<(screen_width/2);index+=2)
  1747.       {
  1748.         Start_Clock();
  1749.         Wait_Clock(12);
  1750.         if (screen_bpp==8)
  1751.         {
  1752.           //分别从右左两边画两条纵向直线
  1753.           VLine(0,(screen_height-1),(screen_width-1)-index,0,vbuffer,lpitch);
  1754.           VLine(0,(screen_height-1),index,0,vbuffer,lpitch);
  1755.           VLine(0,(screen_height-1),(screen_width-1)-(index+1),0,vbuffer,lpitch);
  1756.           VLine(0,(screen_height-1),index+1,0,vbuffer,lpitch);
  1757.         }
  1758.         else
  1759.         if (screen_bpp==16)
  1760.         {
  1761.           VLine16(0,(screen_height-1),(screen_width-1)-index,0,vbuffer,lpitch);
  1762.           VLine16(0,(screen_height-1),index,0,vbuffer,lpitch);
  1763.           VLine16(0,(screen_height-1),(screen_width-1)-(index+1),0,vbuffer,lpitch);
  1764.           VLine16(0,(screen_height-1),index+1,0,vbuffer,lpitch);
  1765.         }
  1766.           
  1767.       }// end for index
  1768.     } break;
  1769.   case SCREEN_SWIPE_Y:
  1770.     {
  1771.       //横向画线(先下后上)
  1772.       for (index=0;index<(screen_height/2);index+=2)
  1773.       {
  1774.         Start_Clock();
  1775.         Wait_Clock(12);
  1776.         if (screen_bpp==8)
  1777.         {
  1778.           HLine(0,(screen_width-1),(screen_height-1)-index,0,vbuffer,lpitch);
  1779.           HLine(0,(screen_width-1),index,0,vbuffer,lpitch);
  1780.           HLine(0,(screen_width-1),(screen_height-1)-(index+1),0,vbuffer,lpitch);
  1781.           HLine(0,(screen_width-1),index+1,0,vbuffer,lpitch);
  1782.         }
  1783.         else
  1784.         if (screen_bpp==16)
  1785.         {
  1786.           HLine16(0,(screen_width-1),(screen_height-1)-index,0,vbuffer,lpitch);
  1787.           HLine16(0,(screen_width-1),index,0,vbuffer,lpitch);
  1788.           HLine16(0,(screen_width-1),(screen_height-1)-(index+1),0,vbuffer,lpitch);
  1789.           HLine16(0,(screen_width-1),index+1,0,vbuffer,lpitch);
  1790.         }
  1791.           
  1792.       }// end for index
  1793.     } break;
  1794.   case SCREEN_SCRUNCH:
  1795.     {
  1796.       //横向/纵向都会画线
  1797.       for (index=0;index<(screen_width/2);index+=2)
  1798.       {
  1799.         Start_Clock();
  1800.         Wait_Clock(12);
  1801.         if (screen_bpp==8)
  1802.         {
  1803.           //这里取模运算因为索引index可能大于(screen_height/2)
  1804.           HLine(0,(screen_width-1),(screen_height-1)-index%(screen_height/2),0,vbuffer,lpitch);
  1805.           HLine(0,(screen_width-1),index%(screen_height/2),0,vbuffer,lpitch);
  1806.           HLine(0,(screen_width-1),(screen_height-1)-(index%(screen_height/2)+1),0,vbuffer,lpitch);
  1807.           HLine(0,(screen_width-1),index%(screen_height/2)+1,0,vbuffer,lpitch);
  1808.           VLine(0,(screen_height-1),(screen_width-1)-index,0,vbuffer,lpitch);
  1809.           VLine(0,(screen_height-1),index,0,vbuffer,lpitch);
  1810.           VLine(0,(screen_height-1),(screen_width-1)-(index+1),0,vbuffer,lpitch);
  1811.           VLine(0,(screen_height-1),index+1,0,vbuffer,lpitch);  
  1812.         }
  1813.         else
  1814.         if (screen_bpp==16)
  1815.         {
  1816.           HLine16(0,(screen_width-1),(screen_height-1)-index%(screen_height/2),0,vbuffer,lpitch);
  1817.           HLine16(0,(screen_width-1),index%(screen_height/2),0,vbuffer,lpitch);
  1818.           HLine16(0,(screen_width-1),(screen_height-1)-(index%(screen_height/2)+1),0,vbuffer,lpitch);
  1819.           HLine16(0,(screen_width-1),index%(screen_height/2)+1,0,vbuffer,lpitch);
  1820.         
  1821.           VLine16(0,(screen_height-1),(screen_width-1)-index,0,vbuffer,lpitch);
  1822.           VLine16(0,(screen_height-1),index,0,vbuffer,lpitch);
  1823.           VLine16(0,(screen_height-1),(screen_width-1)-(index+1),0,vbuffer,lpitch);
  1824.           VLine16(0,(screen_height-1),index+1,0,vbuffer,lpitch);
  1825.         }
  1826.           
  1827.       } // end for index
  1828.     } break;
  1829.   case SCREEN_DISOLVE:
  1830.     {
  1831.       //一个无聊的效果(溶解)
  1832.       if (screen_bpp==8)
  1833.         for (index=0;index<=screen_width*screen_height*4;index++)
  1834.           Draw_Pixel(rand()%screen_width,rand()%screen_height,0,vbuffer,lpitch);
  1835.       
  1836.       else
  1837.       if (screen_bpp==16)   
  1838.         for (index=0;index<=screen_width*screen_height*4;index++)
  1839.           Draw_Pixel16(rand()%screen_width,rand()%screen_height,0,vbuffer,lpitch);
  1840.     } break;
  1841.   defaultbreak;
  1842.   } //end switch
  1843. }
  1844. int Collision_Test(int x1, int y1, int w1, int h1,
  1845.                    int x2, int y2, int w2, int h2)
  1846. {
  1847.   //碰撞检测(仅适用于矩形)
  1848.   //取得近似宽度/高度一半,为什么近似?嘿嘿 自己想去
  1849.   int width1 = (w1>>1) - (w1>>3);
  1850.   int height1 = (h1>>1) - (h1>>3);
  1851.   int width2 = (w2>>1) - (w2>>3);
  1852.   int height2 = (h2>>1) - (h2>>3);
  1853.   //取得矩形中心坐标
  1854.   int cx1 = x1 + width1;
  1855.   int cy1 = y1 + height1;
  1856.   int cx2 = x2 + width2;
  1857.   int cy2 = y2 + height2;
  1858.   int dx = abs(cx2 - cx1);
  1859.   int dy = abs(cy2 - cy1);
  1860.   //如果碰撞,返回值1
  1861.   if (dx<(width1+width2)&&dy<(height1+height2))
  1862.     return(1);
  1863.   else
  1864.     return(0);
  1865. }
  1866. int Color_Scan(int x1, int y1, int x2, int y2, 
  1867.                UCHAR scan_start, UCHAR scan_end, 
  1868.                UCHAR *scan_buffer, int scan_lpitch)
  1869. {
  1870.   //这个函数实现了一个粗糙的碰撞技术基于扫描一个矩形内的像素颜色
  1871.   //是否在一个指定的颜色范围内
  1872.   //裁剪矩形使之合理
  1873.   if (x1>=screen_width)
  1874.     x1 = screen_width-1;
  1875.   else
  1876.   if (x1<0)
  1877.     x1 = 0;
  1878.   if (x2>=screen_width)
  1879.     x2 = screen_width-1;
  1880.   else
  1881.   if (x2<0)
  1882.     x2 = 0;
  1883.   if (y1>=screen_height)
  1884.     y1 = screen_height-1;
  1885.   else
  1886.   if (y1<0)
  1887.     y1 = 0;
  1888.   if (y2>=screen_height)
  1889.     y2 = screen_height-1;
  1890.   else
  1891.   if (y2<0)
  1892.     y2 = 0;
  1893.   
  1894.   scan_buffer +=  y1*scan_lpitch;
  1895.   for (int scan_y=y1;scan_y<=y2;scan_y++)
  1896.   {
  1897.     //y1<y2,x1<x2? 函数外指定.
  1898.     for (int scan_x=x1;scan_x<=x2;scan_x++)
  1899.     {
  1900.       if (scan_buffer[scan_x]>=scan_start && scan_buffer[scan_x]<=scan_end)
  1901.         return(1);
  1902.     }
  1903.     scan_buffer+=scan_lpitch;
  1904.   }
  1905.    // return failure
  1906.   return(0);
  1907. }
  1908. int Color_Scan16(int x1, int y1, int x2, int y2, 
  1909.                  USHORT scan_start, USHORT scan_end,
  1910.                  UCHAR *scan_buffer, int scan_lpitch)
  1911. {
  1912.   USHORT *scan_buffer2 = (USHORT*)scan_buffer;
  1913.   scan_lpitch = (scan_lpitch>>1);
  1914.   if (x1>=screen_width)
  1915.     x1 = screen_width-1;
  1916.   else
  1917.   if (x1<0)
  1918.     x1 = 0;
  1919.   if (x2>=screen_width)
  1920.     x2 = screen_width-1;
  1921.   else
  1922.   if (x2<0)
  1923.     x2 = 0;
  1924.   if (y1>=screen_height)
  1925.     y1 = screen_height-1;
  1926.   else
  1927.   if (y1<0)
  1928.     y1 = 0;
  1929.   if (y2>=screen_height)
  1930.     y2 = screen_height-1;
  1931.   else
  1932.   if (y2<0)
  1933.     y2 = 0;
  1934.   scan_buffer2 +=y1*scan_lpitch;
  1935.   for (int scan_y=y1;scan_y<=y2;scan_y++)
  1936.   {
  1937.     for (int scan_x=x1;scan_x<=x2;scan_x++)
  1938.     {
  1939.       if (scan_buffer2[scan_x] == scan_start || scan_buffer2[scan_x] == scan_end)
  1940.         return(1);
  1941.     }
  1942.     scan_buffer2+=scan_lpitch;
  1943.   }
  1944.   return(0);
  1945. }
  1946. int Scan_Image_Bitmap(BITMAP_FILE_PTR bitmap, 
  1947.                       LPDIRECTDRAWSURFACE7 lpdds, 
  1948.                       int cx,int cy)
  1949. {
  1950.   //此函数从位图文件中提取出指定位图数据至lpdds目标表面
  1951.   //适用于8位?
  1952.   UCHAR *source_ptr,
  1953.         *dest_ptr;
  1954.   DDSURFACEDESC2 ddsd;
  1955.   ddsd.dwSize = sizeof(ddsd);
  1956.   lpdds->Lock(NULL,
  1957.               &ddsd,
  1958.               DDLOCK_WAIT | DDLOCK_SURFACEMEMORYPTR,
  1959.               NULL);
  1960.   cx = cx*(ddsd.dwWidth+1)+1;
  1961.   cy = cy*(ddsd.dwHeight+1)+1;
  1962.   
  1963.   source_ptr = bitmap->buffer + cy*bitmap->bitmapinfoheader.biWidth+cx;
  1964.   dest_ptr = (UCHAR*)ddsd.lpSurface;
  1965.   for (int index_y=0;index_y<ddsd.dwHeight;index_y++)
  1966.   {
  1967.     memcpy(dest_ptr,source_ptr,ddsd.dwWidth);
  1968.     dest_ptr += (ddsd.lPitch);
  1969.     source_ptr += bitmap->bitmapinfoheader.biWidth;
  1970.   }
  1971.   lpdds->Unlock(NULL);
  1972.   return(1);
  1973. }
  1974. void Draw_Top_Tri(int x1,int y1, 
  1975.                   int x2,int y2, 
  1976.                   int x3,int y3,
  1977.                   int color, 
  1978.                   UCHAR *dest_buffer, int mempitch)
  1979. {
  1980. // 画平顶三角形(8位,精确模式)
  1981. float dx_right,   
  1982.       dx_left,     
  1983.       xs,xe,       
  1984.       height;     
  1985. int temp_x,       
  1986.     temp_y,
  1987.     right,        
  1988.     left;
  1989. UCHAR  *dest_addr = NULL;
  1990. if (x2 < x1)
  1991.    {
  1992.    temp_x = x2;
  1993.    x2     = x1;
  1994.    x1     = temp_x;
  1995.    } 
  1996. height = y3-y1;
  1997. dx_left  = (x3-x1)/height;
  1998. dx_right = (x3-x2)/height;
  1999. xs = (float)x1;
  2000. xe = (float)x2+(float)0.5;
  2001. if (y1 < min_clip_y)
  2002.    {
  2003.    xs = xs+dx_left*(float)(-y1+min_clip_y);
  2004.    xe = xe+dx_right*(float)(-y1+min_clip_y);
  2005.    y1=min_clip_y;
  2006.    } 
  2007. if (y3>max_clip_y)
  2008.    y3=max_clip_y;
  2009. dest_addr = dest_buffer+y1*mempitch;
  2010. if (x1>=min_clip_x && x1<=max_clip_x &
  2011.     x2>=min_clip_x && x2<=max_clip_x &
  2012.     x3>=min_clip_x && x3<=max_clip_x)
  2013.     {
  2014.     for (temp_y=y1; temp_y<=y3; temp_y++,dest_addr+=mempitch)
  2015.         {
  2016.         memset((UCHAR *)dest_addr+(unsigned int)xs,
  2017.                 color,(unsigned int)(xe-xs+1));
  2018.         xs+=dx_left;
  2019.         xe+=dx_right;
  2020.         } 
  2021.     } 
  2022. else
  2023.    {
  2024.    for (temp_y=y1; temp_y<=y3; temp_y++,dest_addr+=mempitch)
  2025.        {
  2026.     
  2027.        left  = (int)xs;
  2028.        right = (int)xe;
  2029.        xs+=dx_left;
  2030.        xe+=dx_right;
  2031.        if (left < min_clip_x)
  2032.           {
  2033.           left = min_clip_x;
  2034.           if (right < min_clip_x)
  2035.              continue;
  2036.           }
  2037.        if (right > max_clip_x)
  2038.           {
  2039.           right = max_clip_x;
  2040.           if (left > max_clip_x)
  2041.              continue;
  2042.           }
  2043.        memset((UCHAR  *)dest_addr+(unsigned int)left,
  2044.               color,(unsigned int)(right-left+1));
  2045.        } // end for
  2046.    } 
  2047. }
  2048. /
  2049. void Draw_Bottom_Tri(int x1,int y1, 
  2050.                      int x2,int y2, 
  2051.                      int x3,int y3,
  2052.                      int color,
  2053.                      UCHAR *dest_buffer, int mempitch)
  2054. {
  2055. // 画平底三角形(8位,精确模式)
  2056. float dx_right,    
  2057.       dx_left,   
  2058.       xs,xe,     
  2059.       height;    
  2060. int temp_x,       
  2061.     temp_y,
  2062.     right,        
  2063.     left;
  2064. UCHAR  *dest_addr;
  2065. if (x3 < x2)
  2066.    {
  2067.    temp_x = x2;
  2068.    x2     = x3;
  2069.    x3     = temp_x;
  2070.    } 
  2071. height = y3-y1;
  2072. dx_left  = (x2-x1)/height;
  2073. dx_right = (x3-x1)/height;
  2074. xs = (float)x1;
  2075. xe = (float)x1; // +(float)0.5;
  2076. if (y1<min_clip_y)
  2077.    {
  2078.    
  2079.    xs = xs+dx_left*(float)(-y1+min_clip_y);
  2080.    xe = xe+dx_right*(float)(-y1+min_clip_y);
  2081.    y1=min_clip_y;
  2082.    } 
  2083. if (y3>max_clip_y)
  2084.    y3=max_clip_y;
  2085. dest_addr = dest_buffer+y1*mempitch;
  2086. if (x1>=min_clip_x && x1<=max_clip_x &
  2087.     x2>=min_clip_x && x2<=max_clip_x &
  2088.     x3>=min_clip_x && x3<=max_clip_x)
  2089.     {
  2090.   
  2091.     for (temp_y=y1; temp_y<=y3; temp_y++,dest_addr+=mempitch)
  2092.         {
  2093.         memset((UCHAR  *)dest_addr+(unsigned int)xs,
  2094.                 color,(unsigned int)(xe-xs+1));
  2095.        
  2096.         xs+=dx_left;
  2097.         xe+=dx_right;
  2098.         } // end for
  2099.     } 
  2100. else
  2101.    {
  2102.    for (temp_y=y1; temp_y<=y3; temp_y++,dest_addr+=mempitch)
  2103.        {
  2104.        left  = (int)xs;
  2105.        right = (int)xe;
  2106.     
  2107.        xs+=dx_left;
  2108.        xe+=dx_right;
  2109.        if (left < min_clip_x)
  2110.           {
  2111.           left = min_clip_x;
  2112.           if (right < min_clip_x)
  2113.              continue;
  2114.           }
  2115.        if (right > max_clip_x)
  2116.           {
  2117.           right = max_clip_x;
  2118.           if (left > max_clip_x)
  2119.              continue;
  2120.           }
  2121.        memset((UCHAR  *)dest_addr+(unsigned int)left,
  2122.               color,(unsigned int)(right-left+1));
  2123.        } // end for
  2124.    } 
  2125. ///
  2126. void Draw_Top_TriFP(int x1,int y1,
  2127.                     int x2,int y2, 
  2128.                     int x3,int y3,
  2129.                     int color, 
  2130.                     UCHAR *dest_buffer, int mempitch)
  2131. {
  2132. //绘制平顶三角形(效率模式)
  2133. int dx_right,    
  2134.     dx_left,     
  2135.     xs,xe,       
  2136.     height;     
  2137. int temp_x,       
  2138.     temp_y,
  2139.     right,        
  2140.     left;
  2141. UCHAR  *dest_addr;
  2142. if (y1==y3 || y2==y3)
  2143.     return;
  2144. if (x2 < x1)
  2145.    {
  2146.    temp_x = x2;
  2147.    x2     = x1;
  2148.    x1     = temp_x;
  2149.    } 
  2150. height = y3-y1;
  2151. dx_left  = ((x3-x1)<<FIXP16_SHIFT)/height;
  2152. dx_right = ((x3-x2)<<FIXP16_SHIFT)/height;
  2153. xs = (x1<<FIXP16_SHIFT);
  2154. xe = (x2<<FIXP16_SHIFT);
  2155. if (y1<min_clip_y)
  2156.    {
  2157.    xs = xs+dx_left*(-y1+min_clip_y);
  2158.    xe = xe+dx_right*(-y1+min_clip_y);
  2159.    y1=min_clip_y;
  2160.    } 
  2161. if (y3>max_clip_y)
  2162.    y3=max_clip_y;
  2163. dest_addr = dest_buffer+y1*mempitch;
  2164. if (x1>=min_clip_x && x1<=max_clip_x &
  2165.     x2>=min_clip_x && x2<=max_clip_x &
  2166.     x3>=min_clip_x && x3<=max_clip_x)
  2167.     {
  2168.     // 绘制三角形
  2169.     for (temp_y=y1; temp_y<=y3; temp_y++,dest_addr+=mempitch)
  2170.         {
  2171.         memset((UCHAR *)dest_addr+((xs+FIXP16_ROUND_UP)>>FIXP16_SHIFT),
  2172.                color, (((xe-xs+FIXP16_ROUND_UP)>>FIXP16_SHIFT)+1));
  2173.         xs+=dx_left;
  2174.         xe+=dx_right;
  2175.         } 
  2176.     } 
  2177. else
  2178.    {
  2179.    for (temp_y=y1; temp_y<=y3; temp_y++,dest_addr+=mempitch)
  2180.        {
  2181.        left  = ((xs+FIXP16_ROUND_UP)>>16);
  2182.        right = ((xe+FIXP16_ROUND_UP)>>16);
  2183.        xs+=dx_left;
  2184.        xe+=dx_right;
  2185.        if (left < min_clip_x)
  2186.           {
  2187.           left = min_clip_x;
  2188.           if (right < min_clip_x)
  2189.              continue;
  2190.           }
  2191.        if (right > max_clip_x)
  2192.           {
  2193.           right = max_clip_x;
  2194.           if (left > max_clip_x)
  2195.              continue;
  2196.           }
  2197.        memset((UCHAR  *)dest_addr+(unsigned int)left,
  2198.               color,(unsigned int)(right-left+1));
  2199.        } // end for
  2200.    } 
  2201. /
  2202. void Draw_Bottom_TriFP(int x1,int y1, 
  2203.                        int x2,int y2, 
  2204.                        int x3,int y3,
  2205.                        int color,
  2206.                        UCHAR *dest_buffer, int mempitch)
  2207. {
  2208. //绘制平底三角形(效率模式)
  2209. int dx_right,    
  2210.     dx_left,    
  2211.     xs,xe,       
  2212.     height;     
  2213. int temp_x,       
  2214.     temp_y,
  2215.     right,         
  2216.     left;
  2217. UCHAR  *dest_addr;
  2218. if (y1==y2 || y1==y3)
  2219.     return;
  2220. if (x3 < x2)
  2221.    {
  2222.    temp_x = x2;
  2223.    x2     = x3;
  2224.    x3     = temp_x;
  2225.    } 
  2226. height = y3-y1;
  2227. dx_left  = ((x2-x1)<<FIXP16_SHIFT)/height;
  2228. dx_right = ((x3-x1)<<FIXP16_SHIFT)/height;
  2229. xs = (x1<<FIXP16_SHIFT);
  2230. xe = (x1<<FIXP16_SHIFT); 
  2231. if (y1<min_clip_y)
  2232.    {
  2233.    xs = xs+dx_left*(-y1+min_clip_y);
  2234.    xe = xe+dx_right*(-y1+min_clip_y);
  2235.    y1=min_clip_y;
  2236.    } 
  2237. if (y3>max_clip_y)
  2238.    y3=max_clip_y;
  2239. dest_addr = dest_buffer+y1*mempitch;
  2240. if (x1>=min_clip_x && x1<=max_clip_x &
  2241.     x2>=min_clip_x && x2<=max_clip_x &
  2242.     x3>=min_clip_x && x3<=max_clip_x)
  2243.     {
  2244.     for (temp_y=y1; temp_y<=y3; temp_y++,dest_addr+=mempitch)
  2245.         {
  2246.         memset((UCHAR *)dest_addr+((xs+FIXP16_ROUND_UP)>>FIXP16_SHIFT),
  2247.                 color, (((xe-xs+FIXP16_ROUND_UP)>>FIXP16_SHIFT)+1));
  2248.         xs+=dx_left;
  2249.         xe+=dx_right;
  2250.         } 
  2251.     } 
  2252. else
  2253.    {
  2254.    for (temp_y=y1; temp_y<=y3; temp_y++,dest_addr+=mempitch)
  2255.        {
  2256.        left  = ((xs+FIXP16_ROUND_UP)>>FIXP16_SHIFT);
  2257.        right = ((xe+FIXP16_ROUND_UP)>>FIXP16_SHIFT);
  2258.        xs+=dx_left;
  2259.        xe+=dx_right;
  2260.        if (left < min_clip_x)
  2261.           {
  2262.           left = min_clip_x;
  2263.           if (right < min_clip_x)
  2264.              continue;
  2265.           }
  2266.        if (right > max_clip_x)
  2267.           {
  2268.           right = max_clip_x;
  2269.           if (left > max_clip_x)
  2270.              continue;
  2271.           }
  2272.        memset((UCHAR *)dest_addr+left,
  2273.               color, (right-left+1));
  2274.        } // end for
  2275.    } 
  2276. }
  2277. void Draw_Top_Tri16(int x1,int y1, 
  2278.                     int x2,int y2, 
  2279.                     int x3,int y3,
  2280.                     int color, 
  2281.                     UCHAR *_dest_buffer, int mempitch)
  2282. {
  2283. // 画平顶三角形(16位,精确模式)
  2284. float dx_right,    
  2285.       dx_left,     
  2286.       xs,xe,       
  2287.       height;   
  2288. int temp_x,        
  2289.     temp_y,
  2290.     right,       
  2291.     left;
  2292. USHORT *dest_buffer = (USHORT *)_dest_buffer;
  2293. mempitch = (mempitch >> 1);
  2294. USHORT  *dest_addr = NULL;
  2295. if (x2 < x1)
  2296.    {
  2297.    temp_x = x2;
  2298.    x2     = x1;
  2299.    x1     = temp_x;
  2300.    } 
  2301. height = y3-y1;
  2302. dx_left  = (x3-x1)/height;
  2303. dx_right = (x3-x2)/height;
  2304. xs = (float)x1;
  2305. xe = (float)x2+(float)0.5;
  2306. if (y1 < min_clip_y)
  2307.    {
  2308.    
  2309.    xs = xs+dx_left*(float)(-y1+min_clip_y);
  2310.    xe = xe+dx_right*(float)(-y1+min_clip_y);
  2311.    y1=min_clip_y;
  2312.    } 
  2313. if (y3>max_clip_y)
  2314.    y3=max_clip_y;
  2315. dest_addr = dest_buffer+y1*mempitch;
  2316. if (x1>=min_clip_x && x1<=max_clip_x &
  2317.     x2>=min_clip_x && x2<=max_clip_x &
  2318.     x3>=min_clip_x && x3<=max_clip_x)
  2319.     {
  2320.     for (temp_y=y1; temp_y<=y3; temp_y++,dest_addr+=mempitch)
  2321.         {
  2322.    
  2323.         Mem_Set_WORD(dest_addr+(unsigned int)xs,color,(unsigned int)(xe-xs+1));
  2324.         xs+=dx_left;
  2325.         xe+=dx_right;
  2326.         } // end for
  2327.     } 
  2328. else
  2329.    {
  2330.    for (temp_y=y1; temp_y<=y3; temp_y++,dest_addr+=mempitch)
  2331.        {
  2332.        left  = (int)xs;
  2333.        right = (int)xe;
  2334.        xs+=dx_left;
  2335.        xe+=dx_right;
  2336.        if (left < min_clip_x)
  2337.           {
  2338.           left = min_clip_x;
  2339.           if (right < min_clip_x)
  2340.              continue;
  2341.           }
  2342.        if (right > max_clip_x)
  2343.           {
  2344.           right = max_clip_x;
  2345.           if (left > max_clip_x)
  2346.              continue;
  2347.           }
  2348.         Mem_Set_WORD(dest_addr+(unsigned int)left,color,(unsigned int)(right-left+1));
  2349.        } // end for
  2350.    } 
  2351. /
  2352. void Draw_Bottom_Tri16(int x1,int y1, 
  2353.                        int x2,int y2, 
  2354.                        int x3,int y3,
  2355.                        int color,
  2356.                        UCHAR *_dest_buffer, int mempitch)
  2357. {
  2358. // 画平底三角形(16位,精确模式)
  2359. float dx_right,    // 右边1/斜率(右)
  2360.       dx_left,     // 左边1/斜率(左)
  2361.       xs,xe,       // 左右两边起始坐标
  2362.       height;      // 三角形高度
  2363. int temp_x,        
  2364.     temp_y,
  2365.     right,         
  2366.     left;
  2367. //16位模式转换
  2368. USHORT *dest_buffer = (USHORT *)_dest_buffer;
  2369. mempitch = (mempitch >> 1);
  2370. USHORT  *dest_addr = NULL;
  2371. // 测试使得 x3>x2
  2372. if (x3 < x2)
  2373.    {
  2374.    temp_x = x2;
  2375.    x2     = x3;
  2376.    x3     = temp_x;
  2377.    } 
  2378. height = y3-y1;
  2379. dx_left  = (x2-x1)/height;
  2380. dx_right = (x3-x1)/height;
  2381. //开始坐标
  2382. xs = (float)x1;
  2383. xe = (float)x1; // +(float)0.5;
  2384. //裁剪顶部
  2385. if (y1<min_clip_y)
  2386.    {
  2387.    // 计算新的 xs 和 xe
  2388.    xs = xs+dx_left*(float)(-y1+min_clip_y);
  2389.    xe = xe+dx_right*(float)(-y1+min_clip_y);
  2390.    // 重置y1
  2391.    y1=min_clip_y;
  2392.    } 
  2393. if (y3>max_clip_y)
  2394.    y3=max_clip_y;
  2395. // 计算开始目标行地址
  2396. dest_addr = dest_buffer+y1*mempitch;
  2397. // 如果三角形三点都在裁剪区域内
  2398. if (x1>=min_clip_x && x1<=max_clip_x &
  2399.     x2>=min_clip_x && x2<=max_clip_x &
  2400.     x3>=min_clip_x && x3<=max_clip_x)
  2401.     {
  2402.     // 绘制三角形
  2403.     for (temp_y=y1; temp_y<=y3; temp_y++,dest_addr+=mempitch)
  2404.         {
  2405.         // 画横线
  2406.         Mem_Set_WORD(dest_addr+(unsigned int)xs,color,(unsigned int)(xe-xs+1));
  2407.         // 加上单位高度变化的x坐标
  2408.         xs+=dx_left;
  2409.         xe+=dx_right;
  2410.         }
  2411.     } 
  2412. else
  2413.    {
  2414.    //若三角形有部分在裁剪区域外
  2415.    // 绘制三角形
  2416.    for (temp_y=y1; temp_y<=y3; temp_y++,dest_addr+=mempitch)
  2417.        {
  2418.     
  2419.        left  = (int)xs;
  2420.        right = (int)xe;
  2421.        // 加上单位高度变化的x坐标
  2422.        xs+=dx_left;
  2423.        xe+=dx_right;
  2424.        // 裁剪直线
  2425.        if (left < min_clip_x)
  2426.           {
  2427.           left = min_clip_x;
  2428.           if (right < min_clip_x)
  2429.              continue;
  2430.           }
  2431.        if (right > max_clip_x)
  2432.           {
  2433.           right = max_clip_x;
  2434.           if (left > max_clip_x)
  2435.              continue;
  2436.           }
  2437.        //绘制直线
  2438.        Mem_Set_WORD(dest_addr+(unsigned int)left,color,(unsigned int)(right-left+1));
  2439.        } 
  2440.    } 
  2441. ///
  2442. void Draw_TriangleFP_2D(int x1,int y1,
  2443.                         int x2,int y2,
  2444.                         int x3,int y3,
  2445.                         int color,
  2446.                         UCHAR *dest_buffer, int mempitch)
  2447. {
  2448. //绘制任意三角形(结合画平顶和画平底的方法,效率模式)
  2449. int temp_x,
  2450.     temp_y,
  2451.     new_x;
  2452. if ((x1==x2 && x2==x3)  ||  (y1==y2 && y2==y3))
  2453.    return;
  2454. if (y2<y1)
  2455.    {
  2456.    temp_x = x2;
  2457.    temp_y = y2;
  2458.    x2     = x1;
  2459.    y2     = y1;
  2460.    x1     = temp_x;
  2461.    y1     = temp_y;
  2462.    }
  2463. if (y3<y1)
  2464.    {
  2465.    temp_x = x3;
  2466.    temp_y = y3;
  2467.    x3     = x1;
  2468.    y3     = y1;
  2469.    x1     = temp_x;
  2470.    y1     = temp_y;
  2471.    } 
  2472. if (y3<y2)
  2473.    {
  2474.    temp_x = x3;
  2475.    temp_y = y3;
  2476.    x3     = x2;
  2477.    y3     = y2;
  2478.    x2     = temp_x;
  2479.    y2     = temp_y;
  2480.    } 
  2481. if ( y3<min_clip_y || y1>max_clip_y ||
  2482.     (x1<min_clip_x && x2<min_clip_x && x3<min_clip_x) ||
  2483.     (x1>max_clip_x && x2>max_clip_x && x3>max_clip_x) )
  2484.    return;
  2485. if (y1==y2)
  2486.    {
  2487.    Draw_Top_TriFP(x1,y1,x2,y2,x3,y3,color, dest_buffer, mempitch);
  2488.    } 
  2489. else
  2490. if (y2==y3)
  2491.    {
  2492.    Draw_Bottom_TriFP(x1,y1,x2,y2,x3,y3,color, dest_buffer, mempitch);
  2493.    } 
  2494. else
  2495.    {
  2496.    new_x = x1 + (int)(0.5+(float)(y2-y1)*(float)(x3-x1)/(float)(y3-y1));
  2497.    Draw_Bottom_TriFP(x1,y1,new_x,y2,x2,y2,color, dest_buffer, mempitch);
  2498.    Draw_Top_TriFP(x2,y2,new_x,y2,x3,y3,color, dest_buffer, mempitch);
  2499.    } 
  2500. }
  2501. /
  2502. void Draw_Triangle_2D(int x1,int y1,
  2503.                       int x2,int y2,
  2504.                       int x3,int y3,
  2505.                       int color,
  2506.                       UCHAR *dest_buffer, int mempitch)
  2507. {
  2508. //画任意三角形(结合画平顶和画平底的方法,8位,精确模式)
  2509. int temp_x, 
  2510.     temp_y,
  2511.     new_x;
  2512. // 检测三点是否在同一直线
  2513. if ((x1==x2 && x2==x3)  ||  (y1==y2 && y2==y3))
  2514.    return;
  2515. // 使纵坐标方向y3>y2>y1
  2516. if (y2<y1)
  2517.    {
  2518.    temp_x = x2;
  2519.    temp_y = y2;
  2520.    x2     = x1;
  2521.    y2     = y1;
  2522.    x1     = temp_x;
  2523.    y1     = temp_y;
  2524.    } 
  2525. if (y3<y1)
  2526.    {
  2527.    temp_x = x3;
  2528.    temp_y = y3;
  2529.    x3     = x1;
  2530.    y3     = y1;
  2531.    x1     = temp_x;
  2532.    y1     = temp_y;
  2533.    } 
  2534. if (y3<y2)
  2535.    {
  2536.    temp_x = x3;
  2537.    temp_y = y3;
  2538.    x3     = x2;
  2539.    y3     = y2;
  2540.    x2     = temp_x;
  2541.    y2     = temp_y;
  2542.    } 
  2543. // 检测三角形是否在裁剪区域外
  2544. if ( y3<min_clip_y || y1>max_clip_y ||
  2545.     (x1<min_clip_x && x2<min_clip_x && x3<min_clip_x) ||
  2546.     (x1>max_clip_x && x2>max_clip_x && x3>max_clip_x) )
  2547.    return;
  2548. // 是否平顶
  2549. if (y1==y2)
  2550.    {
  2551.    Draw_Top_Tri(x1,y1,x2,y2,x3,y3,color, dest_buffer, mempitch);
  2552.    } 
  2553. // 是否平底
  2554. else
  2555. if (y2==y3)
  2556.    {
  2557.    Draw_Bottom_Tri(x1,y1,x2,y2,x3,y3,color, dest_buffer, mempitch);
  2558.    } 
  2559. //任意三角形
  2560. else
  2561.    {
  2562.    // 从最长边找到一点将三角形一分为二(平顶和平底)
  2563.    new_x = x1 + (int)(0.5+(float)(y2-y1)*(float)(x3-x1)/(float)(y3-y1));
  2564.    Draw_Bottom_Tri(x1,y1,new_x,y2,x2,y2,color, dest_buffer, mempitch);
  2565.    Draw_Top_Tri(x2,y2,new_x,y2,x3,y3,color, dest_buffer, mempitch);
  2566.    } 
  2567. ///
  2568. void Draw_Triangle_2D16(int x1,int y1,
  2569.                         int x2,int y2,
  2570.                         int x3,int y3,
  2571.                         int color,
  2572.                         UCHAR *dest_buffer, int mempitch)
  2573. {
  2574. //画任意三角形(结合画平顶和画平底的方法,16位,精确模式)
  2575. int temp_x, 
  2576.     temp_y,
  2577.     new_x;
  2578. // 检测三点是否在同一直线
  2579. if ((x1==x2 && x2==x3)  ||  (y1==y2 && y2==y3))
  2580.    return;
  2581. // 使纵坐标方向y3>y2>y1
  2582. if (y2<y1)
  2583.    {
  2584.    temp_x = x2;
  2585.    temp_y = y2;
  2586.    x2     = x1;
  2587.    y2     = y1;
  2588.    x1     = temp_x;
  2589.    y1     = temp_y;
  2590.    } // end if
  2591. if (y3<y1)
  2592.    {
  2593.    temp_x = x3;
  2594.    temp_y = y3;
  2595.    x3     = x1;
  2596.    y3     = y1;
  2597.    x1     = temp_x;
  2598.    y1     = temp_y;
  2599.    } // end if
  2600. if (y3<y2)
  2601.    {
  2602.    temp_x = x3;
  2603.    temp_y = y3;
  2604.    x3     = x2;
  2605.    y3     = y2;
  2606.    x2     = temp_x;
  2607.    y2     = temp_y;
  2608.    } // end if
  2609. // 检测三角形是否在裁剪区域外
  2610. if ( y3<min_clip_y || y1>max_clip_y ||
  2611.     (x1<min_clip_x && x2<min_clip_x && x3<min_clip_x) ||
  2612.     (x1>max_clip_x && x2>max_clip_x && x3>max_clip_x) )
  2613.    return;
  2614. // 是否平顶
  2615. if (y1==y2)
  2616.    {
  2617.    Draw_Top_Tri16(x1,y1,x2,y2,x3,y3,color, dest_buffer, mempitch);
  2618.    }
  2619. //是否平底
  2620. else
  2621. if (y2==y3)
  2622.    {
  2623.    Draw_Bottom_Tri16(x1,y1,x2,y2,x3,y3,color, dest_buffer, mempitch);
  2624.    } 
  2625. //任意三角形
  2626. else
  2627.    {
  2628.    // 从最长边找到一点将三角形一分为二(平顶和平底)
  2629.    new_x = x1 + (int)(0.5+(float)(y2-y1)*(float)(x3-x1)/(float)(y3-y1));
  2630.    Draw_Bottom_Tri16(x1,y1,new_x,y2,x2,y2,color, dest_buffer, mempitch);
  2631.    Draw_Top_Tri16(x2,y2,new_x,y2,x3,y3,color, dest_buffer, mempitch);
  2632.    } 
  2633. inline void Draw_QuadFP_2D(int x0,int y0,
  2634.                     int x1,int y1,
  2635.                     int x2,int y2,
  2636.                     int x3, int y3,
  2637.                     int color,
  2638.                     UCHAR *dest_buffer, int mempitch)
  2639. {
  2640. //画2D四边形
  2641. //其实就是画2个三角形
  2642. Draw_TriangleFP_2D(x0,y0,x1,y1,x3,y3,color,dest_buffer,mempitch);
  2643. Draw_TriangleFP_2D(x1,y1,x2,y2,x3,y3,color,dest_buffer,mempitch);
  2644. int Mat_Mul_3X3(MATRIX3X3_PTR ma, MATRIX3X3_PTR mb, MATRIX3X3_PTR mprod)
  2645. {
  2646.   // 计算两个3X3矩阵相乘的矩阵
  2647.   for (int row=0;row<3;row++)
  2648.   {
  2649.     for (int col=0;col<3;col++)
  2650.     {
  2651.       float sum=0;
  2652.       for (int index=0;index<3;index++)
  2653.       {
  2654.         sum+=(ma->M[row][index]*mb->M[index][col]);
  2655.       }
  2656.       mprod->M[row][col] = sum;
  2657.     }
  2658.   }
  2659.   return(1);
  2660. }
  2661. int Mat_Mul_1X3_3X3(MATRIX1X3_PTR ma, MATRIX3X3_PTR mb, MATRIX1X3_PTR mprod)
  2662. {
  2663.   for (int col=0;col<3;col++)
  2664.   {
  2665.     float sum=0;
  2666.     for (int index=0;index<3;index)
  2667.     {
  2668.       sum+=(ma->M[index]*mb->M[index][col]);
  2669.     }
  2670.     mprod->M[col] =sum;
  2671.   }
  2672.   return(1);
  2673. }
  2674. int Mat_Mul_1X2_3X2(MATRIX1X2_PTR ma, MATRIX3X2_PTR mb, MATRIX1X2_PTR mprod)
  2675. {
  2676.   for (int col=0;col<2;col++)
  2677.   {
  2678.      float sum = 0;
  2679.      for (int index=0;index<2;index++)
  2680.      {
  2681.         sum+=(ma->M[index]*mb->M[index][col]);
  2682.      }
  2683.      sum+=mb->M[index][col];    //这句很关键,相当于ma的第3个元素看作1
  2684.      mprod->M[col] = sum;
  2685.   }
  2686.   return(1);
  2687. }
  2688. inline int Mat_Init_3X2(MATRIX3X2_PTR ma, 
  2689.                         float m00, float m01, 
  2690.                         float m10, float m11, 
  2691.                         float m20, float m21)
  2692. {
  2693.   //初始化3X2矩阵
  2694.   ma->M[0][0] = m00; ma->M[0][1] = m01; 
  2695.   ma->M[1][0] = m10; ma->M[1][1] = m11; 
  2696.   ma->M[2][0] = m20; ma->M[2][1] = m21;
  2697.   return(1);
  2698. }
  2699. int Fast_Distance_2D(int x, int y)
  2700. {
  2701.   // 此函数计算2点间的距离(参数x,y为两点x/y轴方向的坐标差)
  2702.   //到现在还没能够利用麦克劳林级数推出:(
  2703.   x = abs(x);
  2704.   y = abs(y);
  2705.   int mn = MIN(x,y);
  2706.   // 返回距离(3.5%的误差)
  2707.   return(x+y-(mn>>1)-(mn>>2)+(mn>>4));
  2708. ///
  2709. float Fast_Distance_3D(float fx, float fy, float fz)
  2710. {
  2711.   
  2712.   //计算3维中两点的距离 
  2713.   int temp;  // 临时变量
  2714.   int x,y,z; 
  2715.   x = fabs(fx) * 1024;
  2716.   y = fabs(fy) * 1024;
  2717.   z = fabs(fz) * 1024;
  2718.   
  2719.   if (y < x) SWAP(x,y,temp);
  2720.   if (z < y) SWAP(y,z,temp);
  2721.   if (y < x) SWAP(x,y,temp);    // 若上一句执行,此时的y中的值为z,所以再进行比较一次
  2722.   int dist = (z + 11*(y >> 5) + (x >> 2) );
  2723.   // 返回距离(8%的误差)
  2724.   return((float)(dist >> 10));
  2725. int Find_Bounding_Box_Poly2D(POLYGON2D_PTR poly, 
  2726.                              float &min_x, float &max_x, 
  2727.                              float &min_y, float &max_y)
  2728. {
  2729.   //找到多边形的边界边框矩形
  2730.   if (poly->num_verts==0)
  2731.     return(0);
  2732.   max_x = max_y = min_x = min_y =0;
  2733.   
  2734.   for (int index=0;index<poly->num_verts;index++)
  2735.   {
  2736.     if (poly->vlist[index].x > max_x)
  2737.       max_x = poly->vlist[index].x;
  2738.     if (poly->vlist[index].x < min_x)
  2739.       min_x = poly->vlist[index].x;
  2740.     if (poly->vlist[index].y > max_y)
  2741.       max_y = poly->vlist[index].y;
  2742.     if (poly->vlist[index].y < min_y)
  2743.       min_y =poly->vlist[index].y;  
  2744.   }
  2745.   return(1);
  2746. }
  2747. int Draw_Filled_Polygon2D(POLYGON2D_PTR poly,UCHAR *vbuffer,int mempitch)
  2748. {
  2749.   //绘制填充多边形(8位)
  2750.   int ydiff1,ydiff2,
  2751.       xdiff1,xdiff2,
  2752.       start,
  2753.       length,
  2754.       errorterm1,errorterm2,
  2755.       offset1,offset2,
  2756.       count1,count2,
  2757.       xunit1,xunit2;
  2758.   int edgecount = poly->num_verts-1;
  2759.   int firstvert=0;
  2760.   int min_y=poly->vlist[0].y;
  2761.   
  2762.   for (int index=1;index<poly->num_verts;index++)
  2763.   {/*找到y轴坐标最小的顶点*/
  2764.     
  2765.     if ((poly->vlist[index].y)<min_y)
  2766.     {
  2767.       firstvert=index;
  2768.       min_y=poly->vlist[index].y;
  2769.     }
  2770.   }
  2771.   int startvert1=firstvert;
  2772.   int startvert2=firstvert;
  2773.   int xstart1=poly->vlist[startvert1].x+poly->x0;  //逆时针移动的初始位置
  2774.   int ystart1=poly->vlist[startvert1].y+poly->y0;
  2775.   int xstart2=poly->vlist[startvert2].x+poly->x0;  //顺时针移动的初始位置
  2776.   int ystart2=poly->vlist[startvert2].y+poly->y0;
  2777.   /*取得逆时针移动遇到的第1个顶点坐标*/
  2778.   int endvert1=startvert1-1;
  2779.   if (endvert1<0)
  2780.     endvert1=poly->num_verts-1;
  2781.   int xend1=poly->vlist[endvert1].x+poly->x0;
  2782.   int yend1=poly->vlist[endvert1].y+poly->y0;
  2783.   
  2784.   /*取得顺时针移动遇到的第1个顶点坐标*/
  2785.   int endvert2=startvert2+1;
  2786.   if(endvert2==(poly->num_verts))
  2787.     endvert2=0;
  2788.   int xend2=poly->vlist[endvert2].x+poly->x0;
  2789.   int yend2=poly->vlist[endvert2].y+poly->y0;
  2790.   //绘制并填充多边形
  2791.   while (edgecount>0)
  2792.   {
  2793.     offset1=mempitch*ystart1+xstart1; //左边缘偏移量
  2794.     offset2=mempitch*ystart2+xstart2; //右边缘偏移量
  2795.     
  2796.     //初始化误差额
  2797.     errorterm1=0;
  2798.     errorterm2=0;
  2799.     
  2800.     //初始化左边与右边x&y方向的偏移差
  2801.     if ((ydiff1=yend1-ystart1)<0)
  2802.       ydiff1=-ydiff1;
  2803.     if ((ydiff2=yend2-ystart2)<0)
  2804.       ydiff2=-ydiff2;
  2805.     if ((xdiff1=xend1-xstart1)<0)
  2806.     {
  2807.       xunit1=-1;
  2808.       xdiff1=-xdiff1;
  2809.     }
  2810.     else
  2811.     {
  2812.       xunit1=1;
  2813.     }
  2814.     if ((xdiff2=xend2-xstart2)<0)
  2815.     {
  2816.       xunit2=-1;
  2817.       xdiff2=-xdiff2;
  2818.     }
  2819.     else
  2820.     {
  2821.       xunit2=1;
  2822.     }
  2823.     
  2824.     //选择使用哪种情况
  2825.     if (xdiff1>ydiff1)
  2826.     {/*|k1|<1*/
  2827.       if (xdiff2>ydiff2)
  2828.       {/*|k2|<1*/
  2829.         count1=xdiff1;    //左边X的增量
  2830.         count2=xdiff2;    //右边X的增量
  2831.         while (count1&&count2)
  2832.         {
  2833.           while ((errorterm1<xdiff1)&&(count1>0))
  2834.           {
  2835.             if(count1--)
  2836.             {
  2837.               offset1+=xunit1;
  2838.               xstart1+=xunit1;
  2839.             }
  2840.             errorterm1+=ydiff1;
  2841.             if (errorterm1<xdiff1)
  2842.             {
  2843.               vbuffer[offset1]=(UCHAR)poly->color;
  2844.             }
  2845.           }
  2846.           errorterm1-=xdiff1;
  2847.           while ((errorterm2<xdiff2)&&(count2>0))
  2848.           {
  2849.             if (count2--)
  2850.             {
  2851.               offset2+=xunit2;
  2852.               xstart2+=xunit2;
  2853.             }
  2854.             errorterm2+=ydiff2;
  2855.             if (errorterm2<xdiff2)
  2856.             {
  2857.               vbuffer[offset2]=(UCHAR)poly->color;
  2858.             }
  2859.           }
  2860.           errorterm2-=xdiff2;
  2861.           length=offset2-offset1;
  2862.           if (length<0)
  2863.           {
  2864.             length=-length;
  2865.             start=offset2;
  2866.           }
  2867.           else
  2868.             start=offset1;
  2869.           for (int index=start;index<start+length+1;index++)
  2870.           {
  2871.             vbuffer[index]=(UCHAR)poly->color;
  2872.           }
  2873.           offset1+=mempitch;
  2874.           ystart1++;
  2875.           offset2+=mempitch;
  2876.           ystart2++;
  2877.         }
  2878.       }
  2879.       else
  2880.       {/*|k2|>1*/
  2881.         count1=xdiff1;
  2882.         count2=ydiff2;
  2883.         while (count1&&count2)
  2884.         {
  2885.           while ((errorterm1<xdiff1)&&(count1>0))
  2886.           {
  2887.             if(count1--)
  2888.             {
  2889.               offset1+=xunit1;
  2890.               xstart1+=xunit1;
  2891.             }
  2892.             errorterm1+=ydiff1;
  2893.             if (errorterm1<xdiff1)
  2894.             {
  2895.               vbuffer[offset1]=(UCHAR)poly->color;
  2896.             }
  2897.           }
  2898.           errorterm1-=xdiff1;
  2899.           
  2900.           errorterm2+=xdiff2;
  2901.           if (errorterm2>=ydiff2)
  2902.           {
  2903.             errorterm2-=ydiff2;
  2904.             offset2+=xunit2;
  2905.             xstart2+=xunit2;
  2906.           }
  2907.           count2--;
  2908.           length=offset2-offset1;
  2909.           if (length<0)
  2910.           {
  2911.             length=-length;
  2912.             start=offset2;
  2913.           }
  2914.           else
  2915.             start=offset1;
  2916.           
  2917.           for (int index=start;index<start+length+1;index++)
  2918.           {
  2919.             vbuffer[index]=(UCHAR)poly->color;
  2920.           }
  2921.           offset1+=mempitch;
  2922.           ystart1++;
  2923.           offset2+=mempitch;
  2924.           ystart2++;
  2925.         }
  2926.       }
  2927.     }
  2928.     else
  2929.     {/*|k1|>1*/
  2930.       if (xdiff2>ydiff2)
  2931.       {/*|k2|<1*/
  2932.         count1=ydiff1;
  2933.         count2=xdiff2;
  2934.         while (count1&&count2)
  2935.         {
  2936.           errorterm1+=xdiff1;
  2937.           if (errorterm1>=ydiff1)
  2938.           {
  2939.             errorterm1-=ydiff1;
  2940.             offset1+=xunit1;
  2941.             xstart1+=xunit1;
  2942.           }
  2943.           count1--;
  2944.           
  2945.           while ((errorterm2<xdiff2)&&(count2>0))
  2946.           {
  2947.             if (count2--)
  2948.             {
  2949.               offset2+=xunit2;
  2950.               xstart2+=xunit2;
  2951.             }
  2952.             errorterm2+=ydiff2;
  2953.             if (errorterm2<xdiff2)
  2954.             {
  2955.               vbuffer[offset2]=(UCHAR)poly->color;
  2956.             }
  2957.         
  2958.           }
  2959.           errorterm2-=xdiff2;
  2960.           length=offset2-offset1;
  2961.           if (length<0)
  2962.           {
  2963.             length=-length;
  2964.             start=offset2;
  2965.           }
  2966.           else
  2967.             start=offset1;
  2968.           for (int index=start;index<start+length+1;index++)
  2969.           {
  2970.             vbuffer[index]=(UCHAR)poly->color;
  2971.           }
  2972.           offset1+=mempitch;
  2973.           ystart1++;
  2974.           offset2+=mempitch;
  2975.           ystart2++;
  2976.         }
  2977.       }
  2978.       else
  2979.       {/*|k2|>1*/
  2980.         
  2981.         count1=ydiff1;
  2982.         count2=ydiff2;
  2983.         while (count1&&count2)
  2984.         {
  2985.           errorterm1+=xdiff1;
  2986.           if (errorterm1>=ydiff1)
  2987.           {
  2988.             errorterm1-=ydiff1;
  2989.             offset1+=xunit1;
  2990.             xstart1+=xunit1;
  2991.           }
  2992.           count1--;
  2993.           errorterm2+=xdiff2;
  2994.           if (errorterm2>=ydiff2)
  2995.           {
  2996.             errorterm2-=ydiff2;
  2997.             offset2+=xunit2;
  2998.             xstart2+=xunit2;
  2999.           }
  3000.           count2--;
  3001.           length=offset2-offset1;
  3002.           if (length<0)
  3003.           {
  3004.             length=-length;
  3005.             start=offset2;
  3006.           }
  3007.           else
  3008.             start=offset1;
  3009.           for (int index=start;index<start+length+1;index++)
  3010.           {
  3011.             vbuffer[index]=(UCHAR)poly->color;
  3012.           }
  3013.           offset1+=mempitch;
  3014.           ystart1++;
  3015.           offset2+=mempitch;
  3016.           ystart2++;
  3017.         }
  3018.       }
  3019.     }
  3020.     if (!count1)
  3021.     {/*首先到达逆时针顶点*/
  3022.       --edgecount;
  3023.       startvert1=endvert1;
  3024.       --endvert1;
  3025.       if (endvert1<0)
  3026.         endvert1=poly->num_verts-1;
  3027.       xend1=poly->vlist[endvert1].x+poly->x0;
  3028.       yend1=poly->vlist[endvert1].y+poly->y0;
  3029.     }
  3030.     if (!count2)
  3031.     {/*首先到达顺时针顶点*/
  3032.       --edgecount;
  3033.       startvert2=endvert2;
  3034.       ++endvert2;
  3035.       if(endvert2==(poly->num_verts))
  3036.         endvert2=0;
  3037.       xend2=poly->vlist[endvert2].x+poly->x0;
  3038.       yend2=poly->vlist[endvert2].y+poly->y0;
  3039.     }
  3040.     
  3041.   }
  3042.   
  3043.   return(1);
  3044. }
  3045. int Draw_Filled_Polygon2D16(POLYGON2D_PTR poly, UCHAR *_vbuffer, int mempitch)
  3046. {
  3047.   //绘制填充多边形(16位)
  3048.   int ydiff1,ydiff2,
  3049.       xdiff1,xdiff2,
  3050.       start,
  3051.       length,
  3052.       errorterm1,errorterm2,
  3053.       offset1,offset2,
  3054.       count1,count2,
  3055.       xunit1,xunit2;
  3056.   USHORT *vbuffer = (USHORT*)_vbuffer;
  3057.   mempitch = mempitch>>1;
  3058.   int edgecount = poly->num_verts-1;
  3059.   int firstvert=0;
  3060.   int min_y=poly->vlist[0].y;
  3061.   
  3062.   for (int index=1;index<poly->num_verts;index++)
  3063.   {/*找到y轴坐标最小的顶点*/
  3064.     
  3065.     if ((poly->vlist[index].y)<min_y)
  3066.     {
  3067.       firstvert=index;
  3068.       min_y=poly->vlist[index].y;
  3069.     }
  3070.   }
  3071.   int startvert1=firstvert;
  3072.   int startvert2=firstvert;
  3073.   int xstart1=poly->vlist[startvert1].x+poly->x0;  //逆时针移动的初始位置
  3074.   int ystart1=poly->vlist[startvert1].y+poly->y0;
  3075.   int xstart2=poly->vlist[startvert2].x+poly->x0;  //顺时针移动的初始位置
  3076.   int ystart2=poly->vlist[startvert2].y+poly->y0;
  3077.   /*取得逆时针移动遇到的第1个顶点坐标*/
  3078.   int endvert1=startvert1-1;
  3079.   if (endvert1<0)
  3080.     endvert1=poly->num_verts-1;
  3081.   int xend1=poly->vlist[endvert1].x+poly->x0;
  3082.   int yend1=poly->vlist[endvert1].y+poly->y0;
  3083.   
  3084.   /*取得顺时针移动遇到的第1个顶点坐标*/
  3085.   int endvert2=startvert2+1;
  3086.   if(endvert2==(poly->num_verts))
  3087.     endvert2=0;
  3088.   int xend2=poly->vlist[endvert2].x+poly->x0;
  3089.   int yend2=poly->vlist[endvert2].y+poly->y0;
  3090.   //绘制并填充多边形
  3091.   while (edgecount>0)
  3092.   {
  3093.     offset1=mempitch*ystart1+xstart1; //左边缘偏移量
  3094.     offset2=mempitch*ystart2+xstart2; //右边缘偏移量
  3095.     
  3096.     //初始化误差额
  3097.     errorterm1=0;
  3098.     errorterm2=0;
  3099.     
  3100.     //初始化左边与右边x&y方向的偏移差
  3101.     if ((ydiff1=yend1-ystart1)<0)
  3102.       ydiff1=-ydiff1;
  3103.     if ((ydiff2=yend2-ystart2)<0)
  3104.       ydiff2=-ydiff2;
  3105.     if ((xdiff1=xend1-xstart1)<0)
  3106.     {
  3107.       xunit1=-1;
  3108.       xdiff1=-xdiff1;
  3109.     }
  3110.     else
  3111.     {
  3112.       xunit1=1;
  3113.     }
  3114.     if ((xdiff2=xend2-xstart2)<0)
  3115.     {
  3116.       xunit2=-1;
  3117.       xdiff2=-xdiff2;
  3118.     }
  3119.     else
  3120.     {
  3121.       xunit2=1;
  3122.     }
  3123.     
  3124.     //选择使用哪种情况
  3125.     if (xdiff1>ydiff1)
  3126.     {/*|k1|<1*/
  3127.       if (xdiff2>ydiff2)
  3128.       {/*|k2|<1*/
  3129.         count1=xdiff1;    //左边X的增量
  3130.         count2=xdiff2;    //右边X的增量
  3131.         while (count1&&count2)
  3132.         {
  3133.           while ((errorterm1<xdiff1)&&(count1>0))
  3134.           {
  3135.             if(count1--)
  3136.             {
  3137.               offset1+=xunit1;
  3138.               xstart1+=xunit1;
  3139.             }
  3140.             errorterm1+=ydiff1;
  3141.             if (errorterm1<xdiff1)
  3142.             {
  3143.               vbuffer[offset1]=(USHORT)poly->color;
  3144.             }
  3145.           }
  3146.           errorterm1-=xdiff1;
  3147.           while ((errorterm2<xdiff2)&&(count2>0))
  3148.           {
  3149.             if (count2--)
  3150.             {
  3151.               offset2+=xunit2;
  3152.               xstart2+=xunit2;
  3153.             }
  3154.             errorterm2+=ydiff2;
  3155.             if (errorterm2<xdiff2)
  3156.             {
  3157.               vbuffer[offset2]=(USHORT)poly->color;
  3158.             }
  3159.           }
  3160.           errorterm2-=xdiff2;
  3161.           length=offset2-offset1;
  3162.           if (length<0)
  3163.           {
  3164.             length=-length;
  3165.             start=offset2;
  3166.           }
  3167.           else
  3168.             start=offset1;
  3169.           for (int index=start;index<start+length+1;index++)
  3170.           {
  3171.             vbuffer[index]=(USHORT)poly->color;
  3172.           }
  3173.           offset1+=mempitch;
  3174.           ystart1++;
  3175.           offset2+=mempitch;
  3176.           ystart2++;
  3177.         }
  3178.       }
  3179.       else
  3180.       {/*|k2|>1*/
  3181.         count1=xdiff1;
  3182.         count2=ydiff2;
  3183.         while (count1&&count2)
  3184.         {
  3185.           while ((errorterm1<xdiff1)&&(count1>0))
  3186.           {
  3187.             if(count1--)
  3188.             {
  3189.               offset1+=xunit1;
  3190.               xstart1+=xunit1;
  3191.             }
  3192.             errorterm1+=ydiff1;
  3193.             if (errorterm1<xdiff1)
  3194.             {
  3195.               vbuffer[offset1]=(USHORT)poly->color;
  3196.             }
  3197.           }
  3198.           errorterm1-=xdiff1;
  3199.           
  3200.           errorterm2+=xdiff2;
  3201.           if (errorterm2>=ydiff2)
  3202.           {
  3203.             errorterm2-=ydiff2;
  3204.             offset2+=xunit2;
  3205.             xstart2+=xunit2;
  3206.           }
  3207.           count2--;
  3208.           length=offset2-offset1;
  3209.           if (length<0)
  3210.           {
  3211.             length=-length;
  3212.             start=offset2;
  3213.           }
  3214.           else
  3215.             start=offset1;
  3216.           
  3217.           for (int index=start;index<start+length+1;index++)
  3218.           {
  3219.             vbuffer[index]=(USHORT)poly->color;
  3220.           }
  3221.           offset1+=mempitch;
  3222.           ystart1++;
  3223.           offset2+=mempitch;
  3224.           ystart2++;
  3225.         }
  3226.       }
  3227.     }
  3228.     else
  3229.     {/*|k1|>1*/
  3230.       if (xdiff2>ydiff2)
  3231.       {/*|k2|<1*/
  3232.         count1=ydiff1;
  3233.         count2=xdiff2;
  3234.         while (count1&&count2)
  3235.         {
  3236.           errorterm1+=xdiff1;
  3237.           if (errorterm1>=ydiff1)
  3238.           {
  3239.             errorterm1-=ydiff1;
  3240.             offset1+=xunit1;
  3241.             xstart1+=xunit1;
  3242.           }
  3243.           count1--;
  3244.           
  3245.           while ((errorterm2<xdiff2)&&(count2>0))
  3246.           {
  3247.             if (count2--)
  3248.             {
  3249.               offset2+=xunit2;
  3250.               xstart2+=xunit2;
  3251.             }
  3252.             errorterm2+=ydiff2;
  3253.             if (errorterm2<xdiff2)
  3254.             {
  3255.               vbuffer[offset2]=(USHORT)poly->color;
  3256.             }
  3257.         
  3258.           }
  3259.           errorterm2-=xdiff2;
  3260.           length=offset2-offset1;
  3261.           if (length<0)
  3262.           {
  3263.             length=-length;
  3264.             start=offset2;
  3265.           }
  3266.           else
  3267.             start=offset1;
  3268.           for (int index=start;index<start+length+1;index++)
  3269.           {
  3270.             vbuffer[index]=(USHORT)poly->color;
  3271.           }
  3272.           offset1+=mempitch;
  3273.           ystart1++;
  3274.           offset2+=mempitch;
  3275.           ystart2++;
  3276.         }
  3277.       }
  3278.       else
  3279.       {/*|k2|>1*/
  3280.         
  3281.         count1=ydiff1;
  3282.         count2=ydiff2;
  3283.         while (count1&&count2)
  3284.         {
  3285.           errorterm1+=xdiff1;
  3286.           if (errorterm1>=ydiff1)
  3287.           {
  3288.             errorterm1-=ydiff1;
  3289.             offset1+=xunit1;
  3290.             xstart1+=xunit1;
  3291.           }
  3292.           count1--;
  3293.           errorterm2+=xdiff2;
  3294.           if (errorterm2>=ydiff2)
  3295.           {
  3296.             errorterm2-=ydiff2;
  3297.             offset2+=xunit2;
  3298.             xstart2+=xunit2;
  3299.           }
  3300.           count2--;
  3301.           length=offset2-offset1;
  3302.           if (length<0)
  3303.           {
  3304.             length=-length;
  3305.             start=offset2;
  3306.           }
  3307.           else
  3308.             start=offset1;
  3309.           for (int index=start;index<start+length+1;index++)
  3310.           {
  3311.             vbuffer[index]=(USHORT)poly->color;
  3312.           }
  3313.           offset1+=mempitch;
  3314.           ystart1++;
  3315.           offset2+=mempitch;
  3316.           ystart2++;
  3317.         }
  3318.       }
  3319.     }
  3320.     if (!count1)
  3321.     {/*首先到达逆时针顶点*/
  3322.       --edgecount;
  3323.       startvert1=endvert1;
  3324.       --endvert1;
  3325.       if (endvert1<0)
  3326.         endvert1=poly->num_verts-1;
  3327.       xend1=poly->vlist[endvert1].x+poly->x0;
  3328.       yend1=poly->vlist[endvert1].y+poly->y0;
  3329.     }
  3330.     if (!count2)
  3331.     {/*首先到达顺时针顶点*/
  3332.       --edgecount;
  3333.       startvert2=endvert2;
  3334.       ++endvert2;
  3335.       if(endvert2==(poly->num_verts))
  3336.         endvert2=0;
  3337.       xend2=poly->vlist[endvert2].x+poly->x0;
  3338.       yend2=poly->vlist[endvert2].y+poly->y0;
  3339.     }
  3340.     
  3341.   }
  3342.   
  3343.   return(1);
  3344. }
  3345. void Build_Sin_Cos_Tables(void)
  3346. {
  3347.   //创建三角函数表
  3348.   for (int ang=0;ang<=360;ang++)
  3349.   {
  3350.     float theta = float(ang)*PI/(float)180;
  3351.     cos_look[ang] = cos(theta);
  3352.     sin_look[ang] = sin(theta);
  3353.   }
  3354. }
  3355. int Translate_Polygon2D(POLYGON2D_PTR poly,int dx,int dy)
  3356. {
  3357.   //移动多边形
  3358.   if(!poly)
  3359.     return(0);
  3360.   poly->x0+=dx;
  3361.   poly->y0+=dy;
  3362.   return(1);
  3363. }
  3364. int Scale_Polygon2D(POLYGON2D_PTR poly,float sx,float sy)
  3365. {
  3366.   //缩放多边形
  3367.   if(!poly)
  3368.     return(0);
  3369.   for (int cur_vest=0;cur_vest<poly->num_verts;cur_vest++)
  3370.   {
  3371.     poly->vlist[cur_vest].x*=sx;
  3372.     poly->vlist[cur_vest].y*=sy;
  3373.   }
  3374.   return(1);
  3375. }
  3376. int Rotate_Polygon2D(POLYGON2D_PTR poly,int theta)
  3377. {
  3378.   //旋转多边形
  3379.   if(!poly)
  3380.     return(0);
  3381.   for(int curr_vert=0;curr_vert<poly->num_verts;curr_vert++)
  3382.   {
  3383.     float xr=poly->vlist[curr_vert].x*cos_look[theta]-
  3384.               poly->vlist[curr_vert].y*sin_look[theta];
  3385.     float yr=poly->vlist[curr_vert].x*sin_look[theta]+
  3386.               poly->vlist[curr_vert].y*cos_look[theta];
  3387.     poly->vlist[curr_vert].x=xr;
  3388.     poly->vlist[curr_vert].y=yr;
  3389.   }
  3390.   return(1);
  3391. }
  3392. int Draw_Polygon2D(POLYGON2D_PTR poly,UCHAR *vbuffer,int lpitch)
  3393. {
  3394.   //绘制2D多边形(8位)
  3395.   if(poly->state)
  3396.   {
  3397.     for(int index=0;index<poly->num_verts-1;index++)
  3398.     {/*依次连接1~n-1个顶点*/
  3399.       Draw_Clip_Line(poly->vlist[index].x+poly->x0,
  3400.                      poly->vlist[index].y+poly->y0,
  3401.                      poly->vlist[index+1].x+poly->x0,
  3402.                      poly->vlist[index+1].y+poly->y0,
  3403.                      poly->color,
  3404.                      vbuffer,lpitch);
  3405.     }
  3406.     //连接顶点1和顶点n
  3407.     Draw_Clip_Line(poly->vlist[0].x+poly->x0,
  3408.                    poly->vlist[0].y+poly->y0,
  3409.                    poly->vlist[index].x+poly->x0,
  3410.                    poly->vlist[index].y+poly->y0,
  3411.                    poly->color,
  3412.                    vbuffer,lpitch);
  3413.     return(1);
  3414.   }
  3415.   else
  3416.     return(0);
  3417. }
  3418. int Draw_Polygon2D16(POLYGON2D_PTR poly,UCHAR *vbuffer,int lpitch)
  3419. {
  3420.   //绘制2D多边形(16位)
  3421.   if(poly->state)
  3422.   {
  3423.     for(int index=0;index<poly->num_verts-1;index++)
  3424.     {/*依次连接1~n-1个顶点*/
  3425.       Draw_Clip_Line16(poly->vlist[index].x+poly->x0,
  3426.                       poly->vlist[index].y+poly->y0,
  3427.                       poly->vlist[index+1].x+poly->x0,
  3428.                       poly->vlist[index+1].y+poly->y0,
  3429.                       poly->color,
  3430.                       vbuffer,lpitch);
  3431.     }
  3432.     //连接顶点1和顶点n
  3433.     Draw_Clip_Line16(poly->vlist[0].x+poly->x0,
  3434.                      poly->vlist[0].y+poly->y0,
  3435.                      poly->vlist[index].x+poly->x0,
  3436.                      poly->vlist[index].y+poly->y0,
  3437.                      poly->color,
  3438.                      vbuffer,lpitch);
  3439.     return(1);
  3440.   }
  3441.   else
  3442.     return(0);
  3443. }
  3444. /*以下三个函数以矩阵运算实现2D多边形的平移,缩放,旋转*/
  3445. int Translate_Polygon2D_Mat(POLYGON2D_PTR poly,int dx,int dy)
  3446. {
  3447.   if (!poly)
  3448.     return(0);
  3449.   MATRIX3X2 mt;
  3450.   Mat_Init_3X2(&mt,1,0,0,1,dx,dy);
  3451.   MATRIX1X2 p0={float(poly->x0),float(poly->y0)};
  3452.   MATRIX1X2 p1={0,0};
  3453.   Mat_Mul_1X2_3X2(&p0,&mt,&p1);
  3454.   
  3455.   poly->x0=p1.M[0];
  3456.   poly->y0=p1.M[1];
  3457.   return(1);
  3458.     
  3459. }
  3460. int Scale_Polygon2D_Mat(POLYGON2D_PTR poly,float sx,float sy)
  3461. {
  3462.   if(!poly)
  3463.     return(0);
  3464.   MATRIX3X2 ms;
  3465.   Mat_Init_3X2(&ms,sx,0,0,sy,0,0);
  3466.   for (int cur_vest=0;cur_vest<poly->num_verts;cur_vest++)
  3467.   {
  3468.     MATRIX1X2 p0={poly->vlist[cur_vest].x,poly->vlist[cur_vest].y};
  3469.     MATRIX1X2 p1={0,0};
  3470.     Mat_Mul_1X2_3X2(&p0,&ms,&p1);
  3471.     poly->vlist[cur_vest].x=p1.M[0];
  3472.     poly->vlist[cur_vest].y=p1.M[1];
  3473.   }
  3474.   return(1);
  3475. }
  3476. int Rotate_Polygon2D_Mat(POLYGON2D_PTR poly,int theta)
  3477. {
  3478.   if(!poly)
  3479.     return(0);
  3480.   if(theta<0)
  3481.     theta+=360;
  3482.   MATRIX3X2 mr;
  3483.   Mat_Init_3X2(&mr,cos_look[theta],sin_look[theta],-sin_look[theta],cos_look[theta],0,0);
  3484.   for (int cur_vest=0;cur_vest<poly->num_verts;cur_vest++)
  3485.   {
  3486.     MATRIX1X2 p0={poly->vlist[cur_vest].x,poly->vlist[cur_vest].y};
  3487.     MATRIX1X2 p1={0,0};
  3488.     Mat_Mul_1X2_3X2(&p0,&mr,&p1);
  3489.     poly->vlist[cur_vest].x=p1.M[0];
  3490.     poly->vlist[cur_vest].y=p1.M[1];
  3491.   }
  3492.   return(1);
  3493. }
  3494. //
  3495. int Create_BOB(BOB_PTR bob,                     //须创建的BOB对象
  3496.                int x, int y,                    //初始位置
  3497.                int width, int height,           //宽,高
  3498.                int num_frames,                  //帧数
  3499.                int attr,                        //属性
  3500.                int mem_flags/* =0 */,           //存储方式(默认在显存)
  3501.                USHORT color_key_value/* =0 */,  //默认色彩键为黑色
  3502.                int bpp/* =8 */)                 //默认色深为8位
  3503. {
  3504.   DDSURFACEDESC2 ddsd;
  3505.   int index;
  3506.   //初始化BOB对象
  3507.   bob->state      = BOB_STATE_ALIVE;
  3508.   bob->attr       = attr;
  3509.   bob->anim_state = 0;
  3510.   bob->counter_1  = 0;
  3511.   bob->counter_2  = 0;
  3512.   bob->max_count_1= 0;
  3513.   bob->max_count_2= 0;
  3514.   bob->curr_frame = 0;
  3515.   bob->num_frames = num_frames;
  3516.   bob->bpp        = bpp;
  3517.   bob->curr_animation= 0;
  3518.   bob->anim_counter  = 0;
  3519.   bob->anim_index    = 0;
  3520.   bob->anim_count_max= 0;
  3521.   bob->x             = x;
  3522.   bob->y             = y;
  3523.   bob->xv            = 0;
  3524.   bob->yv            = 0;
  3525.   bob->width  = width;
  3526.   bob->height = height;
  3527.   for (index=0;index<MAX_BOB_FRAMES;index++)
  3528.     bob->images[index] = NULL;
  3529.   for (index=0;index<MAX_BOB_ANIMATIONS;index++)
  3530.     bob->animations[index] = NULL;
  3531.   #if 0
  3532.   // 须保证显示表面宽为8的倍数,一些旧版本的DD那样做,现在不需要
  3533.   bob->width_fill = ((width%8!=0) ? (8-width%8) : 0);
  3534.   Write_Error("/nCreate BOB: width_fill=%d",bob->width_fill);
  3535.   #endif
  3536.   //创建表面
  3537.   for (index=0;index<bob->num_frames;index++)
  3538.   {
  3539.     DDRAW_INIT_STRUCT(ddsd);
  3540.     ddsd.dwFlags = DDSD_CAPS | DDSD_WIDTH | DDSD_HEIGHT;
  3541.     ddsd.dwWidth = bob->width + bob->width_fill;
  3542.     ddsd.dwHeight= bob->height;
  3543.     ddsd.ddsCaps.dwCaps = DDSCAPS_OFFSCREENPLAIN | mem_flags;
  3544.     if (FAILED(lpdd->CreateSurface(&ddsd,&(bob->images[index]),NULL)))
  3545.       return(0);
  3546.     DDCOLORKEY color_key;
  3547.     color_key.dwColorSpaceLowValue  = color_key_value;
  3548.     color_key.dwColorSpaceHighValue = color_key_value;
  3549.     (bob->images[index])->SetColorKey(DDCKEY_SRCBLT,&color_key);
  3550.   } // end for index
  3551.   return(1);
  3552. }
  3553. int Clone_BOB(BOB_PTR source, BOB_PTR dest)
  3554. {
  3555.   //克隆BOB对象,所克隆的对象和源对象数据一样,指针指向同一块内存区
  3556.   //克隆的对象有一个BOB_ATTR_CLONE标记
  3557.   if ((source && dest) && (source!=dest))
  3558.   {
  3559.     memcpy(dest,source,sizeof(BOB));
  3560.     dest->attr |= BOB_ATTR_CLONE;
  3561.   }
  3562.   else
  3563.     return(0);
  3564.   return(1);
  3565. }
  3566. int Destroy_BOB(BOB_PTR bob)
  3567. {
  3568.   //销毁BOB对象,对克隆的对象,将指针赋NULL.对源对象,需释放内存.
  3569.   int index;
  3570.   if (!bob)
  3571.     return(0);
  3572.   if (bob->attr & BOB_ATTR_CLONE)
  3573.   {
  3574.     for (index=0;index<MAX_BOB_FRAMES;index++)
  3575.       if (bob->images[index])
  3576.         bob->images[index]=NULL;
  3577.     for (index=0;index<MAX_BOB_ANIMATIONS;index++)
  3578.       if (bob->animations[index])
  3579.         bob->animations[index]=NULL;
  3580.   }
  3581.   else
  3582.   {
  3583.     for (index=0;index<MAX_BOB_FRAMES;index++)
  3584.       if (bob->images[index])
  3585.         (bob->images[index])->Release();
  3586.     for (index=0;index<MAX_BOB_ANIMATIONS;index++)
  3587.       if (bob->animations[index])
  3588.         free(bob->animations[index]);
  3589.       
  3590.   }
  3591.   return(1);
  3592. int Draw_BOB(BOB_PTR bob, LPDIRECTDRAWSURFACE7 dest)
  3593. {
  3594.   RECT dest_rect,
  3595.        source_rect;
  3596.   if (!bob)
  3597.     return(0);
  3598.   if (!(bob->attr & BOB_ATTR_VISIBLE))
  3599.     return(1);
  3600.   dest_rect.left  = bob->x;
  3601.   dest_rect.top   = bob->y;
  3602.   dest_rect.right = bob->x+bob->width;
  3603.   dest_rect.bottom= bob->y+bob->height;
  3604.   source_rect.left    = 0;
  3605.   source_rect.top     = 0;
  3606.   source_rect.right   = bob->width;
  3607.   source_rect.bottom  = bob->height;
  3608.   //绘制过程
  3609.   if (FAILED(dest->Blt(&dest_rect,bob->images[bob->curr_frame],
  3610.               &source_rect,(DDBLT_WAIT | DDBLT_KEYSRC),
  3611.               NULL)))
  3612.       return(0);
  3613.   
  3614.   return(1);
  3615. }
  3616. int Draw_BOB16(BOB_PTR bob, LPDIRECTDRAWSURFACE7 dest)
  3617. {
  3618.   RECT dest_rect,
  3619.        source_rect;
  3620.   if (!bob)
  3621.     return(0);
  3622.   if (!(bob->attr & BOB_ATTR_VISIBLE))
  3623.     return(1);
  3624.   dest_rect.left  = bob->x;
  3625.   dest_rect.top   = bob->y;
  3626.   dest_rect.right = bob->x+bob->width;
  3627.   dest_rect.bottom= bob->y+bob->height;
  3628.   source_rect.left    = 0;
  3629.   source_rect.top     = 0;
  3630.   source_rect.right   = bob->width;
  3631.   source_rect.bottom  = bob->height;
  3632.   //绘制过程
  3633.   if (FAILED(dest->Blt(&dest_rect,bob->images[bob->curr_frame],
  3634.               &source_rect,(DDBLT_WAIT | DDBLT_KEYSRC),
  3635.               NULL)))
  3636.       return(0);
  3637.   
  3638.   return(1);
  3639. }
  3640. int Draw_Scaled_BOB(BOB_PTR bob, int swidth, int sheight,
  3641.                     LPDIRECTDRAWSURFACE7 dest)
  3642. {
  3643.   //绘制经缩放的BOB对象
  3644.   RECT dest_rect,
  3645.        source_rect;
  3646.   if (!bob)
  3647.     return(0);
  3648.   if (!(bob->attr & BOB_ATTR_VISIBLE))
  3649.     return(1);
  3650.   dest_rect.left  = bob->x;
  3651.   dest_rect.top   = bob->y;
  3652.   dest_rect.right = bob->x+swidth;
  3653.   dest_rect.bottom= bob->y+sheight;
  3654.   source_rect.left    = 0;
  3655.   source_rect.top     = 0;
  3656.   source_rect.right   = bob->width;
  3657.   source_rect.bottom  = bob->height;
  3658.   //绘制过程
  3659.   if (FAILED(dest->Blt(&dest_rect,bob->images[bob->curr_frame],
  3660.               &source_rect,(DDBLT_WAIT | DDBLT_KEYSRC),
  3661.               NULL)))
  3662.       return(0);
  3663.   
  3664.   return(1);
  3665. }
  3666. int Draw_Scaled_BOB16(BOB_PTR bob, int swidth, int sheight,
  3667.                       LPDIRECTDRAWSURFACE7 dest)
  3668. {
  3669.   //绘制经缩放的BOB对象
  3670.   RECT dest_rect,
  3671.        source_rect;
  3672.   if (!bob)
  3673.     return(0);
  3674.   if (!(bob->attr & BOB_ATTR_VISIBLE))
  3675.     return(1);
  3676.   dest_rect.left  = bob->x;
  3677.   dest_rect.top   = bob->y;
  3678.   dest_rect.right = bob->x+swidth;
  3679.   dest_rect.bottom= bob->y+sheight;
  3680.   source_rect.left    = 0;
  3681.   source_rect.top     = 0;
  3682.   source_rect.right   = bob->width;
  3683.   source_rect.bottom  = bob->height;
  3684.   //绘制过程
  3685.   if (FAILED(dest->Blt(&dest_rect,bob->images[bob->curr_frame],
  3686.               &source_rect,(DDBLT_WAIT | DDBLT_KEYSRC),
  3687.               NULL)))
  3688.       return(0);
  3689.   
  3690.   return(1);
  3691. }
  3692. int Load_Frame_BOB(BOB_PTR bob, 
  3693.                    BITMAP_FILE_PTR bitmap, 
  3694.                    int frame,
  3695.                    int cx,int cy,
  3696.                    int mode)
  3697. {
  3698.   //此函数将位图数据加载到BOB对象中的一帧(8位)
  3699.   
  3700.   DDSURFACEDESC2 ddsd;
  3701.   if (!bob)
  3702.     return(0);
  3703.   
  3704.   UCHAR *source_ptr,
  3705.         *dest_ptr;
  3706.   //计算须加载位图的绝对坐标
  3707.   if (mode==BITMAP_EXTRACT_MODE_CELL)
  3708.   {
  3709.     cx = cx*(bob->width+1) + 1;
  3710.     cy = cy*(bob->height+1) + 1;
  3711.   }
  3712.   //定位加载地址
  3713.   source_ptr = bitmap->buffer + cy*bitmap->bitmapinfoheader.biWidth+cx;
  3714.   ddsd.dwSize = sizeof(ddsd);
  3715.   (bob->images[frame])->Lock(NULL,
  3716.                              &ddsd,
  3717.                              DDLOCK_WAIT | DDLOCK_SURFACEMEMORYPTR,
  3718.                              NULL);
  3719.   dest_ptr = (UCHAR*)ddsd.lpSurface;
  3720.   //完成位图copy
  3721.   for (int index_y=0;index_y<bob->height;index_y++)
  3722.   {
  3723.     memcpy(dest_ptr,source_ptr,bob->width);
  3724.     dest_ptr += ddsd.lPitch;  // (bob->width+bob->width_fill);
  3725.     source_ptr += bitmap->bitmapinfoheader.biWidth;
  3726.   }
  3727.   (bob->images[frame])->Unlock(NULL);
  3728.   bob->attr |= BOB_ATTR_LOADED;
  3729.   return(1);
  3730. }
  3731. int Load_Frame_BOB16(BOB_PTR bob, 
  3732.                     BITMAP_FILE_PTR bitmap, 
  3733.                     int frame,
  3734.                     int cx,int cy,
  3735.                     int mode)
  3736. {
  3737.   //此函数将位图数据加载到BOB对象中的一帧(16位)
  3738.   
  3739.   DDSURFACEDESC2 ddsd;
  3740.   if (!bob)
  3741.     return(0);
  3742.   
  3743.   USHORT *source_ptr,
  3744.          *dest_ptr;
  3745.   //计算须加载位图的绝对坐标
  3746.   if (mode==BITMAP_EXTRACT_MODE_CELL)
  3747.   {
  3748.     cx = cx*(bob->width+1) + 1;
  3749.     cy = cy*(bob->height+1) + 1;
  3750.   }
  3751.   //定位加载地址
  3752.   source_ptr =(USHORT*)bitmap->buffer + cy*bitmap->bitmapinfoheader.biWidth+cx;
  3753.   ddsd.dwSize = sizeof(ddsd);
  3754.   (bob->images[frame])->Lock(NULL,
  3755.                              &ddsd,
  3756.                              DDLOCK_WAIT | DDLOCK_SURFACEMEMORYPTR,
  3757.                              NULL);
  3758.   dest_ptr = (USHORT*)ddsd.lpSurface;
  3759.   // 完成位图copy
  3760.   for (int index_y=0;index_y<bob->height;index_y++)
  3761.   {
  3762.     memcpy(dest_ptr,source_ptr,(bob->width*2));
  3763.     dest_ptr += (ddsd.lPitch>>1);  // (bob->width+bob->width_fill);
  3764.     source_ptr += bitmap->bitmapinfoheader.biWidth;
  3765.   }
  3766.   (bob->images[frame])->Unlock(NULL);
  3767.   bob->attr |= BOB_ATTR_LOADED;
  3768.   return(1);
  3769. }
  3770. int Animate_BOB(BOB_PTR bob)
  3771. {
  3772.   if (!bob)
  3773.     return(0);
  3774.   //BOB对象只有一帧
  3775.   if(bob->attr & BOB_ATTR_SINGLE_FRAME)
  3776.   {
  3777.     bob->curr_frame = 0;
  3778.     return(1);
  3779.   }
  3780.   //使用多个帧创建BOB,但BOB以线性次序0..n执行动画
  3781.   else
  3782.   if (bob->attr & BOB_ATTR_MULTI_FRAME)
  3783.   {
  3784.     if (++bob->anim_counter>=bob->anim_count_max)
  3785.     {
  3786.       bob->anim_counter = 0;
  3787.       if (++bob->curr_frame>=bob->num_frames)
  3788.         bob->curr_frame = 0;
  3789.     }
  3790.   }
  3791.   //创建一个多帧的,支持动画序列的BOB
  3792.   else
  3793.   if (bob->attr & BOB_ATTR_MULTI_ANIM)
  3794.   {
  3795.     if (++bob->anim_counter>=bob->anim_count_max)
  3796.     {
  3797.       bob->anim_counter = 0;
  3798.       bob->anim_index++;
  3799.       //提取动画序列的下一帧
  3800.       bob->curr_frame = bob->animations[bob->curr_animation][bob->anim_index];
  3801.       //到了动画序列的末尾
  3802.       if (bob->curr_frame == -1)
  3803.       {
  3804.         //动画只播放一次
  3805.         if(bob->attr & BOB_ATTR_ANIM_ONE_SHOT)
  3806.         {
  3807.           bob->anim_state = BOB_STATE_ANIM_DONE;
  3808.           //使动画停留在最后一帧
  3809.           bob->anim_index--;
  3810.           bob->curr_frame = bob->animations[bob->curr_animation][bob->anim_index];
  3811.         }
  3812.         //动画重复播放
  3813.         else
  3814.         {
  3815.           //从第1帧重新开始
  3816.           bob->anim_index = 0;
  3817.           bob->curr_frame = bob->animations[bob->curr_animation][bob->anim_index];
  3818.         }
  3819.       }
  3820.     }
  3821.   }
  3822.   
  3823.   return(1);
  3824. }
  3825. int Move_BOB(BOB_PTR bob)
  3826. {
  3827.   //移动BOB(考虑到边界情况)
  3828.   if (!bob)
  3829.     return(0);
  3830.   bob->x+=bob->xv;
  3831.   bob->y+=bob->yv;
  3832.   //BOB对象在移出屏幕时卷到屏幕的另一边
  3833.   if (bob->attr & BOB_ATTR_WRAPAROUND)
  3834.   {
  3835.     if (bob->x>max_clip_x)
  3836.       bob->x = min_clip_x - bob->width;
  3837.     else
  3838.     if (bob->x < min_clip_x-bob->width)
  3839.       bob->x = max_clip_x;
  3840.     if (bob->y > max_clip_y)
  3841.       bob->y = min_clip_y - bob->height;
  3842.     else
  3843.     if (bob->y < min_clip_y-bob->height)
  3844.       bob->y = max_clip_y;
  3845.   }
  3846.   //BOB对象当碰到屏幕边界时像一个球一样反弹
  3847.   else
  3848.   if (bob->attr & BOB_ATTR_BOUNCE)
  3849.   {
  3850.     //仅仅是改变速度
  3851.     if ((bob->x > max_clip_x - bob->width) || (bob->x < min_clip_x) )
  3852.       bob->xv = -bob->xv;
  3853.     
  3854.     if ((bob->y > max_clip_y - bob->height) || (bob->y < min_clip_y) )
  3855.       bob->yv = -bob->yv;
  3856.   }
  3857.   return(1);
  3858. }
  3859. int Load_Animation_BOB(BOB_PTR bob, 
  3860.                        int anim_index,  //动画序列号
  3861.                        int num_frames,  //动画帧数
  3862.                        int *sequence)   //被加载的序列数组
  3863. {
  3864.   //此函数加载动画序列到BOB对象,加载的序列以-1结尾作为结束标记
  3865.   if (!bob)
  3866.     return(0);
  3867.   if (!(bob->animations[anim_index] = (int*)malloc((num_frames+1)*sizeof(int))))
  3868.     return(0);
  3869.   for (int index=0;index<num_frames;index++)
  3870.     bob->animations[anim_index][index] = sequence[index];
  3871.   bob->animations[anim_index][index] = -1;
  3872.   return(1);
  3873. }
  3874. int Set_Pos_BOB(BOB_PTR bob, int x, int y)
  3875. {
  3876.   //设置BOB对象的位置
  3877.   if (!bob)
  3878.     return(0);
  3879.   bob->x = x;
  3880.   bob->y = y;
  3881.   return(1);
  3882. }
  3883. int Set_Anim_Speed_BOB(BOB_PTR bob,int speed)
  3884. {
  3885.   //设置动画播放速度
  3886.   if (!bob)
  3887.     return(0);
  3888.   bob->anim_count_max = speed;
  3889.   return(1);
  3890. }
  3891. int Set_Animation_BOB(BOB_PTR bob, int anim_index)
  3892. {
  3893.   //此函数设置须播放的动画类别
  3894.   if(!bob)
  3895.     return(0);
  3896.   
  3897.   bob->curr_animation = anim_index;
  3898.   bob->anim_index =0;
  3899.   return(1);
  3900. }
  3901. int Set_Vel_BOB(BOB_PTR bob,int xv, int yv)
  3902. {
  3903.   //设置BOB速度
  3904.   if(!bob)
  3905.     return(0);
  3906.   bob->xv = xv;
  3907.   bob->yv = yv;
  3908.   return(1);
  3909. }
  3910. int Hide_BOB(BOB_PTR bob)
  3911. {
  3912.   //设置BOB不可见
  3913.   if(!bob)
  3914.     return(0);
  3915.   RESET_BIT(bob->attr,BOB_ATTR_VISIBLE);
  3916.   return(1);
  3917. }
  3918. int Show_BOB(BOB_PTR bob)
  3919. {
  3920.   //设置BOB可见
  3921.   if(!bob)
  3922.     return(0);
  3923.   SET_BIT(bob->attr,BOB_ATTR_VISIBLE);
  3924.   return(1);
  3925. }
  3926. int Collision_BOBS(BOB_PTR bob1, BOB_PTR bob2)
  3927. {
  3928.   //BOB对象碰撞检测
  3929.   if (!bob1 || !bob2)
  3930.     return(0);
  3931.   int width1  = (bob1->width>>1) - (bob1->width>>3);
  3932.   int height1 = (bob1->height>>1) - (bob1->height>>3);
  3933.   int width2  = (bob2->width>>1) - (bob2->width>>3);
  3934.   int height2 = (bob2->height>>1) - (bob2->height>>3);
  3935.   //计算BOB中心坐标
  3936.   int cx1 = bob1->x + width1;
  3937.   int cy1 = bob1->y + height1;
  3938.   int cx2 = bob2->x + width2;
  3939.   int cy2 = bob2->y + height2;
  3940.   int dx = abs(cx2 - cx1);
  3941.   int dy = abs(cy2 - cy1);
  3942.   //碰撞则返回1
  3943.   if (dx < (width1+width2) && dy < (height1+height2))
  3944.     return(1);
  3945.   else
  3946.     return(0);
  3947. }

 

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/我家自动化/article/detail/103418
推荐阅读
相关标签
  

闽ICP备14008679号