搜索
查看
编辑修改
首页
UNITY
NODEJS
PYTHON
AI
GIT
PHP
GO
CEF3
JAVA
HTML
CSS
搜索
我家自动化
这个屌丝很懒,什么也没留下!
关注作者
热门标签
jquery
HTML
CSS
PHP
ASP
PYTHON
GO
AI
C
C++
C#
PHOTOSHOP
UNITY
iOS
android
vue
xml
爬虫
SEO
LINUX
WINDOWS
JAVA
MFC
CEF3
CAD
NODEJS
GIT
Pyppeteer
article
热门文章
1
2022年5月、11月网络工程师真题详解_快速获得lun在某时刻完整数据拷贝
2
java markdown协作_课外资源 - 基于Java实现的多用户同步MarkDown编辑器
3
网络安全人才缺口巨大,现在网安工程师能挣多少钱?_网络安全工程师挣钱吗
4
Android AIDL 实现两个APP之间的跨进程通信实例_android 两个app类调用
5
python大一基础题_Python 基础练习题
6
java计算机毕业设计基于安卓Android/微信小程序的在线装修预定系统APP_基于安卓的家装erp系统设计
7
使用GitHub API 查询开源项目信息
8
Mac 系统安装maven_mac 安装 maven
9
【强化学习】PPO算法求解倒立摆问题 + Pytorch代码实战_ppo算法代码
10
Element-UI:el-table样式修改_el-table 样式修改
当前位置:
article
> 正文
T3D图形库(四)_t3d, 8cxvun0002
作者:我家自动化 | 2024-02-18 01:46:38
赞
踩
t3d, 8cxvun0002
DDraw及图形算法库文件部分
/*2008.9.16
T3D图形库
——<<windows游戏
编程大师技巧>>
*/
//DDraw_lib.cpp
// INCLUDES ///
#include <windows.h>
#include <windowsx.h>
#include <mmsystem.h> //多媒体API
#include <iostream.h>
#include <conio.h> //控制台IO支持
#include <stdlib.h> //声明定义的一些常用标准函数库
#include <malloc.h> //声明或定义一些内存的函数
#include <memory.h> //提供了内存操作相关的一些函数及声明
#include <string.h> //字符串的一些功能
#include <stdarg.h> //应付可变参数
#include <stdio.h> //efinitions/declarations for standard I/O routines
#include <math.h> //一些数学方法
#include <io.h> //declarations for low-level file handling and I/O functions
#include <fcntl.h> //文件控制操作
#include <sys/timeb.h>//附加的日期和时间定义
#include <time.h> //时间操作函数库
#include <ddraw.h>
#include "DDraw_lib.h"
// DEFINES
// TYPES //
// PROTOTYPES /
// EXTERNALS /
extern
HWND
main_window_handle;
extern
HINSTANCE
main_instance;
// GLOBALS
FILE
*fp_error = NULL;
char
error_filename[80];
//DirectDraw 接口指针
LPDIRECTDRAW7 lpdd =NULL;
LPDIRECTDRAWSURFACE7 lpddsprimary =NULL;
LPDIRECTDRAWSURFACE7 lpddsback =NULL;
LPDIRECTDRAWPALETTE lpddpal =NULL;
LPDIRECTDRAWCLIPPER lpddclipper =NULL;
LPDIRECTDRAWCLIPPER lpddclipperwin =NULL;
PALETTEENTRY palette[MAX_COLORS_PALETTE];
PALETTEENTRY save_palette[MAX_COLORS_PALETTE];
DDSURFACEDESC2 ddsd;
DDBLTFX ddbltfx;
DDSCAPS2 ddscaps;
HRESULT
ddrval;
UCHAR
*primary_buffer = NULL;
//主缓冲
UCHAR
*back_buffer = NULL;
//后备缓冲
int
primary_lpitch = 0;
//主缓冲内存行距
int
back_lpitch = 0;
//后备缓冲内存行距
BITMAP_FILE bitmap8bit;
BITMAP_FILE bitmap16bit;
BITMAP_FILE bitmap24bit;
DWORD
start_clock_count = 0;
int
windowed_mode = FALSE;
//裁剪矩形
int
min_clip_x = 0,
max_clip_x = (SCREEN_WIDTH-1),
min_clip_y = 0,
max_clip_y = (SCREEN_HEIGHT-1);
//屏幕相关信息,被DDraw_Init()重写
int
screen_width =SCREEN_WIDTH,
screen_height =SCREEN_HEIGHT,
screen_bpp =SCREEN_BPP,
screen_windowed =0;
int
dd_pixel_format =DD_PIXEL_FORMAT565;
//默认像素格式
int
window_client_x0 = 0;
//DirectDraw下窗口模式客户区起始地址坐标
int
window_client_y0 = 0;
float
cos_look[361];
//存储相应角度对应的弧度
float
sin_look[361];
//函数指针
USHORT
(*RGB16Bit)(
int
r,
int
g,
int
b) =NULL;
// FUNCTIONS //
USHORT
RGB16Bit565(
int
r,
int
g,
int
b)
{
r>>=3; g>>=2; b>>=3;
return
(_RGB16BIT565((r),(g),(b)));
}
USHORT
RGB16Bit555(
int
r,
int
g,
int
b)
{
r>>=3; g>>=3; b>>=3;
return
(_RGB16BIT555((r),(g),(b)));
}
inline
void
Mem_Set_WORD(
void
*dest,
USHORT
data,
int
count)
{
//把无符号16位data数据分count次传输到dest地址
_asm
{
mov edi,dest ;
mov ecx,count;
mov ax, data ;
rep stosw ;
}
}
inline
void
Mem_Set_QUAD(
void
*dest,
UINT
data,
int
count)
{
//把无符号32位data数据分count次传输到dest地址
_asm
{
mov edi, dest ;
mov ecx, count;
mov eax, data ;
rep stosd ;
}
}
LPDIRECTDRAWSURFACE7 DDraw_Create_Surface(
int
width,
int
height,
int
mem_flags
/* =0 */
,
USHORT
color_key_value
/* =0 */
)
{
DDSURFACEDESC2 ddsd;
LPDIRECTDRAWSURFACE7 lpdds;
DDRAW_INIT_STRUCT(ddsd);
//初始化ddsd
ddsd.dwFlags=DDSD_CAPS | DDSD_WIDTH | DDSD_HEIGHT;
//设置有效标志
ddsd.dwWidth=width;
ddsd.dwHeight=height;
ddsd.ddsCaps.dwCaps=DDSCAPS_OFFSCREENPLAIN | mem_flags;
//设置属性
if
(FAILED(lpdd->CreateSurface(&ddsd,&lpdds,NULL)))
//创造表面
return
(NULL);
DDCOLORKEY color_key;
color_key.dwColorSpaceLowValue=color_key_value;
color_key.dwColorSpaceHighValue=color_key_value;
lpdds->SetColorKey(DDCKEY_SRCBLT,&color_key);
//设置透明色键
return
(lpdds);
}
int
DDraw_Init(
int
width,
int
height,
int
bpp,
int
windowed)
{
int
index;
if
(FAILED(DirectDrawCreateEx(NULL,(
void
**)&lpdd,IID_IDirectDraw7,NULL)))
return
(0);
if
(windowed)
{
//设置协作模式(窗口模式)
if
(FAILED(lpdd->SetCooperativeLevel(main_window_handle,DDSCL_NORMAL)))
return
(0);
}
else
{
//设置协作模式(全屏模式)
if
(FAILED(lpdd->SetCooperativeLevel(main_window_handle,
DDSCL_ALLOWMODEX | DDSCL_FULLSCREEN |
DDSCL_EXCLUSIVE | DDSCL_ALLOWMODEX | DDSCL_MULTITHREADED)))
return
(0);
//设置显示模式
if
(FAILED(lpdd->SetDisplayMode(width,height,bpp,0,0)))
return
(0);
}
//设置全局变量
screen_height =height;
screen_width =width ;
screen_bpp =bpp;
screen_windowed=windowed;
//初始化DDSURFACEDESC2结构体
memset(&ddsd,0,
sizeof
(ddsd));
ddsd.dwSize=
sizeof
(ddsd);
if
(!screen_windowed)
{
//全屏模式
ddsd.dwFlags = DDSD_CAPS | DDSD_BACKBUFFERCOUNT;
ddsd.ddsCaps.dwCaps = DDSCAPS_PRIMARYSURFACE | DDSCAPS_FLIP | DDSCAPS_COMPLEX;
//设置后备缓冲数——窗口模式为0,全屏模式(双缓冲)为1,三缓冲为2
ddsd.dwBackBufferCount=1;
}
else
{
//窗口模式
ddsd.dwFlags=DDSD_CAPS;
ddsd.ddsCaps.dwCaps=DDSCAPS_PRIMARYSURFACE;
ddsd.dwBackBufferCount=0;
}
//创造主显示表面
lpdd->CreateSurface(&ddsd,&lpddsprimary,NULL);
//取得主显示表面的像素格式
DDPIXELFORMAT ddpf;
//初始化ddpf
DDRAW_INIT_STRUCT(ddpf);
//从主表面取得格式
lpddsprimary->GetPixelFormat(&ddpf);
dd_pixel_format=ddpf.dwRGBBitCount;
Write_Error(
"/npixel format = %d"
,dd_pixel_format);
//确定16位RGB格式(1.5.5.5或5.6.5)
if
(dd_pixel_format==DD_PIXEL_FORMAT555)
{
RGB16Bit = RGB16Bit555;
Write_Error(
"/npixel format = 5.5.5"
);
}
else
{
RGB16Bit = RGB16Bit565;
Write_Error(
"/npixel format = 5.6.5"
);
}
if
(!screen_windowed)
{
//全屏模式下需要一个后备缓冲
ddscaps.dwCaps=DDSCAPS_BACKBUFFER;
if
(FAILED(lpddsprimary->GetAttachedSurface(&ddscaps,&lpddsback)))
return
(0);
}
else
{
//否则创造一个离屏表面
lpddsback=DDraw_Create_Surface(width,height);
}
//创造一个调色板(仅适用8位模式)
if
(screen_bpp=DD_PIXEL_FORMAT8)
{
memset(palette,0,MAX_COLORS_PALETTE*
sizeof
(PALETTEENTRY));
//从文件中加载调色板项到palette
Load_Palette_From_File(DEFAULT_PALETTE_FILE,palette);
if
(screen_windowed)
{
//窗口模式,则调色板前/后10个索引设置为windows桌面颜色
for
(index=0;index<10;index++)
palette[index].peFlags=palette[index+246].peFlags=PC_EXPLICIT;
//创建调色板接口lpddpal(不允许256个索引)
if
(FAILED(lpdd->CreatePalette(DDPCAPS_8BIT | DDPCAPS_INITIALIZE,
palette,&lpddpal,NULL)))
return
(0);
}
else
{
//全屏模式
if
(FAILED(lpdd->CreatePalette(DDPCAPS_8BIT | DDPCAPS_INITIALIZE | DDPCAPS_ALLOW256,
palette,&lpddpal,NULL)))
return
(0);
}
//将调色板接口关联到主显示表面
if
(FAILED(lpddsprimary->SetPalette(lpddpal)))
return
(0);
}
//清空主/从显示表面
if
(screen_windowed)
{
DDraw_Fill_Surface(lpddsback,0);
}
else
{
DDraw_Fill_Surface(lpddsprimary,0);
DDraw_Fill_Surface(lpddsback,0);
}
//设置裁剪矩形(软件模拟算法时用)
min_clip_x = 0;
max_clip_x = screen_width-1;
min_clip_y = 0;
max_clip_y = screen_height-1;
//设置后备缓冲裁剪矩形(用于接口)
RECT screen_rect = { 0,0,screen_width,screen_height };
//创建后备缓冲裁剪器
if
(FAILED(lpddclipper = DDraw_Attach_Clipper(lpddsback,1,&screen_rect)))
return
(0);
//创建窗口模式裁剪器
if
(screen_windowed)
{
if
(FAILED(lpdd->CreateClipper(0,&lpddclipperwin,NULL)))
return
(0);
if
(FAILED(lpddclipperwin->SetHWnd(0,main_window_handle)))
return
(0);
if
(FAILED(lpddsprimary->SetClipper(lpddclipperwin)))
return
(0);
}
return
(1);
}
int
DDraw_Shutdown(
void
)
{
//释放申请的directdraw资源
//首先释放裁剪器
if
(lpddclipper)
lpddclipper->Release();
if
(lpddclipperwin)
lpddclipperwin->Release();
//释放调色板
if
(lpddpal)
lpddpal->Release();
//释放后备缓冲
if
(lpddsback)
lpddsback->Release();
//释放主缓冲
if
(lpddsprimary)
lpddsprimary->Release();
//释放directdraw对象
if
(lpdd)
lpdd->Release();
return
(1);
}
LPDIRECTDRAWCLIPPER DDraw_Attach_Clipper(LPDIRECTDRAWSURFACE7 lpdds,
int
num_rects,
LPRECT clip_list)
{
int
index;
LPDIRECTDRAWCLIPPER lpddclipper;
LPRGNDATA region_data;
//创建裁剪器对象
if
(FAILED(lpdd->CreateClipper(0,&lpddclipper,NULL)))
return
(0);
//创建裁剪序列
region_data = (LPRGNDATA)malloc(
sizeof
(RGNDATAHEADER)+num_rects*
sizeof
(RECT));
memcpy(region_data->Buffer,clip_list,
sizeof
(RECT)*num_rects);
region_data->rdh.dwSize =
sizeof
(RGNDATAHEADER);
region_data->rdh.iType =RDH_RECTANGLES;
region_data->rdh.nCount =num_rects;
region_data->rdh.nRgnSize =num_rects*
sizeof
(RECT);
region_data->rdh.rcBound.left =64000;
region_data->rdh.rcBound.top =64000;
region_data->rdh.rcBound.right =-64000;
region_data->rdh.rcBound.bottom=-64000;
for
(index=0; index<num_rects; index++)
{
//在所有RECT周围创建一个边界框并存储在rcBound中
if
(clip_list[index].left < region_data->rdh.rcBound.left)
region_data->rdh.rcBound.left = clip_list[index].left;
if
(clip_list[index].right > region_data->rdh.rcBound.right)
region_data->rdh.rcBound.right = clip_list[index].right;
if
(clip_list[index].top < region_data->rdh.rcBound.top)
region_data->rdh.rcBound.top = clip_list[index].top;
if
(clip_list[index].bottom > region_data->rdh.rcBound.bottom)
region_data->rdh.rcBound.bottom = clip_list[index].bottom;
}
//将裁减序列发送给裁剪器
if
(FAILED(lpddclipper->SetClipList(region_data,0)))
{
free(region_data);
return
(NULL);
}
//将裁剪器与表面相关联
if
(FAILED(lpdds->SetClipper(lpddclipper)))
{
free(region_data);
return
(NULL);
}
free(region_data);
return
(lpddclipper);
}
int
DDraw_Flip(
void
)
{
//此函数切换主显示表面和第二表面(这里是后备缓冲)
//测试表面是否被锁定
if
(primary_buffer||back_buffer)
return
(0);
if
(!screen_windowed)
while
(FAILED(lpddsprimary->Flip(NULL,DDFLIP_WAIT)));
else
{
RECT dest_rect;
//取得窗口矩形
GetWindowRect(main_window_handle,&dest_rect);
//确定窗口客户区坐标
dest_rect.left +=window_client_x0;
dest_rect.top +=window_client_y0;
dest_rect.right +=dest_rect.left+screen_width;
dest_rect.bottom +=dest_rect.top+screen_height;
//将后备缓冲blit到主缓冲的目标矩形内
if
(FAILED(lpddsprimary->Blt(&dest_rect,lpddsback,NULL,DDBLT_WAIT,NULL)))
return
(0);
}
return
(1);
}
int
DDraw_Wait_For_Vsync(
void
)
{
//等待垂直刷新
lpdd->WaitForVerticalBlank(DDWAITVB_BLOCKEND,0);
return
(1);
}
int
DDraw_Fill_Surface(LPDIRECTDRAWSURFACE7 lpdds,
USHORT
color, RECT *client
/* =NULL */
)
{
DDBLTFX ddbltfx;
DDRAW_INIT_STRUCT(ddbltfx);
ddbltfx.dwFillColor=color;
//向目标表面的目标矩形(null为整个表面)填充颜色
lpdds->Blt(client,
NULL,
NULL,
DDBLT_WAIT | DDBLT_COLORFILL,
&ddbltfx);
return
(1);
}
UCHAR
* DDraw_Lock_Surface(LPDIRECTDRAWSURFACE7 lpdds,
int
*lpitch)
{
//锁定表面
//如果表面无效
if
(!lpdds)
return
(NULL);
//表面有效,则锁定之
DDRAW_INIT_STRUCT(ddsd);
lpdds->Lock(NULL,&ddsd,DDLOCK_WAIT | DDLOCK_SURFACEMEMORYPTR,NULL);
if
(lpitch)
*lpitch = ddsd.lPitch;
//返回指向表面初始地址的指针
return
((
UCHAR
*)ddsd.lpSurface);
}
int
DDraw_Unlock_Surface(LPDIRECTDRAWSURFACE7 lpdds)
{
//解锁表面
if
(!lpdds)
return
(0);
lpdds->Unlock(NULL);
return
(1);
}
UCHAR
* DDraw_Lock_Primary_Surface(
void
)
{
//如果已经被锁定(主缓冲首地址存在)
if
(primary_buffer)
{
return
(primary_buffer);
}
DDRAW_INIT_STRUCT(ddsd);
lpddsprimary->Lock(NULL,&ddsd,DDLOCK_SURFACEMEMORYPTR | DDLOCK_WAIT,NULL);
primary_buffer = (
UCHAR
*)ddsd.lpSurface;
primary_lpitch = ddsd.lPitch;
return
(primary_buffer);
}
int
DDraw_Unlock_Primary_Surface(
void
)
{
//解锁主显示表面
if
(!primary_buffer)
return
(0);
lpddsprimary->Unlock(NULL);
primary_buffer = NULL;
primary_lpitch = 0;
return
(1);
}
UCHAR
* DDraw_Lock_Back_Surface(
void
)
{
//锁定后备显示表面
if
(back_buffer)
{
return
(back_buffer);
}
DDRAW_INIT_STRUCT(ddsd);
lpddsback->Lock(NULL,&ddsd,DDLOCK_WAIT | DDLOCK_SURFACEMEMORYPTR,NULL);
back_buffer=(
UCHAR
*)ddsd.lpSurface;
back_lpitch=ddsd.lPitch;
return
(back_buffer);
}
int
DDraw_Unlock_Back_Surface(
void
)
{
//解锁后备显示表面
if
(!back_buffer)
return
(0);
lpddsback->Unlock(NULL);
back_buffer=NULL;
back_lpitch=0;
return
(1);
}
DWORD
Get_Clock(
void
)
{
//返回当前时间片
return
(GetTickCount());
}
DWORD
Start_Clock(
void
)
{
//记录开始时间
return
(start_clock_count=Get_Clock());
}
DWORD
Wait_Clock(
DWORD
count)
{
while
((Get_Clock() - start_clock_count)<count);
return
(Get_Clock());
}
Draw_Clip_Line16(
int
x0,
int
y0,
int
x1,
int
y1,
int
color,
UCHAR
* dest_buffer,
int
lpitch)
{
//画经裁剪的直线(16位)
int
cxs,cys,cxe,cye;
cxs=x0;
cys=y0;
cxe=x1;
cye=y1;
if
(Clip_Line(cxs,cys,cxe,cye))
Draw_Line16(cxs,cys,cxe,cye,color,dest_buffer,lpitch);
return
(1);
}
Draw_Clip_Line(
int
x0,
int
y0,
int
x1,
int
y1,
int
color,
UCHAR
* dest_buffer,
int
lpitch)
{
//画经裁剪的直线(8位)
int
cxs,cys,cxe,cye;
cxs=x0;
cys=y0;
cxe=x1;
cye=y1;
if
(Clip_Line(cxs,cys,cxe,cye))
Draw_Line(cxs,cys,cxe,cye,color,dest_buffer,lpitch);
return
(1);
}
Clip_Line(
int
&x1,
int
&y1,
int
&x2,
int
&y2)
{
//裁剪直线
#define CLIP_CODE_C 0x0000
#define CLIP_CODE_N 0x0008
#define CLIP_CODE_S 0x0004
#define CLIP_CODE_E 0x0002
#define CLIP_CODE_W 0x0001
#define CLIP_CODE_NE 0x000a
#define CLIP_CODE_SE 0x0006
#define CLIP_CODE_NW 0x0009
#define CLIP_CODE_SW 0x0005
int
xc1=x1,
yc1=y1,
xc2=x2,
yc2=y2;
int
p1_code=0,
p2_code=0;
//确定两点的位置
if
(y1<min_clip_y)
p1_code|=CLIP_CODE_N;
else
if
(y1>max_clip_y)
p1_code|=CLIP_CODE_S;
if
(x1<min_clip_x)
p1_code|=CLIP_CODE_W;
else
if
(x1>max_clip_x)
p1_code|=CLIP_CODE_E;
if
(y2<min_clip_y)
p2_code|=CLIP_CODE_N;
else
if
(y2>max_clip_y)
p2_code|=CLIP_CODE_S;
if
(x2<min_clip_x)
p2_code|=CLIP_CODE_W;
else
if
(x2>max_clip_x)
p2_code|=CLIP_CODE_E;
//若两点在剪切区域外且在同一方向
if
((p1_code&p2_code))
return
(0);
//若两点都在剪切区域内
if
(p1_code==0&&p2_code==0)
return
(1);
switch
(p1_code)
{
case
CLIP_CODE_C:
break
;
case
CLIP_CODE_N:
{
yc1=min_clip_y;
xc1=x1+(min_clip_y-y1)*(x2-x1)/(y2-y1);
}
break
;
case
CLIP_CODE_S:
{
yc1=max_clip_y;
xc1=x1+(max_clip_y-y1)*(x2-x1)/(y2-y1);
}
break
;
case
CLIP_CODE_W:
{
xc1=min_clip_x;
yc1=y1+(min_clip_x-x1)*(y2-y1)/(x2-x1);
}
break
;
case
CLIP_CODE_E:
{
xc1=max_clip_x;
yc1=y1+(max_clip_x-x1)*(y2-y1)/(x2-x1);
}
break
;
case
CLIP_CODE_NE:
{
yc1=min_clip_y;
xc1=x1+(min_clip_y-y1)*(x2-x1)/(y2-y1);
if
(xc1<min_clip_x||xc1>max_clip_x)
{
xc1=max_clip_x;
yc1=y1+(max_clip_x-x1)*(y2-y1)/(x2-x1);
}
}
break
;
case
CLIP_CODE_SE:
{
yc1=max_clip_y;
xc1=x1+(max_clip_y-y1)*(x2-x1)/(y2-y1);
if
(xc1<min_clip_x||xc1>max_clip_x)
{
xc1=max_clip_x;
yc1=y1+(max_clip_x-x1)*(y2-y1)/(x2-x1);
}
}
break
;
case
CLIP_CODE_NW:
{
yc1=min_clip_y;
xc1=x1+(min_clip_y-y1)*(x2-x1)/(y2-y1);
if
(xc1<min_clip_x||xc1>max_clip_x)
{
xc1=min_clip_x;
yc1=y1+(min_clip_x-x1)*(y2-y1)/(x2-x1);
}
}
break
;
case
CLIP_CODE_SW:
{
yc1=max_clip_y;
xc1=x1+(max_clip_y-y1)*(x2-x1)/(y2-y1);
if
(xc1<min_clip_x||xc2>max_clip_x)
{
xc1=min_clip_x;
yc1=y1+(min_clip_x-x1)*(y2-y1)/(x2-x1);
}
}
break
;
default
:
break
;
}
switch
(p2_code)
{
case
CLIP_CODE_C:
break
;
case
CLIP_CODE_N:
{
yc2=min_clip_y;
xc2=x2+(min_clip_y-y2)*(x2-x1)/(y2-y1);
}
break
;
case
CLIP_CODE_S:
{
yc2=max_clip_y;
xc2=x2+(max_clip_y-y2)*(x2-x1)/(y2-y1);
}
break
;
case
CLIP_CODE_W:
{
xc2=min_clip_x;
yc2=y2+(min_clip_x-x2)*(y2-y1)/(x2-x1);
}
break
;
case
CLIP_CODE_E:
{
xc2=max_clip_x;
yc2=y2+(max_clip_x-x2)*(y2-y1)/(x2-x1);
}
break
;
case
CLIP_CODE_NE:
{
yc2=min_clip_y;
xc2=x2+(min_clip_y-y2)*(x2-x1)/(y2-y1);
if
(xc2<min_clip_x||xc2>max_clip_x)
{
xc2=max_clip_x;
yc2=y2+(max_clip_x-x2)*(y2-y1)/(x2-x1);
}
}
break
;
case
CLIP_CODE_SE:
{
yc2=max_clip_y;
xc2=x2+(max_clip_y-y2)*(x2-x1)/(y2-y1);
if
(xc2<min_clip_x||xc2>max_clip_x)
{
xc2=max_clip_x;
yc2=y2+(max_clip_x-x2)*(y2-y1)/(x2-x1);
}
}
break
;
case
CLIP_CODE_NW:
{
yc2=min_clip_y;
xc2=x2+(min_clip_y-y2)*(x2-x1)/(y2-y1);
if
(xc2<min_clip_x||xc2>max_clip_x)
{
xc2=min_clip_x;
yc2=y2+(min_clip_x-x2)*(y2-y1)/(x2-x1);
}
}
break
;
case
CLIP_CODE_SW:
{
yc2=max_clip_y;
xc2=x2+(max_clip_y-y2)*(x2-x1)/(y2-y1);
if
(xc2<min_clip_x||xc2>max_clip_x)
{
xc2=min_clip_x;
yc2=y2+(min_clip_x-x2)*(y2-y1)/(x2-x1);
}
}
break
;
default
:
break
;
}
if
( (xc1<min_clip_x)||(xc1>max_clip_x)||
(yc1<min_clip_y)||(yc1>max_clip_y)||
(xc2<min_clip_x)||(xc2>max_clip_x)||
(yc2<min_clip_y)||(yc2>max_clip_y) )
{
//若经过裁剪仍有点在剪切区域外,
//则剪切区域内不存在要画的直线
return
(0);
}
//否则修改直线的两个端点坐标
x1=xc1;
y1=yc1;
x2=xc2;
y2=yc2;
return
(1);
}
int
Draw_Line(
int
x0,
int
y0,
int
x1,
int
y1,
int
color,
UCHAR
* vb_start,
int
lpitch)
{
/*Bresenham算法画线*/
int
dx,
dy,
dx2,
dy2,
x_inc,
y_inc,
error,
index;
//取得直线的第一个点(像素)
vb_start=vb_start+x0+y0*lpitch;
dx=x1-x0;
dy=y1-y0;
if
(dx>=0)
x_inc=1;
else
{
x_inc=-1;
dx=-dx;
}
if
(dy>=0)
y_inc=lpitch;
else
{
y_inc=-lpitch;
dy=-dy;
}
dx2=dx<<1;
dy2=dy<<1;
if
(dx>dy)
{
/*斜率<1的情况*/
error=dy2-dx;
for
(index=0;index<=dx;index++)
{
*vb_start=color;
if
(error>=0)
{
error-=dx2;
vb_start+=y_inc;
}
error+=dy2;
vb_start+=x_inc;
}
}
else
{
/*斜率>1的情况*/
error=dx2-dy;
for
(index=0;index<=dy;index++)
{
*vb_start=color;
if
(error>=0)
{
error-=dy2;
vb_start+=x_inc;
}
error+=dx2;
vb_start+=y_inc;
}
}
return
(1);
}
int
Draw_Line16(
int
x0,
int
y0,
int
x1,
int
y1,
int
color,
UCHAR
*vb_start,
int
lpitch)
{
int
dx,
dy,
dx2,
dy2,
x_inc,
y_inc,
error,
index;
//将字节间距转换为USHORT间距
int
lpitch_2 = lpitch>>1;
//确定直线首地址
USHORT
* vb_start2=(
USHORT
*)vb_start + x0 + y0*lpitch_2;
dx = x1 - x0;
dy = y1 - y0;
if
(dx>=0)
{
x_inc = 1;
}
else
{
x_inc = -1;
dx = -dx;
}
if
(dy>=0)
{
y_inc = lpitch_2;
}
else
{
y_inc = -lpitch_2;
dy = -dy;
}
dx2 = dx<<1;
dy2 = dy<<1;
if
(dx>dy)
{
//斜率小于1的情况
error = dy2 - dx;
for
(index=0;index<=dx;index++)
{
//设置像素
*vb_start2 = (
USHORT
)color;
if
(error>=0)
{
error-=dx2;
vb_start2+=y_inc;
}
error+=dy2;
vb_start2+=x_inc;
}
}
else
{
//斜率大于1的情况
error = dx2 -dy;
for
(index=0;index<=dy;index++)
{
*vb_start2 = (
USHORT
)color;
if
(error>=0)
{
error-=dy2;
vb_start2+=x_inc;
}
error+=dx2;
vb_start2+=y_inc;
}
}
return
(1);
}
int
Draw_Pixel(
int
x,
int
y,
int
color,
UCHAR
*video_buffer,
int
lpitch)
{
//画像素
video_buffer[x+y*lpitch] = color;
return
(1);
}
int
Draw_Pixel16(
int
x,
int
y,
int
color,
UCHAR
*video_buffer,
int
lpitch)
{
((
USHORT
*)video_buffer)[x+y*(lpitch>>1)] = color;
return
(1);
}
int
Draw_Rectangle(
int
x1,
int
y1,
int
x2,
int
y2,
int
color,
LPDIRECTDRAWSURFACE7 lpdds)
{
//填充矩形
DDBLTFX ddbltfx;
//目标矩形
RECT fill_area;
DDRAW_INIT_STRUCT(ddbltfx);
//填充颜色
ddbltfx.dwFillColor = color;
//y1>y2?x1>x2?
fill_area.top = y1;
fill_area.left = x1;
fill_area.bottom = y2;
fill_area.right = x2;
lpdds->Blt(&fill_area,
NULL,
NULL,
DDBLT_COLORFILL | DDBLT_WAIT,
&ddbltfx);
return
(1);
}
int
Set_Palette_Entry(
int
color_index, LPPALETTEENTRY color)
{
//更改调色板相应索引号的颜色
lpddpal->SetEntries(0,color_index,1,color);
//更改调色板对象数组
memcpy(&palette[color_index],color,
sizeof
(PALETTEENTRY));
return
(1);
}
int
Get_Palette_Entry(
int
color_index, LPPALETTEENTRY color)
{
//取得调色板索引对应的palette存放在color地址处
memcpy(color,&palette[color_index],
sizeof
(PALETTEENTRY));
return
(1);
}
int
Load_Palette_From_File(
char
*filename, LPPALETTEENTRY palette)
{
FILE
*fp_file;
//文件指针
if
((fp_file=fopen(filename,
"r"
))==NULL)
//以'读'模式打开文件
return
(0);
for
(
int
index=0; index<MAX_COLORS_PALETTE;index++)
{
//从文件中读出R.G.B.F值赋给palette对象
fscanf(fp_file,
"%d %d %d %d"
,&palette[index].peRed,
&palette[index].peGreen,
&palette[index].peBlue,
&palette[index].peFlags);
}
fclose(fp_file);
return
(1);
}
int
Save_Palette_To_File(
char
*filename, LPPALETTEENTRY palette)
{
FILE
* fp_file;
if
((fp_file=fopen(filename,
"w"
))==NULL)
//以"写"方式打开文件
return
(0);
for
(
int
index=0;index<MAX_COLORS_PALETTE;index++)
{
fprintf(fp_file,
"/n%d %d %d %d"
,palette[index].peRed,
palette[index].peGreen,
palette[index].peBlue,
palette[index].peFlags);
}
fclose(fp_file);
return
(1);
}
int
Save_Palette(LPPALETTEENTRY sav_palette)
{
//保存palette对象至sav_palette对象
memcpy(sav_palette,palette,MAX_COLORS_PALETTE*
sizeof
(PALETTEENTRY));
return
(1);
}
int
Set_Palette(LPPALETTEENTRY set_palette)
{
//设置调色板
//更改palette对象
memcpy(palette,set_palette,MAX_COLORS_PALETTE*
sizeof
(PALETTEENTRY));
//更改与显示表面关联的调色板项
lpddpal->SetEntries(0,0,MAX_COLORS_PALETTE,palette);
return
(1);
}
int
Rotate_Colors(
int
start_index,
int
end_index)
{
//取得需改变的调色板项数
int
colors = end_index -start_index + 1;
PALETTEENTRY work_pal[MAX_COLORS_PALETTE];
//取得需改变的调色板项存放在work_pal对象中
lpddpal->GetEntries(0,start_index,colors,work_pal);
//调色板项右移一位(最后一位放置第一位)
lpddpal->SetEntries(0,start_index+1,colors-1,work_pal);
lpddpal->SetEntries(0,start_index,1,&work_pal[colors-1]);
//更新palette对象
lpddpal->GetEntries(0,0,MAX_COLORS_PALETTE,palette);
return
(1);
}
int
Blink_Colors(
int
command, BLINKER_PTR new_light,
int
id)
{
//闪烁像素
static
BLINKER lights[256];
static
int
initialized = 0;
if
(!initialized)
{
initialized = 1;
memset((
void
*)lights,0,
sizeof
(lights));
}
switch
(command)
{
case
BLINKER_ADD :
{
for
(
int
index=0;index<256;index++)
{
if
(lights[index].state==0)
{
lights[index] = *new_light;
lights[index].counter = 0;
lights[index].state = -1;
//初始化为关(灯)
lpddpal->SetEntries(0,lights[index].color_index,1,&lights[index].off_color);
return
(index);
}
}
}
break
;
case
BLINKER_DELETE:
{
//删除闪烁灯
if
(lights[id].state!=0)
{
memset((
void
*)&lights[id],0,
sizeof
(BLINKER));
return
(id);
}
else
return
(-1);
}
break
;
case
BLINKER_UPDATE:
{
//更新闪烁灯
if
(lights[id].state!=0)
{
lights[id].on_color = new_light->on_color;
lights[id].off_color = new_light->off_color;
lights[id].on_time = new_light->on_time;
lights[id].off_time = new_light->off_time;
if
(lights[id].state==-1)
lpddpal->SetEntries(0,lights[id].color_index,1,&lights[id].off_color);
else
lpddpal->SetEntries(0,lights[id].color_index,1,&lights[id].on_color);
return
(id);
}
else
return
(-1);
}
break
;
case
BLINKER_RUN:
{
//运行闪烁灯
for
(
int
index=0;index<256;index++)
{
if
(lights[index].state==-1)
{
//如果闪烁灯是关着的
if
(++lights[index].counter>=lights[index].off_time)
{
//当计数器超过预定的关灯时间
lights[index].counter = 0;
//计数器清零
lights[index].state = - lights[index].state;
//改变灯的开关状态
lpddpal->SetEntries(0,lights[index].color_index,1,&lights[index].on_color);
}
}
else
if
(lights[index].state ==1)
{
if
(++lights[index].counter >= lights[index].on_time)
{
lights[index].counter = 0;
lights[index].state = -lights[index].state;
lpddpal->SetEntries(0,lights[index].color_index,1,&lights[index].off_color);
}
}
}
}
break
;
}
//end switch
return
(1);
}
int
Draw_Text_GDI(
char
*text,
int
x,
int
y,
COLORREF
color, LPDIRECTDRAWSURFACE7 lpdds)
{
//传入COLORREF结构
HDC
xdc;
if
(FAILED(lpdds->GetDC(&xdc)))
return
(0);
SetTextColor(xdc,color);
SetBkMode(xdc,TRANSPARENT);
TextOut(xdc,x,y,text,strlen(text));
lpdds->ReleaseDC(xdc);
return
(1);
}
int
Draw_Text_GDI(
char
*text,
int
x,
int
y,
int
color, LPDIRECTDRAWSURFACE7 lpdds)
{
//传入颜色索引
HDC
xdc;
if
(FAILED(lpdds->GetDC(&xdc)))
return
(0);
SetTextColor(xdc,RGB(palette[color].peRed,palette[color].peGreen,palette[color].peBlue) );
SetBkMode(xdc,TRANSPARENT);
TextOut(xdc,x,y,text,strlen(text));
lpdds->ReleaseDC(xdc);
return
(1);
}
int
Open_Error_File(
char
*filename,
FILE
*fp_override
/* =NULL */
)
{
//打开误差文件
if
(fp_override)
{
//如果误差文件是打开的
fp_error = fp_override;
}
else
{
//误差文件没打开,则打开它
if
((fp_error = fopen(filename,
"w"
))==NULL)
return
(0);
}
struct
_timeb
timebuffer;
char
*timeline;
char
timestring[280];
_ftime(&timebuffer);
timeline = ctime(&(timebuffer.time));
//ctime()将本地时间格式化为字符串,保存在timeline地址处
//先输出timeline地址处的前19位,在加上.毫秒数,最后加上年份
sprintf(timestring,
"%.19s.%hu,%s"
,timeline,timebuffer.millitm,&timeline[20]);
Write_Error(
"/nOpening Error Output File (%s) on %s/n"
,filename,timestring);
if
(!fp_override)
{
//为什么要重新打开? 也许是想把文件指针定位在文件末尾
fclose(fp_error);
//'a+' 读写方式打开,将文件指针指向文件末尾。如果文件不存在则尝试创建之。
if
((fp_error = fopen(filename,
"a+"
))==NULL)
return
(0);
}
return
(1);
}
int
Close_Error_File(
void
)
{
//关闭误差文件
if
(fp_error)
{
Write_Error(
"/nClosing Error Output File."
);
if
(fp_error!=stdout || fp_error!=stderr)
//?
{
fclose(fp_error);
}
fp_error = NULL;
return
(1);
}
else
return
(0);
}
int
Write_Error(
char
*string, ...)
{
//写入误差文件
char
buffer[80];
va_list
arglist;
if
(!string || !fp_error)
return
(0);
va_start(arglist,string);
vsprintf(buffer,string,arglist);
va_end(arglist);
fprintf(fp_error,buffer);
fflush(fp_error);
return
(1);
}
int
Load_Bitmap_File(BITMAP_FILE_PTR bitmap,
char
*filename)
{
int
file_handle,
index;
UCHAR
*temp_buffer = NULL;
OFSTRUCT file_data;
if
((file_handle = OpenFile(filename,&file_data,OF_READ))==-1)
return
(0);
//读位图文件头
_lread(file_handle,&bitmap->bitmapfileheader,
sizeof
(BITMAPFILEHEADER));
//bmp文件标志 'bm'(0x4D42)
if
(bitmap->bitmapfileheader.bfType!=BITMAP_ID)
{
_lclose(file_handle);
return
(0);
}
//读信息头结构
_lread(file_handle,&bitmap->bitmapinfoheader,
sizeof
(BITMAPINFOHEADER));
//如果位图有调色板则加载它
if
(bitmap->bitmapinfoheader.biBitCount == 8)
{
_lread(file_handle,&bitmap->palette,MAX_COLORS_PALETTE*
sizeof
(PALETTEENTRY));
for
(index=0;index<MAX_COLORS_PALETTE;index++)
{
//位图图像调色板数据格式为(B.G.R)
BYTE
temp_color = bitmap->palette[index].peRed;
bitmap->palette[index].peRed = bitmap->palette[index].peBlue;
bitmap->palette[index].peBlue = temp_color;
bitmap->palette[index].peFlags = PC_NOCOLLAPSE;
}
}
//定位文件指针(定位到文件末再向上移动biSizeImage字节)
_lseek(file_handle,-(
int
)(bitmap->bitmapinfoheader.biSizeImage),SEEK_END);
//位图像素格式为8位或16位
if
(bitmap->bitmapinfoheader.biBitCount==8 || bitmap->bitmapinfoheader.biBitCount==16)
{
//16位难道不用对调 R&B ??
if
(bitmap->buffer)
{
free(bitmap->buffer);
}
if
(!(bitmap->buffer = (
UCHAR
*)malloc(bitmap->bitmapinfoheader.biSizeImage)))
{
_lclose(file_handle);
return
(0);
}
//读位图数据到bitmap对象的缓冲区
_lread(file_handle,bitmap->buffer,bitmap->bitmapinfoheader.biSizeImage);
}
else
if
(bitmap->bitmapinfoheader.biBitCount==24)
{
//取得位图数据大小并为其开辟内存 首地址置于临时缓冲区
if
(!(temp_buffer = (
UCHAR
*)malloc(bitmap->bitmapinfoheader.biSizeImage)))
{
_lclose(file_handle);
return
(0);
}
//开辟16位位图数据区首地址置于bitmap对象的缓冲区(biWidth/biHeight以像素为单位)
if
(!(bitmap->buffer=(
UCHAR
*)malloc(2*bitmap->bitmapinfoheader.biWidth*bitmap->bitmapinfoheader.biHeight)))
{
_lclose(file_handle);
free(temp_buffer);
return
(0);
}
//位图数据copy到临时缓冲区
_lread(file_handle,temp_buffer,bitmap->bitmapinfoheader.biSizeImage);
for
(index=0;index<bitmap->bitmapinfoheader.biWidth*bitmap->bitmapinfoheader.biHeight;index++)
{
USHORT
color;
//位图图像数据
if
(dd_pixel_format==DD_PIXEL_FORMAT555)
{
UCHAR
blue = (temp_buffer[index*3+0]>>3),
green = (temp_buffer[index*3+1]>>3),
red = (temp_buffer[index*3+2]>>3);
color = _RGB16BIT555(red,green,blue);
}
else
if
(dd_pixel_format==DD_PIXEL_FORMAT565)
{
UCHAR
blue = (temp_buffer[index*3+0]>>3),
green = (temp_buffer[index*3+1]>>2),
red = (temp_buffer[index*3+2]>>3);
color = _RGB16BIT565(red,green,blue);
}
((
USHORT
*)bitmap->buffer)[index] = color;
}
// end for index
bitmap->bitmapinfoheader.biBitCount = 16;
free(temp_buffer);
}
// end if 24 bit
else
{
return
(0);
}
#if 0
// write the file info out
printf(
"/nfilename:%s /nsize=%d /nwidth=%d /nheight=%d /nbitsperpixel=%d /ncolors=%d /nimpcolors=%d"
,
filename,
bitmap->bitmapinfoheader.biSizeImage,
bitmap->bitmapinfoheader.biWidth,
bitmap->bitmapinfoheader.biHeight,
bitmap->bitmapinfoheader.biBitCount,
bitmap->bitmapinfoheader.biClrUsed,
bitmap->bitmapinfoheader.biClrImportant);
#endif
_lclose(file_handle);
//颠倒bitmap对象中的位图数据
Flip_Bitmap(bitmap->buffer,
bitmap->bitmapinfoheader.biWidth*(bitmap->bitmapinfoheader.biBitCount/8),
bitmap->bitmapinfoheader.biHeight);
return
(1);
}
int
Unload_Bitmap_File(BITMAP_FILE_PTR bitmap)
{
if
(bitmap->buffer)
{
free(bitmap->buffer);
bitmap->buffer = NULL;
}
return
(1);
}
int
Flip_Bitmap(
UCHAR
*image,
int
bytes_per_line,
int
height)
{
//颠倒位图数据
UCHAR
*buffer;
int
index;
if
(!(buffer = (
UCHAR
*)malloc(bytes_per_line*height)))
return
(0);
memcpy(buffer,image,bytes_per_line*height);
for
(index=0;index<height;index++)
{
memcpy(&image[((height-1)-index)*bytes_per_line],
&buffer[index*bytes_per_line],bytes_per_line);
}
free(buffer);
buffer = NULL;
return
(1);
}
int
Create_Bitmap(BITMAP_IMAGE_PTR image,
int
x,
int
y,
int
width,
int
height,
int
bpp
/* =8 */
)
{
//创建一个宽width高height色深为bpp在屏幕(x,y)处的空的位图图像
if
(!(image->buffer = (
UCHAR
*)malloc(width*height*(bpp>>3))))
return
(0);
image->state = BITMAP_STATE_ALIVE;
image->attr = 0;
image->width = width;
image->height = height;
image->bpp = bpp;
image->x = x;
image->y = y;
image->num_bytes = width*height*(bpp>>3);
memset(image->buffer,0,image->num_bytes);
return
(1);
}
int
Destroy_Bitmap(BITMAP_IMAGE_PTR image)
{
//销毁位图图像
if
(image && image->buffer)
{
free(image->buffer);
image->buffer = NULL;
memset(image,0,
sizeof
(BITMAP_IMAGE));
return
(1);
}
else
return
(0);
}
int
Draw_Bitmap(BITMAP_IMAGE_PTR source_bitmap,
UCHAR
*dest_buffer,
int
lpitch,
int
transparent)
{
//绘制位图
//当创建好一个大小指定内容为空的位图内存区后从位图文件的缓冲区中读入指定的位图图像数据与空内存区
//然后将此内存区的位图图像经过本函数绘制在指定区域(dest_buffer)
//位图是否被加载
if
(!(source_bitmap->attr & BITMAP_ATTR_LOADED))
return
(0);
UCHAR
*dest_addr,
//目标地址
*source_addr;
//源地址
UCHAR
pixel;
int
index,
pixel_x;
dest_addr = dest_buffer + source_bitmap->y*lpitch + source_bitmap->x;
source_addr =source_bitmap->buffer;
if
(transparent)
{
//如果位图图像透明,则逐字节copy,此处height/width单位为像素
for
(index=0;index<source_bitmap->height;index++)
{
for
(pixel_x=0;pixel_x<source_bitmap->width;pixel_x++)
{
if
((pixel = source_addr[pixel_x])!=0)
dest_addr[pixel_x]=pixel;
}
dest_addr +=lpitch;
//目标地址向下移动一行
source_addr += source_bitmap->width;
//源地址(位图图像)向下移动一行
}
}
else
{
//位图不透明的情况则逐行copy
for
(index=0;index<source_bitmap->height;index++)
{
memcpy(dest_addr,source_addr,source_bitmap->width);
dest_addr +=lpitch;
source_addr+=source_bitmap->width;
}
}
return
(1);
}
int
Draw_Bitmap16(BITMAP_IMAGE_PTR source_bitmap,
UCHAR
*dest_buffer,
int
lpitch,
int
transparent)
{
//绘制位图(16位)
//当创建好一个大小指定内容为空的位图内存区后从位图文件的缓冲区中读入指定的位图图像数据与空内存区
//然后将此内存区的位图图像经过本函数绘制在指定区域(dest_buffer)
//位图是否被加载
if
(!(source_bitmap->attr & BITMAP_ATTR_LOADED))
return
(0);
USHORT
*dest_addr,
//目标地址
*source_addr;
//源地址
USHORT
pixel;
int
index,
pixel_x,
lpitch_2 = lpitch >> 1;
dest_addr = ((
USHORT
*)dest_buffer) + source_bitmap->y*lpitch_2 + source_bitmap->x;
source_addr = (
USHORT
*) source_bitmap->buffer;
if
(transparent)
{
//如果位图图像透明,则逐字节copy,此处height/width单位为像素
for
(index=0;index<source_bitmap->height;index++)
{
for
(pixel_x=0;pixel_x<source_bitmap->width;pixel_x++)
{
if
((pixel = source_addr[pixel_x])!=0)
dest_addr[pixel_x]=pixel;
}
dest_addr +=lpitch;
//目标地址向下移动一行
source_addr += source_bitmap->width;
//源地址(位图图像)向下移动一行
}
}
else
{
//位图不透明的情况则逐行copy
int
source_bytes_per_line = source_bitmap->width*2;
for
(index=0;index<source_bitmap->height;index++)
{
memcpy(dest_addr,source_addr,source_bytes_per_line);
dest_addr +=lpitch_2;
source_addr+=source_bitmap->width;
}
}
return
(1);
}
int
Load_Image_Bitmap(BITMAP_IMAGE_PTR image,BITMAP_FILE_PTR bitmap,
int
cx,
int
cy,
int
mode)
{
//此函数从一个位图文件对象(BITMAP_FILE)的buffer区读入位图图像数据至image对象的buffer区
//如果没有创建位图图像内存区(BITMAP_IMAGE)
if
(!image)
return
(0);
UCHAR
*source_ptr,
*dest_ptr;
if
(mode==BITMAP_EXTRACT_MODE_CELL)
{
//如果是位图图像模板模式则计算选择的目标图像的实际坐标
cx = cx*(image->width+1) + 1;
cy = cy*(image->height+1) +1;
}
source_ptr = bitmap->buffer + cy*bitmap->bitmapinfoheader.biWidth+cx;
dest_ptr = (
UCHAR
*) image->buffer;
for
(
int
index_y=0;index_y<image->height;index_y++)
{
memcpy(dest_ptr,source_ptr,image->width);
dest_ptr += image->width;
source_ptr += bitmap->bitmapinfoheader.biWidth;
}
image->attr |=BITMAP_ATTR_LOADED;
return
(1);
}
int
Load_Image_Bitmap16(BITMAP_IMAGE_PTR image,BITMAP_FILE_PTR bitmap,
int
cx,
int
cy,
int
mode)
{
//此函数从一个位图文件对象(BITMAP_FILE)的buffer区读入位图图像数据至image对象的buffer区(16位)
//如果没有创建位图图像内存区(BITMAP_IMAGE)
if
(!image)
return
(0);
USHORT
*source_ptr,
*dest_ptr;
if
(mode==BITMAP_EXTRACT_MODE_CELL)
{
//如果是位图图像模板模式则计算选择的目标图像的实际坐标
cx = cx*(image->width+1) + 1;
cy = cy*(image->height+1) +1;
}
source_ptr =(
USHORT
*)bitmap->buffer + cy*bitmap->bitmapinfoheader.biWidth+cx;
dest_ptr = (
USHORT
*) image->buffer;
int
bytes_per_line = image->width*2;
for
(
int
index_y=0;index_y<image->height;index_y++)
{
memcpy(dest_ptr,source_ptr,bytes_per_line);
dest_ptr += image->width;
source_ptr += bitmap->bitmapinfoheader.biWidth;
}
image->attr |=BITMAP_ATTR_LOADED;
return
(1);
}
int
Scroll_Bitmap(BITMAP_IMAGE_PTR image,
int
dx,
int
dy
/* =0 */
)
{
//卷动位图图像(自适应8位和16位)
BITMAP_IMAGE temp_image;
//临时位图图像对象
if
(!image || (dx==0 && dy==0))
return
(0);
if
(dx!=0)
{
dx %= image->width;
if
(dx>0)
{
//向右卷动
//创建一个宽dx,高height的位图图像
Create_Bitmap(&temp_image,0,0,dx,image->height,image->bpp);
//将源位图图像从(width-dx,0)坐标开始,copy宽为dx高为height的图像数据至临时位图图像
Copy_Bitmap(&temp_image,0,0,
image,image->width-dx,0,
dx,image->height);
UCHAR
*source_ptr = image->buffer;
int
shift = (image->bpp>>3)*dx;
//适应8/16位
for
(
int
y=0;y<image->height;y++)
{
//从source_ptr地址向右移动(width-dx)个像素至source_ptr+shift地址处
memmove(source_ptr+shift,source_ptr,(image->width-dx)*(image->bpp>>3));
source_ptr+=((image->bpp>>3)*image->width);
}
//将临时位图图像的数据copy回源位图图像
Copy_Bitmap(image,0,0,&temp_image,0,0,dx,image->height);
}
else
{
// 向左卷动
dx = -dx;
Create_Bitmap(&temp_image, 0, 0, dx, image->height, image->bpp);
Copy_Bitmap(&temp_image,0,0,
image, 0,0,
dx, image->height);
UCHAR
*source_ptr = image->buffer;
int
shift = (image->bpp >> 3)*dx;
for
(
int
y=0; y < image->height; y++)
{
memmove(source_ptr, source_ptr+shift, (image->width-dx)*(image->bpp >> 3));
source_ptr+=((image->bpp >> 3)*image->width);
}
// end for
Copy_Bitmap(image, image->width-dx,0, &temp_image,0,0,
dx, image->height);
}
}
return
(1);
}
int
Copy_Bitmap(BITMAP_IMAGE_PTR dest_bitmap,
int
dest_x,
int
dest_y,
BITMAP_IMAGE_PTR source_bitmap,
int
source_x,
int
source_y,
int
width,
int
height)
{
//copy源位图指定坐标位置开始宽width高height到指定位图图像的指定位置
//同时满足8位和16位
if
(!dest_bitmap || !source_bitmap)
return
(0);
//每像素的字节数
int
bytes_per_pixel = (source_bitmap->bpp >> 3);
UCHAR
* source_ptr = source_bitmap->buffer + (source_x+source_y*source_bitmap->width)*bytes_per_pixel;
UCHAR
* dest_ptr = dest_bitmap->buffer + (dest_x + dest_y*dest_bitmap->width)*bytes_per_pixel;
for
(
int
y=0;y<height;y++)
{
memcpy(dest_ptr,source_ptr,bytes_per_pixel*width);
source_ptr += (source_bitmap->width*bytes_per_pixel);
dest_ptr += (dest_bitmap->width*bytes_per_pixel);
}
return
(1);
}
void
HLine16(
int
x1,
int
x2,
int
y,
int
color,
UCHAR
*vbuffer,
int
lpitch)
{
//画从(x1,y)至(x2,y)颜色为color的直线(16位)
int
temp;
USHORT
*vbuffer2 = (
USHORT
*)vbuffer;
lpitch = lpitch >> 1;
if
(y>max_clip_y || y<min_clip_y)
return
;
if
(x1>x2)
{
temp = x1;
x1 = x2;
x2 = temp;
}
if
(x1>max_clip_x || x2<min_clip_x)
return
;
x1 = ((x1<min_clip_x)?min_clip_x:x1);
x2 = ((x2>max_clip_x)?max_clip_x:x2);
Mem_Set_WORD((vbuffer2+(y*lpitch)+x1),color,x2-x1+1);
}
void
HLine(
int
x1,
int
x2,
int
y,
int
color,
UCHAR
*vbuffer,
int
lpitch)
{
//画从(x1,y)至(x2,y)颜色为color的直线(8位)
int
temp;
lpitch = lpitch >> 1;
if
(y>max_clip_y || y<min_clip_y)
return
;
if
(x1>x2)
{
temp = x1;
x1 = x2;
x2 = temp;
}
if
(x1>max_clip_x || x2<min_clip_x)
return
;
x1 = ((x1<min_clip_x)?min_clip_x:x1);
x2 = ((x2>max_clip_x)?max_clip_x:x2);
memset((
UCHAR
*)(vbuffer+(y*lpitch)+x1),(
UCHAR
)color,x2-x1+1);
}
void
VLine16(
int
y1,
int
y2,
int
x,
int
color,
UCHAR
*vbuffer,
int
lpitch)
{
//画从(x,y1)至(x,y2)的颜色为color的直线(16位)
USHORT
*start_offset;
int
index,
temp;
lpitch = lpitch >>1;
if
(x>max_clip_x || x<min_clip_x)
return
;
if
(y1>y2)
{
temp = y1;
y1 = y2;
y2 = temp;
}
if
(y1>max_clip_y || y2<min_clip_y)
return
;
y1 = ((y1<min_clip_y)?min_clip_y:y1);
y2 = ((y2>max_clip_y)?max_clip_y:y2);
start_offset = (
USHORT
*)vbuffer + (y1*lpitch) + x;
for
(index=0;index<=y2-y1;index++)
{
*start_offset = color;
start_offset += lpitch;
}
}
void
VLine(
int
y1,
int
y2,
int
x,
int
color,
UCHAR
*vbuffer,
int
lpitch)
{
//画从(x,y1)至(x,y2)的颜色为color的直线(8位)
UCHAR
*start_offset;
int
index,
temp;
if
(x>max_clip_x || x<min_clip_x)
return
;
if
(y1>y2)
{
temp = y1;
y1 = y2;
y2 = temp;
}
if
(y1>max_clip_y || y2<min_clip_y)
return
;
y1 = ((y1<min_clip_y)?min_clip_y:y1);
y2 = ((y2>max_clip_y)?max_clip_y:y2);
start_offset = vbuffer + (y1*lpitch) + x;
for
(index=0;index<=y2-y1;index++)
{
*start_offset = (
UCHAR
)color;
start_offset += lpitch;
}
}
void
Screen_Transitions(
int
effect,
UCHAR
*vbuffer,
int
lpitch)
{
int
pal_reg;
//循环变量
int
index;
//循环变量
int
red,green,blue;
PALETTEENTRY color;
PALETTEENTRY work_palette[MAX_COLORS_PALETTE];
//PALETTEENTRY work_color;
switch
(effect)
{
case
SCREEN_DARKNESS:
{
//逐渐变暗
for
(index=0;index<80;index++)
{
Save_Palette(work_palette);
for
(pal_reg=1;pal_reg<MAX_COLORS_PALETTE;pal_reg++)
{
color = work_palette[pal_reg];
if
(color.peRed>4) color.peRed-=3;
else
color.peRed = 0;
if
(color.peGreen>4) color.peGreen-=3;
else
color.peGreen = 0;
if
(color.peBlue>4) color.peBlue-=3;
else
color.peBlue =0;
work_palette[pal_reg] = color;
}
Set_Palette(work_palette);
//等一段时间(让变化看得见)
Start_Clock();
Wait_Clock(12);
}
}
break
;
case
SCREEN_WHITENESS:
{
//逐渐变亮
for
(index=0;index<64;index++)
{
Save_Palette(work_palette);
for
(pal_reg=0;pal_reg<MAX_COLORS_PALETTE;pal_reg++)
{
color = work_palette[pal_reg];
red = color.peRed;
green = color.peGreen;
blue =color.peBlue;
if
((red+=4)>=255)
red = 255;
if
((green+=4)>=255)
green = 255;
if
((blue+=4)>=255)
blue = 255;
color.peRed = red;
color.peGreen =green;
color.peBlue = blue;
work_palette[pal_reg] = color;
}
Set_Palette(work_palette);
Start_Clock();
Wait_Clock(12);
}
}
break
;
case
SCREEN_REDNESS:
{
//逐渐变红
for
(index=0;index<64;index++)
{
Save_Palette(work_palette);
for
(pal_reg=0;pal_reg<MAX_COLORS_PALETTE;pal_reg++)
{
color = work_palette[pal_reg];
red = color.peRed;
green = color.peGreen;
blue =color.peBlue;
if
((red+=6)>=255)
red = 255;
if
((green-=4)<0)
green = 0;
if
((blue-=4)<0)
blue = 0;
color.peRed = red;
color.peGreen =green;
color.peBlue = blue;
work_palette[pal_reg] = color;
}
Set_Palette(work_palette);
Start_Clock();
Wait_Clock(12);
}
}
break
;
case
SCREEN_BLUENESS:
{
//逐渐变蓝
for
(index=0;index<64;index++)
{
Save_Palette(work_palette);
for
(pal_reg=0;pal_reg<MAX_COLORS_PALETTE;pal_reg++)
{
color = work_palette[pal_reg];
red = color.peRed;
green = color.peGreen;
blue =color.peBlue;
if
((red-=4)<0)
red = 0;
if
((green-=4)<0)
green = 0;
if
((blue+=6)>=255)
blue = 255;
color.peRed = red;
color.peGreen =green;
color.peBlue = blue;
work_palette[pal_reg] = color;
}
Set_Palette(work_palette);
Start_Clock();
Wait_Clock(12);
}
}
break
;
case
SCREEN_GREENNESS:
{
//逐渐变绿
for
(index=0;index<64;index++)
{
Save_Palette(work_palette);
for
(pal_reg=0;pal_reg<MAX_COLORS_PALETTE;pal_reg++)
{
color = work_palette[pal_reg];
red = color.peRed;
green = color.peGreen;
blue =color.peBlue;
if
((red-=4)<0)
red = 0;
if
((green+=6)>=255)
green = 255;
if
((blue-=4)<0)
blue = 0;
color.peRed = red;
color.peGreen =green;
color.peBlue = blue;
work_palette[pal_reg] = color;
}
Set_Palette(work_palette);
Start_Clock();
Wait_Clock(12);
}
}
break
;
case
SCREEN_SWIPE_X:
{
//纵向画线(先右后左)
for
(index=0;index<(screen_width/2);index+=2)
{
Start_Clock();
Wait_Clock(12);
if
(screen_bpp==8)
{
//分别从右左两边画两条纵向直线
VLine(0,(screen_height-1),(screen_width-1)-index,0,vbuffer,lpitch);
VLine(0,(screen_height-1),index,0,vbuffer,lpitch);
VLine(0,(screen_height-1),(screen_width-1)-(index+1),0,vbuffer,lpitch);
VLine(0,(screen_height-1),index+1,0,vbuffer,lpitch);
}
else
if
(screen_bpp==16)
{
VLine16(0,(screen_height-1),(screen_width-1)-index,0,vbuffer,lpitch);
VLine16(0,(screen_height-1),index,0,vbuffer,lpitch);
VLine16(0,(screen_height-1),(screen_width-1)-(index+1),0,vbuffer,lpitch);
VLine16(0,(screen_height-1),index+1,0,vbuffer,lpitch);
}
}
// end for index
}
break
;
case
SCREEN_SWIPE_Y:
{
//横向画线(先下后上)
for
(index=0;index<(screen_height/2);index+=2)
{
Start_Clock();
Wait_Clock(12);
if
(screen_bpp==8)
{
HLine(0,(screen_width-1),(screen_height-1)-index,0,vbuffer,lpitch);
HLine(0,(screen_width-1),index,0,vbuffer,lpitch);
HLine(0,(screen_width-1),(screen_height-1)-(index+1),0,vbuffer,lpitch);
HLine(0,(screen_width-1),index+1,0,vbuffer,lpitch);
}
else
if
(screen_bpp==16)
{
HLine16(0,(screen_width-1),(screen_height-1)-index,0,vbuffer,lpitch);
HLine16(0,(screen_width-1),index,0,vbuffer,lpitch);
HLine16(0,(screen_width-1),(screen_height-1)-(index+1),0,vbuffer,lpitch);
HLine16(0,(screen_width-1),index+1,0,vbuffer,lpitch);
}
}
// end for index
}
break
;
case
SCREEN_SCRUNCH:
{
//横向/纵向都会画线
for
(index=0;index<(screen_width/2);index+=2)
{
Start_Clock();
Wait_Clock(12);
if
(screen_bpp==8)
{
//这里取模运算因为索引index可能大于(screen_height/2)
HLine(0,(screen_width-1),(screen_height-1)-index%(screen_height/2),0,vbuffer,lpitch);
HLine(0,(screen_width-1),index%(screen_height/2),0,vbuffer,lpitch);
HLine(0,(screen_width-1),(screen_height-1)-(index%(screen_height/2)+1),0,vbuffer,lpitch);
HLine(0,(screen_width-1),index%(screen_height/2)+1,0,vbuffer,lpitch);
VLine(0,(screen_height-1),(screen_width-1)-index,0,vbuffer,lpitch);
VLine(0,(screen_height-1),index,0,vbuffer,lpitch);
VLine(0,(screen_height-1),(screen_width-1)-(index+1),0,vbuffer,lpitch);
VLine(0,(screen_height-1),index+1,0,vbuffer,lpitch);
}
else
if
(screen_bpp==16)
{
HLine16(0,(screen_width-1),(screen_height-1)-index%(screen_height/2),0,vbuffer,lpitch);
HLine16(0,(screen_width-1),index%(screen_height/2),0,vbuffer,lpitch);
HLine16(0,(screen_width-1),(screen_height-1)-(index%(screen_height/2)+1),0,vbuffer,lpitch);
HLine16(0,(screen_width-1),index%(screen_height/2)+1,0,vbuffer,lpitch);
VLine16(0,(screen_height-1),(screen_width-1)-index,0,vbuffer,lpitch);
VLine16(0,(screen_height-1),index,0,vbuffer,lpitch);
VLine16(0,(screen_height-1),(screen_width-1)-(index+1),0,vbuffer,lpitch);
VLine16(0,(screen_height-1),index+1,0,vbuffer,lpitch);
}
}
// end for index
}
break
;
case
SCREEN_DISOLVE:
{
//一个无聊的效果(溶解)
if
(screen_bpp==8)
for
(index=0;index<=screen_width*screen_height*4;index++)
Draw_Pixel(rand()%screen_width,rand()%screen_height,0,vbuffer,lpitch);
else
if
(screen_bpp==16)
for
(index=0;index<=screen_width*screen_height*4;index++)
Draw_Pixel16(rand()%screen_width,rand()%screen_height,0,vbuffer,lpitch);
}
break
;
default
:
break
;
}
//end switch
}
int
Collision_Test(
int
x1,
int
y1,
int
w1,
int
h1,
int
x2,
int
y2,
int
w2,
int
h2)
{
//碰撞检测(仅适用于矩形)
//取得近似宽度/高度一半,为什么近似?嘿嘿 自己想去
int
width1 = (w1>>1) - (w1>>3);
int
height1 = (h1>>1) - (h1>>3);
int
width2 = (w2>>1) - (w2>>3);
int
height2 = (h2>>1) - (h2>>3);
//取得矩形中心坐标
int
cx1 = x1 + width1;
int
cy1 = y1 + height1;
int
cx2 = x2 + width2;
int
cy2 = y2 + height2;
int
dx = abs(cx2 - cx1);
int
dy = abs(cy2 - cy1);
//如果碰撞,返回值1
if
(dx<(width1+width2)&&dy<(height1+height2))
return
(1);
else
return
(0);
}
int
Color_Scan(
int
x1,
int
y1,
int
x2,
int
y2,
UCHAR
scan_start,
UCHAR
scan_end,
UCHAR
*scan_buffer,
int
scan_lpitch)
{
//这个函数实现了一个粗糙的碰撞技术基于扫描一个矩形内的像素颜色
//是否在一个指定的颜色范围内
//裁剪矩形使之合理
if
(x1>=screen_width)
x1 = screen_width-1;
else
if
(x1<0)
x1 = 0;
if
(x2>=screen_width)
x2 = screen_width-1;
else
if
(x2<0)
x2 = 0;
if
(y1>=screen_height)
y1 = screen_height-1;
else
if
(y1<0)
y1 = 0;
if
(y2>=screen_height)
y2 = screen_height-1;
else
if
(y2<0)
y2 = 0;
scan_buffer += y1*scan_lpitch;
for
(
int
scan_y=y1;scan_y<=y2;scan_y++)
{
//y1<y2,x1<x2? 函数外指定.
for
(
int
scan_x=x1;scan_x<=x2;scan_x++)
{
if
(scan_buffer[scan_x]>=scan_start && scan_buffer[scan_x]<=scan_end)
return
(1);
}
scan_buffer+=scan_lpitch;
}
// return failure
return
(0);
}
int
Color_Scan16(
int
x1,
int
y1,
int
x2,
int
y2,
USHORT
scan_start,
USHORT
scan_end,
UCHAR
*scan_buffer,
int
scan_lpitch)
{
USHORT
*scan_buffer2 = (
USHORT
*)scan_buffer;
scan_lpitch = (scan_lpitch>>1);
if
(x1>=screen_width)
x1 = screen_width-1;
else
if
(x1<0)
x1 = 0;
if
(x2>=screen_width)
x2 = screen_width-1;
else
if
(x2<0)
x2 = 0;
if
(y1>=screen_height)
y1 = screen_height-1;
else
if
(y1<0)
y1 = 0;
if
(y2>=screen_height)
y2 = screen_height-1;
else
if
(y2<0)
y2 = 0;
scan_buffer2 +=y1*scan_lpitch;
for
(
int
scan_y=y1;scan_y<=y2;scan_y++)
{
for
(
int
scan_x=x1;scan_x<=x2;scan_x++)
{
if
(scan_buffer2[scan_x] == scan_start || scan_buffer2[scan_x] == scan_end)
return
(1);
}
scan_buffer2+=scan_lpitch;
}
return
(0);
}
int
Scan_Image_Bitmap(BITMAP_FILE_PTR bitmap,
LPDIRECTDRAWSURFACE7 lpdds,
int
cx,
int
cy)
{
//此函数从位图文件中提取出指定位图数据至lpdds目标表面
//适用于8位?
UCHAR
*source_ptr,
*dest_ptr;
DDSURFACEDESC2 ddsd;
ddsd.dwSize =
sizeof
(ddsd);
lpdds->Lock(NULL,
&ddsd,
DDLOCK_WAIT | DDLOCK_SURFACEMEMORYPTR,
NULL);
cx = cx*(ddsd.dwWidth+1)+1;
cy = cy*(ddsd.dwHeight+1)+1;
source_ptr = bitmap->buffer + cy*bitmap->bitmapinfoheader.biWidth+cx;
dest_ptr = (
UCHAR
*)ddsd.lpSurface;
for
(
int
index_y=0;index_y<ddsd.dwHeight;index_y++)
{
memcpy(dest_ptr,source_ptr,ddsd.dwWidth);
dest_ptr += (ddsd.lPitch);
source_ptr += bitmap->bitmapinfoheader.biWidth;
}
lpdds->Unlock(NULL);
return
(1);
}
void
Draw_Top_Tri(
int
x1,
int
y1,
int
x2,
int
y2,
int
x3,
int
y3,
int
color,
UCHAR
*dest_buffer,
int
mempitch)
{
// 画平顶三角形(8位,精确模式)
float
dx_right,
dx_left,
xs,xe,
height;
int
temp_x,
temp_y,
right,
left;
UCHAR
*dest_addr = NULL;
if
(x2 < x1)
{
temp_x = x2;
x2 = x1;
x1 = temp_x;
}
height = y3-y1;
dx_left = (x3-x1)/height;
dx_right = (x3-x2)/height;
xs = (
float
)x1;
xe = (
float
)x2+(
float
)0.5;
if
(y1 < min_clip_y)
{
xs = xs+dx_left*(
float
)(-y1+min_clip_y);
xe = xe+dx_right*(
float
)(-y1+min_clip_y);
y1=min_clip_y;
}
if
(y3>max_clip_y)
y3=max_clip_y;
dest_addr = dest_buffer+y1*mempitch;
if
(x1>=min_clip_x && x1<=max_clip_x &
x2>=min_clip_x && x2<=max_clip_x &
x3>=min_clip_x && x3<=max_clip_x)
{
for
(temp_y=y1; temp_y<=y3; temp_y++,dest_addr+=mempitch)
{
memset((
UCHAR
*)dest_addr+(unsigned
int
)xs,
color,(unsigned
int
)(xe-xs+1));
xs+=dx_left;
xe+=dx_right;
}
}
else
{
for
(temp_y=y1; temp_y<=y3; temp_y++,dest_addr+=mempitch)
{
left = (
int
)xs;
right = (
int
)xe;
xs+=dx_left;
xe+=dx_right;
if
(left < min_clip_x)
{
left = min_clip_x;
if
(right < min_clip_x)
continue
;
}
if
(right > max_clip_x)
{
right = max_clip_x;
if
(left > max_clip_x)
continue
;
}
memset((
UCHAR
*)dest_addr+(unsigned
int
)left,
color,(unsigned
int
)(right-left+1));
}
// end for
}
}
/
void
Draw_Bottom_Tri(
int
x1,
int
y1,
int
x2,
int
y2,
int
x3,
int
y3,
int
color,
UCHAR
*dest_buffer,
int
mempitch)
{
// 画平底三角形(8位,精确模式)
float
dx_right,
dx_left,
xs,xe,
height;
int
temp_x,
temp_y,
right,
left;
UCHAR
*dest_addr;
if
(x3 < x2)
{
temp_x = x2;
x2 = x3;
x3 = temp_x;
}
height = y3-y1;
dx_left = (x2-x1)/height;
dx_right = (x3-x1)/height;
xs = (
float
)x1;
xe = (
float
)x1;
// +(float)0.5;
if
(y1<min_clip_y)
{
xs = xs+dx_left*(
float
)(-y1+min_clip_y);
xe = xe+dx_right*(
float
)(-y1+min_clip_y);
y1=min_clip_y;
}
if
(y3>max_clip_y)
y3=max_clip_y;
dest_addr = dest_buffer+y1*mempitch;
if
(x1>=min_clip_x && x1<=max_clip_x &
x2>=min_clip_x && x2<=max_clip_x &
x3>=min_clip_x && x3<=max_clip_x)
{
for
(temp_y=y1; temp_y<=y3; temp_y++,dest_addr+=mempitch)
{
memset((
UCHAR
*)dest_addr+(unsigned
int
)xs,
color,(unsigned
int
)(xe-xs+1));
xs+=dx_left;
xe+=dx_right;
}
// end for
}
else
{
for
(temp_y=y1; temp_y<=y3; temp_y++,dest_addr+=mempitch)
{
left = (
int
)xs;
right = (
int
)xe;
xs+=dx_left;
xe+=dx_right;
if
(left < min_clip_x)
{
left = min_clip_x;
if
(right < min_clip_x)
continue
;
}
if
(right > max_clip_x)
{
right = max_clip_x;
if
(left > max_clip_x)
continue
;
}
memset((
UCHAR
*)dest_addr+(unsigned
int
)left,
color,(unsigned
int
)(right-left+1));
}
// end for
}
}
///
void
Draw_Top_TriFP(
int
x1,
int
y1,
int
x2,
int
y2,
int
x3,
int
y3,
int
color,
UCHAR
*dest_buffer,
int
mempitch)
{
//绘制平顶三角形(效率模式)
int
dx_right,
dx_left,
xs,xe,
height;
int
temp_x,
temp_y,
right,
left;
UCHAR
*dest_addr;
if
(y1==y3 || y2==y3)
return
;
if
(x2 < x1)
{
temp_x = x2;
x2 = x1;
x1 = temp_x;
}
height = y3-y1;
dx_left = ((x3-x1)<<FIXP16_SHIFT)/height;
dx_right = ((x3-x2)<<FIXP16_SHIFT)/height;
xs = (x1<<FIXP16_SHIFT);
xe = (x2<<FIXP16_SHIFT);
if
(y1<min_clip_y)
{
xs = xs+dx_left*(-y1+min_clip_y);
xe = xe+dx_right*(-y1+min_clip_y);
y1=min_clip_y;
}
if
(y3>max_clip_y)
y3=max_clip_y;
dest_addr = dest_buffer+y1*mempitch;
if
(x1>=min_clip_x && x1<=max_clip_x &
x2>=min_clip_x && x2<=max_clip_x &
x3>=min_clip_x && x3<=max_clip_x)
{
// 绘制三角形
for
(temp_y=y1; temp_y<=y3; temp_y++,dest_addr+=mempitch)
{
memset((
UCHAR
*)dest_addr+((xs+FIXP16_ROUND_UP)>>FIXP16_SHIFT),
color, (((xe-xs+FIXP16_ROUND_UP)>>FIXP16_SHIFT)+1));
xs+=dx_left;
xe+=dx_right;
}
}
else
{
for
(temp_y=y1; temp_y<=y3; temp_y++,dest_addr+=mempitch)
{
left = ((xs+FIXP16_ROUND_UP)>>16);
right = ((xe+FIXP16_ROUND_UP)>>16);
xs+=dx_left;
xe+=dx_right;
if
(left < min_clip_x)
{
left = min_clip_x;
if
(right < min_clip_x)
continue
;
}
if
(right > max_clip_x)
{
right = max_clip_x;
if
(left > max_clip_x)
continue
;
}
memset((
UCHAR
*)dest_addr+(unsigned
int
)left,
color,(unsigned
int
)(right-left+1));
}
// end for
}
}
/
void
Draw_Bottom_TriFP(
int
x1,
int
y1,
int
x2,
int
y2,
int
x3,
int
y3,
int
color,
UCHAR
*dest_buffer,
int
mempitch)
{
//绘制平底三角形(效率模式)
int
dx_right,
dx_left,
xs,xe,
height;
int
temp_x,
temp_y,
right,
left;
UCHAR
*dest_addr;
if
(y1==y2 || y1==y3)
return
;
if
(x3 < x2)
{
temp_x = x2;
x2 = x3;
x3 = temp_x;
}
height = y3-y1;
dx_left = ((x2-x1)<<FIXP16_SHIFT)/height;
dx_right = ((x3-x1)<<FIXP16_SHIFT)/height;
xs = (x1<<FIXP16_SHIFT);
xe = (x1<<FIXP16_SHIFT);
if
(y1<min_clip_y)
{
xs = xs+dx_left*(-y1+min_clip_y);
xe = xe+dx_right*(-y1+min_clip_y);
y1=min_clip_y;
}
if
(y3>max_clip_y)
y3=max_clip_y;
dest_addr = dest_buffer+y1*mempitch;
if
(x1>=min_clip_x && x1<=max_clip_x &
x2>=min_clip_x && x2<=max_clip_x &
x3>=min_clip_x && x3<=max_clip_x)
{
for
(temp_y=y1; temp_y<=y3; temp_y++,dest_addr+=mempitch)
{
memset((
UCHAR
*)dest_addr+((xs+FIXP16_ROUND_UP)>>FIXP16_SHIFT),
color, (((xe-xs+FIXP16_ROUND_UP)>>FIXP16_SHIFT)+1));
xs+=dx_left;
xe+=dx_right;
}
}
else
{
for
(temp_y=y1; temp_y<=y3; temp_y++,dest_addr+=mempitch)
{
left = ((xs+FIXP16_ROUND_UP)>>FIXP16_SHIFT);
right = ((xe+FIXP16_ROUND_UP)>>FIXP16_SHIFT);
xs+=dx_left;
xe+=dx_right;
if
(left < min_clip_x)
{
left = min_clip_x;
if
(right < min_clip_x)
continue
;
}
if
(right > max_clip_x)
{
right = max_clip_x;
if
(left > max_clip_x)
continue
;
}
memset((
UCHAR
*)dest_addr+left,
color, (right-left+1));
}
// end for
}
}
void
Draw_Top_Tri16(
int
x1,
int
y1,
int
x2,
int
y2,
int
x3,
int
y3,
int
color,
UCHAR
*_dest_buffer,
int
mempitch)
{
// 画平顶三角形(16位,精确模式)
float
dx_right,
dx_left,
xs,xe,
height;
int
temp_x,
temp_y,
right,
left;
USHORT
*dest_buffer = (
USHORT
*)_dest_buffer;
mempitch = (mempitch >> 1);
USHORT
*dest_addr = NULL;
if
(x2 < x1)
{
temp_x = x2;
x2 = x1;
x1 = temp_x;
}
height = y3-y1;
dx_left = (x3-x1)/height;
dx_right = (x3-x2)/height;
xs = (
float
)x1;
xe = (
float
)x2+(
float
)0.5;
if
(y1 < min_clip_y)
{
xs = xs+dx_left*(
float
)(-y1+min_clip_y);
xe = xe+dx_right*(
float
)(-y1+min_clip_y);
y1=min_clip_y;
}
if
(y3>max_clip_y)
y3=max_clip_y;
dest_addr = dest_buffer+y1*mempitch;
if
(x1>=min_clip_x && x1<=max_clip_x &
x2>=min_clip_x && x2<=max_clip_x &
x3>=min_clip_x && x3<=max_clip_x)
{
for
(temp_y=y1; temp_y<=y3; temp_y++,dest_addr+=mempitch)
{
Mem_Set_WORD(dest_addr+(unsigned
int
)xs,color,(unsigned
int
)(xe-xs+1));
xs+=dx_left;
xe+=dx_right;
}
// end for
}
else
{
for
(temp_y=y1; temp_y<=y3; temp_y++,dest_addr+=mempitch)
{
left = (
int
)xs;
right = (
int
)xe;
xs+=dx_left;
xe+=dx_right;
if
(left < min_clip_x)
{
left = min_clip_x;
if
(right < min_clip_x)
continue
;
}
if
(right > max_clip_x)
{
right = max_clip_x;
if
(left > max_clip_x)
continue
;
}
Mem_Set_WORD(dest_addr+(unsigned
int
)left,color,(unsigned
int
)(right-left+1));
}
// end for
}
}
/
void
Draw_Bottom_Tri16(
int
x1,
int
y1,
int
x2,
int
y2,
int
x3,
int
y3,
int
color,
UCHAR
*_dest_buffer,
int
mempitch)
{
// 画平底三角形(16位,精确模式)
float
dx_right,
// 右边1/斜率(右)
dx_left,
// 左边1/斜率(左)
xs,xe,
// 左右两边起始坐标
height;
// 三角形高度
int
temp_x,
temp_y,
right,
left;
//16位模式转换
USHORT
*dest_buffer = (
USHORT
*)_dest_buffer;
mempitch = (mempitch >> 1);
USHORT
*dest_addr = NULL;
// 测试使得 x3>x2
if
(x3 < x2)
{
temp_x = x2;
x2 = x3;
x3 = temp_x;
}
height = y3-y1;
dx_left = (x2-x1)/height;
dx_right = (x3-x1)/height;
//开始坐标
xs = (
float
)x1;
xe = (
float
)x1;
// +(float)0.5;
//裁剪顶部
if
(y1<min_clip_y)
{
// 计算新的 xs 和 xe
xs = xs+dx_left*(
float
)(-y1+min_clip_y);
xe = xe+dx_right*(
float
)(-y1+min_clip_y);
// 重置y1
y1=min_clip_y;
}
if
(y3>max_clip_y)
y3=max_clip_y;
// 计算开始目标行地址
dest_addr = dest_buffer+y1*mempitch;
// 如果三角形三点都在裁剪区域内
if
(x1>=min_clip_x && x1<=max_clip_x &
x2>=min_clip_x && x2<=max_clip_x &
x3>=min_clip_x && x3<=max_clip_x)
{
// 绘制三角形
for
(temp_y=y1; temp_y<=y3; temp_y++,dest_addr+=mempitch)
{
// 画横线
Mem_Set_WORD(dest_addr+(unsigned
int
)xs,color,(unsigned
int
)(xe-xs+1));
// 加上单位高度变化的x坐标
xs+=dx_left;
xe+=dx_right;
}
}
else
{
//若三角形有部分在裁剪区域外
// 绘制三角形
for
(temp_y=y1; temp_y<=y3; temp_y++,dest_addr+=mempitch)
{
left = (
int
)xs;
right = (
int
)xe;
// 加上单位高度变化的x坐标
xs+=dx_left;
xe+=dx_right;
// 裁剪直线
if
(left < min_clip_x)
{
left = min_clip_x;
if
(right < min_clip_x)
continue
;
}
if
(right > max_clip_x)
{
right = max_clip_x;
if
(left > max_clip_x)
continue
;
}
//绘制直线
Mem_Set_WORD(dest_addr+(unsigned
int
)left,color,(unsigned
int
)(right-left+1));
}
}
}
///
void
Draw_TriangleFP_2D(
int
x1,
int
y1,
int
x2,
int
y2,
int
x3,
int
y3,
int
color,
UCHAR
*dest_buffer,
int
mempitch)
{
//绘制任意三角形(结合画平顶和画平底的方法,效率模式)
int
temp_x,
temp_y,
new_x;
if
((x1==x2 && x2==x3) || (y1==y2 && y2==y3))
return
;
if
(y2<y1)
{
temp_x = x2;
temp_y = y2;
x2 = x1;
y2 = y1;
x1 = temp_x;
y1 = temp_y;
}
if
(y3<y1)
{
temp_x = x3;
temp_y = y3;
x3 = x1;
y3 = y1;
x1 = temp_x;
y1 = temp_y;
}
if
(y3<y2)
{
temp_x = x3;
temp_y = y3;
x3 = x2;
y3 = y2;
x2 = temp_x;
y2 = temp_y;
}
if
( y3<min_clip_y || y1>max_clip_y ||
(x1<min_clip_x && x2<min_clip_x && x3<min_clip_x) ||
(x1>max_clip_x && x2>max_clip_x && x3>max_clip_x) )
return
;
if
(y1==y2)
{
Draw_Top_TriFP(x1,y1,x2,y2,x3,y3,color, dest_buffer, mempitch);
}
else
if
(y2==y3)
{
Draw_Bottom_TriFP(x1,y1,x2,y2,x3,y3,color, dest_buffer, mempitch);
}
else
{
new_x = x1 + (
int
)(0.5+(
float
)(y2-y1)*(
float
)(x3-x1)/(
float
)(y3-y1));
Draw_Bottom_TriFP(x1,y1,new_x,y2,x2,y2,color, dest_buffer, mempitch);
Draw_Top_TriFP(x2,y2,new_x,y2,x3,y3,color, dest_buffer, mempitch);
}
}
/
void
Draw_Triangle_2D(
int
x1,
int
y1,
int
x2,
int
y2,
int
x3,
int
y3,
int
color,
UCHAR
*dest_buffer,
int
mempitch)
{
//画任意三角形(结合画平顶和画平底的方法,8位,精确模式)
int
temp_x,
temp_y,
new_x;
// 检测三点是否在同一直线
if
((x1==x2 && x2==x3) || (y1==y2 && y2==y3))
return
;
// 使纵坐标方向y3>y2>y1
if
(y2<y1)
{
temp_x = x2;
temp_y = y2;
x2 = x1;
y2 = y1;
x1 = temp_x;
y1 = temp_y;
}
if
(y3<y1)
{
temp_x = x3;
temp_y = y3;
x3 = x1;
y3 = y1;
x1 = temp_x;
y1 = temp_y;
}
if
(y3<y2)
{
temp_x = x3;
temp_y = y3;
x3 = x2;
y3 = y2;
x2 = temp_x;
y2 = temp_y;
}
// 检测三角形是否在裁剪区域外
if
( y3<min_clip_y || y1>max_clip_y ||
(x1<min_clip_x && x2<min_clip_x && x3<min_clip_x) ||
(x1>max_clip_x && x2>max_clip_x && x3>max_clip_x) )
return
;
// 是否平顶
if
(y1==y2)
{
Draw_Top_Tri(x1,y1,x2,y2,x3,y3,color, dest_buffer, mempitch);
}
// 是否平底
else
if
(y2==y3)
{
Draw_Bottom_Tri(x1,y1,x2,y2,x3,y3,color, dest_buffer, mempitch);
}
//任意三角形
else
{
// 从最长边找到一点将三角形一分为二(平顶和平底)
new_x = x1 + (
int
)(0.5+(
float
)(y2-y1)*(
float
)(x3-x1)/(
float
)(y3-y1));
Draw_Bottom_Tri(x1,y1,new_x,y2,x2,y2,color, dest_buffer, mempitch);
Draw_Top_Tri(x2,y2,new_x,y2,x3,y3,color, dest_buffer, mempitch);
}
}
///
void
Draw_Triangle_2D16(
int
x1,
int
y1,
int
x2,
int
y2,
int
x3,
int
y3,
int
color,
UCHAR
*dest_buffer,
int
mempitch)
{
//画任意三角形(结合画平顶和画平底的方法,16位,精确模式)
int
temp_x,
temp_y,
new_x;
// 检测三点是否在同一直线
if
((x1==x2 && x2==x3) || (y1==y2 && y2==y3))
return
;
// 使纵坐标方向y3>y2>y1
if
(y2<y1)
{
temp_x = x2;
temp_y = y2;
x2 = x1;
y2 = y1;
x1 = temp_x;
y1 = temp_y;
}
// end if
if
(y3<y1)
{
temp_x = x3;
temp_y = y3;
x3 = x1;
y3 = y1;
x1 = temp_x;
y1 = temp_y;
}
// end if
if
(y3<y2)
{
temp_x = x3;
temp_y = y3;
x3 = x2;
y3 = y2;
x2 = temp_x;
y2 = temp_y;
}
// end if
// 检测三角形是否在裁剪区域外
if
( y3<min_clip_y || y1>max_clip_y ||
(x1<min_clip_x && x2<min_clip_x && x3<min_clip_x) ||
(x1>max_clip_x && x2>max_clip_x && x3>max_clip_x) )
return
;
// 是否平顶
if
(y1==y2)
{
Draw_Top_Tri16(x1,y1,x2,y2,x3,y3,color, dest_buffer, mempitch);
}
//是否平底
else
if
(y2==y3)
{
Draw_Bottom_Tri16(x1,y1,x2,y2,x3,y3,color, dest_buffer, mempitch);
}
//任意三角形
else
{
// 从最长边找到一点将三角形一分为二(平顶和平底)
new_x = x1 + (
int
)(0.5+(
float
)(y2-y1)*(
float
)(x3-x1)/(
float
)(y3-y1));
Draw_Bottom_Tri16(x1,y1,new_x,y2,x2,y2,color, dest_buffer, mempitch);
Draw_Top_Tri16(x2,y2,new_x,y2,x3,y3,color, dest_buffer, mempitch);
}
}
inline
void
Draw_QuadFP_2D(
int
x0,
int
y0,
int
x1,
int
y1,
int
x2,
int
y2,
int
x3,
int
y3,
int
color,
UCHAR
*dest_buffer,
int
mempitch)
{
//画2D四边形
//其实就是画2个三角形
Draw_TriangleFP_2D(x0,y0,x1,y1,x3,y3,color,dest_buffer,mempitch);
Draw_TriangleFP_2D(x1,y1,x2,y2,x3,y3,color,dest_buffer,mempitch);
}
int
Mat_Mul_3X3(MATRIX3X3_PTR ma, MATRIX3X3_PTR mb, MATRIX3X3_PTR mprod)
{
// 计算两个3X3矩阵相乘的矩阵
for
(
int
row=0;row<3;row++)
{
for
(
int
col=0;col<3;col++)
{
float
sum=0;
for
(
int
index=0;index<3;index++)
{
sum+=(ma->M[row][index]*mb->M[index][col]);
}
mprod->M[row][col] = sum;
}
}
return
(1);
}
int
Mat_Mul_1X3_3X3(MATRIX1X3_PTR ma, MATRIX3X3_PTR mb, MATRIX1X3_PTR mprod)
{
for
(
int
col=0;col<3;col++)
{
float
sum=0;
for
(
int
index=0;index<3;index)
{
sum+=(ma->M[index]*mb->M[index][col]);
}
mprod->M[col] =sum;
}
return
(1);
}
int
Mat_Mul_1X2_3X2(MATRIX1X2_PTR ma, MATRIX3X2_PTR mb, MATRIX1X2_PTR mprod)
{
for
(
int
col=0;col<2;col++)
{
float
sum = 0;
for
(
int
index=0;index<2;index++)
{
sum+=(ma->M[index]*mb->M[index][col]);
}
sum+=mb->M[index][col];
//这句很关键,相当于ma的第3个元素看作1
mprod->M[col] = sum;
}
return
(1);
}
inline
int
Mat_Init_3X2(MATRIX3X2_PTR ma,
float
m00,
float
m01,
float
m10,
float
m11,
float
m20,
float
m21)
{
//初始化3X2矩阵
ma->M[0][0] = m00; ma->M[0][1] = m01;
ma->M[1][0] = m10; ma->M[1][1] = m11;
ma->M[2][0] = m20; ma->M[2][1] = m21;
return
(1);
}
int
Fast_Distance_2D(
int
x,
int
y)
{
// 此函数计算2点间的距离(参数x,y为两点x/y轴方向的坐标差)
//到现在还没能够利用麦克劳林级数推出:(
x = abs(x);
y = abs(y);
int
mn = MIN(x,y);
// 返回距离(3.5%的误差)
return
(x+y-(mn>>1)-(mn>>2)+(mn>>4));
}
///
float
Fast_Distance_3D(
float
fx,
float
fy,
float
fz)
{
//计算3维中两点的距离
int
temp;
// 临时变量
int
x,y,z;
x = fabs(fx) * 1024;
y = fabs(fy) * 1024;
z = fabs(fz) * 1024;
if
(y < x) SWAP(x,y,temp);
if
(z < y) SWAP(y,z,temp);
if
(y < x) SWAP(x,y,temp);
// 若上一句执行,此时的y中的值为z,所以再进行比较一次
int
dist = (z + 11*(y >> 5) + (x >> 2) );
// 返回距离(8%的误差)
return
((
float
)(dist >> 10));
}
int
Find_Bounding_Box_Poly2D(POLYGON2D_PTR poly,
float
&min_x,
float
&max_x,
float
&min_y,
float
&max_y)
{
//找到多边形的边界边框矩形
if
(poly->num_verts==0)
return
(0);
max_x = max_y = min_x = min_y =0;
for
(
int
index=0;index<poly->num_verts;index++)
{
if
(poly->vlist[index].x > max_x)
max_x = poly->vlist[index].x;
if
(poly->vlist[index].x < min_x)
min_x = poly->vlist[index].x;
if
(poly->vlist[index].y > max_y)
max_y = poly->vlist[index].y;
if
(poly->vlist[index].y < min_y)
min_y =poly->vlist[index].y;
}
return
(1);
}
int
Draw_Filled_Polygon2D(POLYGON2D_PTR poly,
UCHAR
*vbuffer,
int
mempitch)
{
//绘制填充多边形(8位)
int
ydiff1,ydiff2,
xdiff1,xdiff2,
start,
length,
errorterm1,errorterm2,
offset1,offset2,
count1,count2,
xunit1,xunit2;
int
edgecount = poly->num_verts-1;
int
firstvert=0;
int
min_y=poly->vlist[0].y;
for
(
int
index=1;index<poly->num_verts;index++)
{
/*找到y轴坐标最小的顶点*/
if
((poly->vlist[index].y)<min_y)
{
firstvert=index;
min_y=poly->vlist[index].y;
}
}
int
startvert1=firstvert;
int
startvert2=firstvert;
int
xstart1=poly->vlist[startvert1].x+poly->x0;
//逆时针移动的初始位置
int
ystart1=poly->vlist[startvert1].y+poly->y0;
int
xstart2=poly->vlist[startvert2].x+poly->x0;
//顺时针移动的初始位置
int
ystart2=poly->vlist[startvert2].y+poly->y0;
/*取得逆时针移动遇到的第1个顶点坐标*/
int
endvert1=startvert1-1;
if
(endvert1<0)
endvert1=poly->num_verts-1;
int
xend1=poly->vlist[endvert1].x+poly->x0;
int
yend1=poly->vlist[endvert1].y+poly->y0;
/*取得顺时针移动遇到的第1个顶点坐标*/
int
endvert2=startvert2+1;
if
(endvert2==(poly->num_verts))
endvert2=0;
int
xend2=poly->vlist[endvert2].x+poly->x0;
int
yend2=poly->vlist[endvert2].y+poly->y0;
//绘制并填充多边形
while
(edgecount>0)
{
offset1=mempitch*ystart1+xstart1;
//左边缘偏移量
offset2=mempitch*ystart2+xstart2;
//右边缘偏移量
//初始化误差额
errorterm1=0;
errorterm2=0;
//初始化左边与右边x&y方向的偏移差
if
((ydiff1=yend1-ystart1)<0)
ydiff1=-ydiff1;
if
((ydiff2=yend2-ystart2)<0)
ydiff2=-ydiff2;
if
((xdiff1=xend1-xstart1)<0)
{
xunit1=-1;
xdiff1=-xdiff1;
}
else
{
xunit1=1;
}
if
((xdiff2=xend2-xstart2)<0)
{
xunit2=-1;
xdiff2=-xdiff2;
}
else
{
xunit2=1;
}
//选择使用哪种情况
if
(xdiff1>ydiff1)
{
/*|k1|<1*/
if
(xdiff2>ydiff2)
{
/*|k2|<1*/
count1=xdiff1;
//左边X的增量
count2=xdiff2;
//右边X的增量
while
(count1&&count2)
{
while
((errorterm1<xdiff1)&&(count1>0))
{
if
(count1--)
{
offset1+=xunit1;
xstart1+=xunit1;
}
errorterm1+=ydiff1;
if
(errorterm1<xdiff1)
{
vbuffer[offset1]=(
UCHAR
)poly->color;
}
}
errorterm1-=xdiff1;
while
((errorterm2<xdiff2)&&(count2>0))
{
if
(count2--)
{
offset2+=xunit2;
xstart2+=xunit2;
}
errorterm2+=ydiff2;
if
(errorterm2<xdiff2)
{
vbuffer[offset2]=(
UCHAR
)poly->color;
}
}
errorterm2-=xdiff2;
length=offset2-offset1;
if
(length<0)
{
length=-length;
start=offset2;
}
else
start=offset1;
for
(
int
index=start;index<start+length+1;index++)
{
vbuffer[index]=(
UCHAR
)poly->color;
}
offset1+=mempitch;
ystart1++;
offset2+=mempitch;
ystart2++;
}
}
else
{
/*|k2|>1*/
count1=xdiff1;
count2=ydiff2;
while
(count1&&count2)
{
while
((errorterm1<xdiff1)&&(count1>0))
{
if
(count1--)
{
offset1+=xunit1;
xstart1+=xunit1;
}
errorterm1+=ydiff1;
if
(errorterm1<xdiff1)
{
vbuffer[offset1]=(
UCHAR
)poly->color;
}
}
errorterm1-=xdiff1;
errorterm2+=xdiff2;
if
(errorterm2>=ydiff2)
{
errorterm2-=ydiff2;
offset2+=xunit2;
xstart2+=xunit2;
}
count2--;
length=offset2-offset1;
if
(length<0)
{
length=-length;
start=offset2;
}
else
start=offset1;
for
(
int
index=start;index<start+length+1;index++)
{
vbuffer[index]=(
UCHAR
)poly->color;
}
offset1+=mempitch;
ystart1++;
offset2+=mempitch;
ystart2++;
}
}
}
else
{
/*|k1|>1*/
if
(xdiff2>ydiff2)
{
/*|k2|<1*/
count1=ydiff1;
count2=xdiff2;
while
(count1&&count2)
{
errorterm1+=xdiff1;
if
(errorterm1>=ydiff1)
{
errorterm1-=ydiff1;
offset1+=xunit1;
xstart1+=xunit1;
}
count1--;
while
((errorterm2<xdiff2)&&(count2>0))
{
if
(count2--)
{
offset2+=xunit2;
xstart2+=xunit2;
}
errorterm2+=ydiff2;
if
(errorterm2<xdiff2)
{
vbuffer[offset2]=(
UCHAR
)poly->color;
}
}
errorterm2-=xdiff2;
length=offset2-offset1;
if
(length<0)
{
length=-length;
start=offset2;
}
else
start=offset1;
for
(
int
index=start;index<start+length+1;index++)
{
vbuffer[index]=(
UCHAR
)poly->color;
}
offset1+=mempitch;
ystart1++;
offset2+=mempitch;
ystart2++;
}
}
else
{
/*|k2|>1*/
count1=ydiff1;
count2=ydiff2;
while
(count1&&count2)
{
errorterm1+=xdiff1;
if
(errorterm1>=ydiff1)
{
errorterm1-=ydiff1;
offset1+=xunit1;
xstart1+=xunit1;
}
count1--;
errorterm2+=xdiff2;
if
(errorterm2>=ydiff2)
{
errorterm2-=ydiff2;
offset2+=xunit2;
xstart2+=xunit2;
}
count2--;
length=offset2-offset1;
if
(length<0)
{
length=-length;
start=offset2;
}
else
start=offset1;
for
(
int
index=start;index<start+length+1;index++)
{
vbuffer[index]=(
UCHAR
)poly->color;
}
offset1+=mempitch;
ystart1++;
offset2+=mempitch;
ystart2++;
}
}
}
if
(!count1)
{
/*首先到达逆时针顶点*/
--edgecount;
startvert1=endvert1;
--endvert1;
if
(endvert1<0)
endvert1=poly->num_verts-1;
xend1=poly->vlist[endvert1].x+poly->x0;
yend1=poly->vlist[endvert1].y+poly->y0;
}
if
(!count2)
{
/*首先到达顺时针顶点*/
--edgecount;
startvert2=endvert2;
++endvert2;
if
(endvert2==(poly->num_verts))
endvert2=0;
xend2=poly->vlist[endvert2].x+poly->x0;
yend2=poly->vlist[endvert2].y+poly->y0;
}
}
return
(1);
}
int
Draw_Filled_Polygon2D16(POLYGON2D_PTR poly,
UCHAR
*_vbuffer,
int
mempitch)
{
//绘制填充多边形(16位)
int
ydiff1,ydiff2,
xdiff1,xdiff2,
start,
length,
errorterm1,errorterm2,
offset1,offset2,
count1,count2,
xunit1,xunit2;
USHORT
*vbuffer = (
USHORT
*)_vbuffer;
mempitch = mempitch>>1;
int
edgecount = poly->num_verts-1;
int
firstvert=0;
int
min_y=poly->vlist[0].y;
for
(
int
index=1;index<poly->num_verts;index++)
{
/*找到y轴坐标最小的顶点*/
if
((poly->vlist[index].y)<min_y)
{
firstvert=index;
min_y=poly->vlist[index].y;
}
}
int
startvert1=firstvert;
int
startvert2=firstvert;
int
xstart1=poly->vlist[startvert1].x+poly->x0;
//逆时针移动的初始位置
int
ystart1=poly->vlist[startvert1].y+poly->y0;
int
xstart2=poly->vlist[startvert2].x+poly->x0;
//顺时针移动的初始位置
int
ystart2=poly->vlist[startvert2].y+poly->y0;
/*取得逆时针移动遇到的第1个顶点坐标*/
int
endvert1=startvert1-1;
if
(endvert1<0)
endvert1=poly->num_verts-1;
int
xend1=poly->vlist[endvert1].x+poly->x0;
int
yend1=poly->vlist[endvert1].y+poly->y0;
/*取得顺时针移动遇到的第1个顶点坐标*/
int
endvert2=startvert2+1;
if
(endvert2==(poly->num_verts))
endvert2=0;
int
xend2=poly->vlist[endvert2].x+poly->x0;
int
yend2=poly->vlist[endvert2].y+poly->y0;
//绘制并填充多边形
while
(edgecount>0)
{
offset1=mempitch*ystart1+xstart1;
//左边缘偏移量
offset2=mempitch*ystart2+xstart2;
//右边缘偏移量
//初始化误差额
errorterm1=0;
errorterm2=0;
//初始化左边与右边x&y方向的偏移差
if
((ydiff1=yend1-ystart1)<0)
ydiff1=-ydiff1;
if
((ydiff2=yend2-ystart2)<0)
ydiff2=-ydiff2;
if
((xdiff1=xend1-xstart1)<0)
{
xunit1=-1;
xdiff1=-xdiff1;
}
else
{
xunit1=1;
}
if
((xdiff2=xend2-xstart2)<0)
{
xunit2=-1;
xdiff2=-xdiff2;
}
else
{
xunit2=1;
}
//选择使用哪种情况
if
(xdiff1>ydiff1)
{
/*|k1|<1*/
if
(xdiff2>ydiff2)
{
/*|k2|<1*/
count1=xdiff1;
//左边X的增量
count2=xdiff2;
//右边X的增量
while
(count1&&count2)
{
while
((errorterm1<xdiff1)&&(count1>0))
{
if
(count1--)
{
offset1+=xunit1;
xstart1+=xunit1;
}
errorterm1+=ydiff1;
if
(errorterm1<xdiff1)
{
vbuffer[offset1]=(
USHORT
)poly->color;
}
}
errorterm1-=xdiff1;
while
((errorterm2<xdiff2)&&(count2>0))
{
if
(count2--)
{
offset2+=xunit2;
xstart2+=xunit2;
}
errorterm2+=ydiff2;
if
(errorterm2<xdiff2)
{
vbuffer[offset2]=(
USHORT
)poly->color;
}
}
errorterm2-=xdiff2;
length=offset2-offset1;
if
(length<0)
{
length=-length;
start=offset2;
}
else
start=offset1;
for
(
int
index=start;index<start+length+1;index++)
{
vbuffer[index]=(
USHORT
)poly->color;
}
offset1+=mempitch;
ystart1++;
offset2+=mempitch;
ystart2++;
}
}
else
{
/*|k2|>1*/
count1=xdiff1;
count2=ydiff2;
while
(count1&&count2)
{
while
((errorterm1<xdiff1)&&(count1>0))
{
if
(count1--)
{
offset1+=xunit1;
xstart1+=xunit1;
}
errorterm1+=ydiff1;
if
(errorterm1<xdiff1)
{
vbuffer[offset1]=(
USHORT
)poly->color;
}
}
errorterm1-=xdiff1;
errorterm2+=xdiff2;
if
(errorterm2>=ydiff2)
{
errorterm2-=ydiff2;
offset2+=xunit2;
xstart2+=xunit2;
}
count2--;
length=offset2-offset1;
if
(length<0)
{
length=-length;
start=offset2;
}
else
start=offset1;
for
(
int
index=start;index<start+length+1;index++)
{
vbuffer[index]=(
USHORT
)poly->color;
}
offset1+=mempitch;
ystart1++;
offset2+=mempitch;
ystart2++;
}
}
}
else
{
/*|k1|>1*/
if
(xdiff2>ydiff2)
{
/*|k2|<1*/
count1=ydiff1;
count2=xdiff2;
while
(count1&&count2)
{
errorterm1+=xdiff1;
if
(errorterm1>=ydiff1)
{
errorterm1-=ydiff1;
offset1+=xunit1;
xstart1+=xunit1;
}
count1--;
while
((errorterm2<xdiff2)&&(count2>0))
{
if
(count2--)
{
offset2+=xunit2;
xstart2+=xunit2;
}
errorterm2+=ydiff2;
if
(errorterm2<xdiff2)
{
vbuffer[offset2]=(
USHORT
)poly->color;
}
}
errorterm2-=xdiff2;
length=offset2-offset1;
if
(length<0)
{
length=-length;
start=offset2;
}
else
start=offset1;
for
(
int
index=start;index<start+length+1;index++)
{
vbuffer[index]=(
USHORT
)poly->color;
}
offset1+=mempitch;
ystart1++;
offset2+=mempitch;
ystart2++;
}
}
else
{
/*|k2|>1*/
count1=ydiff1;
count2=ydiff2;
while
(count1&&count2)
{
errorterm1+=xdiff1;
if
(errorterm1>=ydiff1)
{
errorterm1-=ydiff1;
offset1+=xunit1;
xstart1+=xunit1;
}
count1--;
errorterm2+=xdiff2;
if
(errorterm2>=ydiff2)
{
errorterm2-=ydiff2;
offset2+=xunit2;
xstart2+=xunit2;
}
count2--;
length=offset2-offset1;
if
(length<0)
{
length=-length;
start=offset2;
}
else
start=offset1;
for
(
int
index=start;index<start+length+1;index++)
{
vbuffer[index]=(
USHORT
)poly->color;
}
offset1+=mempitch;
ystart1++;
offset2+=mempitch;
ystart2++;
}
}
}
if
(!count1)
{
/*首先到达逆时针顶点*/
--edgecount;
startvert1=endvert1;
--endvert1;
if
(endvert1<0)
endvert1=poly->num_verts-1;
xend1=poly->vlist[endvert1].x+poly->x0;
yend1=poly->vlist[endvert1].y+poly->y0;
}
if
(!count2)
{
/*首先到达顺时针顶点*/
--edgecount;
startvert2=endvert2;
++endvert2;
if
(endvert2==(poly->num_verts))
endvert2=0;
xend2=poly->vlist[endvert2].x+poly->x0;
yend2=poly->vlist[endvert2].y+poly->y0;
}
}
return
(1);
}
void
Build_Sin_Cos_Tables(
void
)
{
//创建三角函数表
for
(
int
ang=0;ang<=360;ang++)
{
float
theta =
float
(ang)*PI/(
float
)180;
cos_look[ang] = cos(theta);
sin_look[ang] = sin(theta);
}
}
int
Translate_Polygon2D(POLYGON2D_PTR poly,
int
dx,
int
dy)
{
//移动多边形
if
(!poly)
return
(0);
poly->x0+=dx;
poly->y0+=dy;
return
(1);
}
int
Scale_Polygon2D(POLYGON2D_PTR poly,
float
sx,
float
sy)
{
//缩放多边形
if
(!poly)
return
(0);
for
(
int
cur_vest=0;cur_vest<poly->num_verts;cur_vest++)
{
poly->vlist[cur_vest].x*=sx;
poly->vlist[cur_vest].y*=sy;
}
return
(1);
}
int
Rotate_Polygon2D(POLYGON2D_PTR poly,
int
theta)
{
//旋转多边形
if
(!poly)
return
(0);
for
(
int
curr_vert=0;curr_vert<poly->num_verts;curr_vert++)
{
float
xr=poly->vlist[curr_vert].x*cos_look[theta]-
poly->vlist[curr_vert].y*sin_look[theta];
float
yr=poly->vlist[curr_vert].x*sin_look[theta]+
poly->vlist[curr_vert].y*cos_look[theta];
poly->vlist[curr_vert].x=xr;
poly->vlist[curr_vert].y=yr;
}
return
(1);
}
int
Draw_Polygon2D(POLYGON2D_PTR poly,
UCHAR
*vbuffer,
int
lpitch)
{
//绘制2D多边形(8位)
if
(poly->state)
{
for
(
int
index=0;index<poly->num_verts-1;index++)
{
/*依次连接1~n-1个顶点*/
Draw_Clip_Line(poly->vlist[index].x+poly->x0,
poly->vlist[index].y+poly->y0,
poly->vlist[index+1].x+poly->x0,
poly->vlist[index+1].y+poly->y0,
poly->color,
vbuffer,lpitch);
}
//连接顶点1和顶点n
Draw_Clip_Line(poly->vlist[0].x+poly->x0,
poly->vlist[0].y+poly->y0,
poly->vlist[index].x+poly->x0,
poly->vlist[index].y+poly->y0,
poly->color,
vbuffer,lpitch);
return
(1);
}
else
return
(0);
}
int
Draw_Polygon2D16(POLYGON2D_PTR poly,
UCHAR
*vbuffer,
int
lpitch)
{
//绘制2D多边形(16位)
if
(poly->state)
{
for
(
int
index=0;index<poly->num_verts-1;index++)
{
/*依次连接1~n-1个顶点*/
Draw_Clip_Line16(poly->vlist[index].x+poly->x0,
poly->vlist[index].y+poly->y0,
poly->vlist[index+1].x+poly->x0,
poly->vlist[index+1].y+poly->y0,
poly->color,
vbuffer,lpitch);
}
//连接顶点1和顶点n
Draw_Clip_Line16(poly->vlist[0].x+poly->x0,
poly->vlist[0].y+poly->y0,
poly->vlist[index].x+poly->x0,
poly->vlist[index].y+poly->y0,
poly->color,
vbuffer,lpitch);
return
(1);
}
else
return
(0);
}
/*以下三个函数以矩阵运算实现2D多边形的平移,缩放,旋转*/
int
Translate_Polygon2D_Mat(POLYGON2D_PTR poly,
int
dx,
int
dy)
{
if
(!poly)
return
(0);
MATRIX3X2 mt;
Mat_Init_3X2(&mt,1,0,0,1,dx,dy);
MATRIX1X2 p0={
float
(poly->x0),
float
(poly->y0)};
MATRIX1X2 p1={0,0};
Mat_Mul_1X2_3X2(&p0,&mt,&p1);
poly->x0=p1.M[0];
poly->y0=p1.M[1];
return
(1);
}
int
Scale_Polygon2D_Mat(POLYGON2D_PTR poly,
float
sx,
float
sy)
{
if
(!poly)
return
(0);
MATRIX3X2 ms;
Mat_Init_3X2(&ms,sx,0,0,sy,0,0);
for
(
int
cur_vest=0;cur_vest<poly->num_verts;cur_vest++)
{
MATRIX1X2 p0={poly->vlist[cur_vest].x,poly->vlist[cur_vest].y};
MATRIX1X2 p1={0,0};
Mat_Mul_1X2_3X2(&p0,&ms,&p1);
poly->vlist[cur_vest].x=p1.M[0];
poly->vlist[cur_vest].y=p1.M[1];
}
return
(1);
}
int
Rotate_Polygon2D_Mat(POLYGON2D_PTR poly,
int
theta)
{
if
(!poly)
return
(0);
if
(theta<0)
theta+=360;
MATRIX3X2 mr;
Mat_Init_3X2(&mr,cos_look[theta],sin_look[theta],-sin_look[theta],cos_look[theta],0,0);
for
(
int
cur_vest=0;cur_vest<poly->num_verts;cur_vest++)
{
MATRIX1X2 p0={poly->vlist[cur_vest].x,poly->vlist[cur_vest].y};
MATRIX1X2 p1={0,0};
Mat_Mul_1X2_3X2(&p0,&mr,&p1);
poly->vlist[cur_vest].x=p1.M[0];
poly->vlist[cur_vest].y=p1.M[1];
}
return
(1);
}
//
int
Create_BOB(BOB_PTR bob,
//须创建的BOB对象
int
x,
int
y,
//初始位置
int
width,
int
height,
//宽,高
int
num_frames,
//帧数
int
attr,
//属性
int
mem_flags
/* =0 */
,
//存储方式(默认在显存)
USHORT
color_key_value
/* =0 */
,
//默认色彩键为黑色
int
bpp
/* =8 */
)
//默认色深为8位
{
DDSURFACEDESC2 ddsd;
int
index;
//初始化BOB对象
bob->state = BOB_STATE_ALIVE;
bob->attr = attr;
bob->anim_state = 0;
bob->counter_1 = 0;
bob->counter_2 = 0;
bob->max_count_1= 0;
bob->max_count_2= 0;
bob->curr_frame = 0;
bob->num_frames = num_frames;
bob->bpp = bpp;
bob->curr_animation= 0;
bob->anim_counter = 0;
bob->anim_index = 0;
bob->anim_count_max= 0;
bob->x = x;
bob->y = y;
bob->xv = 0;
bob->yv = 0;
bob->width = width;
bob->height = height;
for
(index=0;index<MAX_BOB_FRAMES;index++)
bob->images[index] = NULL;
for
(index=0;index<MAX_BOB_ANIMATIONS;index++)
bob->animations[index] = NULL;
#if 0
// 须保证显示表面宽为8的倍数,一些旧版本的DD那样做,现在不需要
bob->width_fill = ((width%8!=0) ? (8-width%8) : 0);
Write_Error(
"/nCreate BOB: width_fill=%d"
,bob->width_fill);
#endif
//创建表面
for
(index=0;index<bob->num_frames;index++)
{
DDRAW_INIT_STRUCT(ddsd);
ddsd.dwFlags = DDSD_CAPS | DDSD_WIDTH | DDSD_HEIGHT;
ddsd.dwWidth = bob->width + bob->width_fill;
ddsd.dwHeight= bob->height;
ddsd.ddsCaps.dwCaps = DDSCAPS_OFFSCREENPLAIN | mem_flags;
if
(FAILED(lpdd->CreateSurface(&ddsd,&(bob->images[index]),NULL)))
return
(0);
DDCOLORKEY color_key;
color_key.dwColorSpaceLowValue = color_key_value;
color_key.dwColorSpaceHighValue = color_key_value;
(bob->images[index])->SetColorKey(DDCKEY_SRCBLT,&color_key);
}
// end for index
return
(1);
}
int
Clone_BOB(BOB_PTR source, BOB_PTR dest)
{
//克隆BOB对象,所克隆的对象和源对象数据一样,指针指向同一块内存区
//克隆的对象有一个BOB_ATTR_CLONE标记
if
((source && dest) && (source!=dest))
{
memcpy(dest,source,
sizeof
(BOB));
dest->attr |= BOB_ATTR_CLONE;
}
else
return
(0);
return
(1);
}
int
Destroy_BOB(BOB_PTR bob)
{
//销毁BOB对象,对克隆的对象,将指针赋NULL.对源对象,需释放内存.
int
index;
if
(!bob)
return
(0);
if
(bob->attr & BOB_ATTR_CLONE)
{
for
(index=0;index<MAX_BOB_FRAMES;index++)
if
(bob->images[index])
bob->images[index]=NULL;
for
(index=0;index<MAX_BOB_ANIMATIONS;index++)
if
(bob->animations[index])
bob->animations[index]=NULL;
}
else
{
for
(index=0;index<MAX_BOB_FRAMES;index++)
if
(bob->images[index])
(bob->images[index])->Release();
for
(index=0;index<MAX_BOB_ANIMATIONS;index++)
if
(bob->animations[index])
free(bob->animations[index]);
}
return
(1);
}
int
Draw_BOB(BOB_PTR bob, LPDIRECTDRAWSURFACE7 dest)
{
RECT dest_rect,
source_rect;
if
(!bob)
return
(0);
if
(!(bob->attr & BOB_ATTR_VISIBLE))
return
(1);
dest_rect.left = bob->x;
dest_rect.top = bob->y;
dest_rect.right = bob->x+bob->width;
dest_rect.bottom= bob->y+bob->height;
source_rect.left = 0;
source_rect.top = 0;
source_rect.right = bob->width;
source_rect.bottom = bob->height;
//绘制过程
if
(FAILED(dest->Blt(&dest_rect,bob->images[bob->curr_frame],
&source_rect,(DDBLT_WAIT | DDBLT_KEYSRC),
NULL)))
return
(0);
return
(1);
}
int
Draw_BOB16(BOB_PTR bob, LPDIRECTDRAWSURFACE7 dest)
{
RECT dest_rect,
source_rect;
if
(!bob)
return
(0);
if
(!(bob->attr & BOB_ATTR_VISIBLE))
return
(1);
dest_rect.left = bob->x;
dest_rect.top = bob->y;
dest_rect.right = bob->x+bob->width;
dest_rect.bottom= bob->y+bob->height;
source_rect.left = 0;
source_rect.top = 0;
source_rect.right = bob->width;
source_rect.bottom = bob->height;
//绘制过程
if
(FAILED(dest->Blt(&dest_rect,bob->images[bob->curr_frame],
&source_rect,(DDBLT_WAIT | DDBLT_KEYSRC),
NULL)))
return
(0);
return
(1);
}
int
Draw_Scaled_BOB(BOB_PTR bob,
int
swidth,
int
sheight,
LPDIRECTDRAWSURFACE7 dest)
{
//绘制经缩放的BOB对象
RECT dest_rect,
source_rect;
if
(!bob)
return
(0);
if
(!(bob->attr & BOB_ATTR_VISIBLE))
return
(1);
dest_rect.left = bob->x;
dest_rect.top = bob->y;
dest_rect.right = bob->x+swidth;
dest_rect.bottom= bob->y+sheight;
source_rect.left = 0;
source_rect.top = 0;
source_rect.right = bob->width;
source_rect.bottom = bob->height;
//绘制过程
if
(FAILED(dest->Blt(&dest_rect,bob->images[bob->curr_frame],
&source_rect,(DDBLT_WAIT | DDBLT_KEYSRC),
NULL)))
return
(0);
return
(1);
}
int
Draw_Scaled_BOB16(BOB_PTR bob,
int
swidth,
int
sheight,
LPDIRECTDRAWSURFACE7 dest)
{
//绘制经缩放的BOB对象
RECT dest_rect,
source_rect;
if
(!bob)
return
(0);
if
(!(bob->attr & BOB_ATTR_VISIBLE))
return
(1);
dest_rect.left = bob->x;
dest_rect.top = bob->y;
dest_rect.right = bob->x+swidth;
dest_rect.bottom= bob->y+sheight;
source_rect.left = 0;
source_rect.top = 0;
source_rect.right = bob->width;
source_rect.bottom = bob->height;
//绘制过程
if
(FAILED(dest->Blt(&dest_rect,bob->images[bob->curr_frame],
&source_rect,(DDBLT_WAIT | DDBLT_KEYSRC),
NULL)))
return
(0);
return
(1);
}
int
Load_Frame_BOB(BOB_PTR bob,
BITMAP_FILE_PTR bitmap,
int
frame,
int
cx,
int
cy,
int
mode)
{
//此函数将位图数据加载到BOB对象中的一帧(8位)
DDSURFACEDESC2 ddsd;
if
(!bob)
return
(0);
UCHAR
*source_ptr,
*dest_ptr;
//计算须加载位图的绝对坐标
if
(mode==BITMAP_EXTRACT_MODE_CELL)
{
cx = cx*(bob->width+1) + 1;
cy = cy*(bob->height+1) + 1;
}
//定位加载地址
source_ptr = bitmap->buffer + cy*bitmap->bitmapinfoheader.biWidth+cx;
ddsd.dwSize =
sizeof
(ddsd);
(bob->images[frame])->Lock(NULL,
&ddsd,
DDLOCK_WAIT | DDLOCK_SURFACEMEMORYPTR,
NULL);
dest_ptr = (
UCHAR
*)ddsd.lpSurface;
//完成位图copy
for
(
int
index_y=0;index_y<bob->height;index_y++)
{
memcpy(dest_ptr,source_ptr,bob->width);
dest_ptr += ddsd.lPitch;
// (bob->width+bob->width_fill);
source_ptr += bitmap->bitmapinfoheader.biWidth;
}
(bob->images[frame])->Unlock(NULL);
bob->attr |= BOB_ATTR_LOADED;
return
(1);
}
int
Load_Frame_BOB16(BOB_PTR bob,
BITMAP_FILE_PTR bitmap,
int
frame,
int
cx,
int
cy,
int
mode)
{
//此函数将位图数据加载到BOB对象中的一帧(16位)
DDSURFACEDESC2 ddsd;
if
(!bob)
return
(0);
USHORT
*source_ptr,
*dest_ptr;
//计算须加载位图的绝对坐标
if
(mode==BITMAP_EXTRACT_MODE_CELL)
{
cx = cx*(bob->width+1) + 1;
cy = cy*(bob->height+1) + 1;
}
//定位加载地址
source_ptr =(
USHORT
*)bitmap->buffer + cy*bitmap->bitmapinfoheader.biWidth+cx;
ddsd.dwSize =
sizeof
(ddsd);
(bob->images[frame])->Lock(NULL,
&ddsd,
DDLOCK_WAIT | DDLOCK_SURFACEMEMORYPTR,
NULL);
dest_ptr = (
USHORT
*)ddsd.lpSurface;
// 完成位图copy
for
(
int
index_y=0;index_y<bob->height;index_y++)
{
memcpy(dest_ptr,source_ptr,(bob->width*2));
dest_ptr += (ddsd.lPitch>>1);
// (bob->width+bob->width_fill);
source_ptr += bitmap->bitmapinfoheader.biWidth;
}
(bob->images[frame])->Unlock(NULL);
bob->attr |= BOB_ATTR_LOADED;
return
(1);
}
int
Animate_BOB(BOB_PTR bob)
{
if
(!bob)
return
(0);
//BOB对象只有一帧
if
(bob->attr & BOB_ATTR_SINGLE_FRAME)
{
bob->curr_frame = 0;
return
(1);
}
//使用多个帧创建BOB,但BOB以线性次序0..n执行动画
else
if
(bob->attr & BOB_ATTR_MULTI_FRAME)
{
if
(++bob->anim_counter>=bob->anim_count_max)
{
bob->anim_counter = 0;
if
(++bob->curr_frame>=bob->num_frames)
bob->curr_frame = 0;
}
}
//创建一个多帧的,支持动画序列的BOB
else
if
(bob->attr & BOB_ATTR_MULTI_ANIM)
{
if
(++bob->anim_counter>=bob->anim_count_max)
{
bob->anim_counter = 0;
bob->anim_index++;
//提取动画序列的下一帧
bob->curr_frame = bob->animations[bob->curr_animation][bob->anim_index];
//到了动画序列的末尾
if
(bob->curr_frame == -1)
{
//动画只播放一次
if
(bob->attr & BOB_ATTR_ANIM_ONE_SHOT)
{
bob->anim_state = BOB_STATE_ANIM_DONE;
//使动画停留在最后一帧
bob->anim_index--;
bob->curr_frame = bob->animations[bob->curr_animation][bob->anim_index];
}
//动画重复播放
else
{
//从第1帧重新开始
bob->anim_index = 0;
bob->curr_frame = bob->animations[bob->curr_animation][bob->anim_index];
}
}
}
}
return
(1);
}
int
Move_BOB(BOB_PTR bob)
{
//移动BOB(考虑到边界情况)
if
(!bob)
return
(0);
bob->x+=bob->xv;
bob->y+=bob->yv;
//BOB对象在移出屏幕时卷到屏幕的另一边
if
(bob->attr & BOB_ATTR_WRAPAROUND)
{
if
(bob->x>max_clip_x)
bob->x = min_clip_x - bob->width;
else
if
(bob->x < min_clip_x-bob->width)
bob->x = max_clip_x;
if
(bob->y > max_clip_y)
bob->y = min_clip_y - bob->height;
else
if
(bob->y < min_clip_y-bob->height)
bob->y = max_clip_y;
}
//BOB对象当碰到屏幕边界时像一个球一样反弹
else
if
(bob->attr & BOB_ATTR_BOUNCE)
{
//仅仅是改变速度
if
((bob->x > max_clip_x - bob->width) || (bob->x < min_clip_x) )
bob->xv = -bob->xv;
if
((bob->y > max_clip_y - bob->height) || (bob->y < min_clip_y) )
bob->yv = -bob->yv;
}
return
(1);
}
int
Load_Animation_BOB(BOB_PTR bob,
int
anim_index,
//动画序列号
int
num_frames,
//动画帧数
int
*sequence)
//被加载的序列数组
{
//此函数加载动画序列到BOB对象,加载的序列以-1结尾作为结束标记
if
(!bob)
return
(0);
if
(!(bob->animations[anim_index] = (
int
*)malloc((num_frames+1)*
sizeof
(
int
))))
return
(0);
for
(
int
index=0;index<num_frames;index++)
bob->animations[anim_index][index] = sequence[index];
bob->animations[anim_index][index] = -1;
return
(1);
}
int
Set_Pos_BOB(BOB_PTR bob,
int
x,
int
y)
{
//设置BOB对象的位置
if
(!bob)
return
(0);
bob->x = x;
bob->y = y;
return
(1);
}
int
Set_Anim_Speed_BOB(BOB_PTR bob,
int
speed)
{
//设置动画播放速度
if
(!bob)
return
(0);
bob->anim_count_max = speed;
return
(1);
}
int
Set_Animation_BOB(BOB_PTR bob,
int
anim_index)
{
//此函数设置须播放的动画类别
if
(!bob)
return
(0);
bob->curr_animation = anim_index;
bob->anim_index =0;
return
(1);
}
int
Set_Vel_BOB(BOB_PTR bob,
int
xv,
int
yv)
{
//设置BOB速度
if
(!bob)
return
(0);
bob->xv = xv;
bob->yv = yv;
return
(1);
}
int
Hide_BOB(BOB_PTR bob)
{
//设置BOB不可见
if
(!bob)
return
(0);
RESET_BIT(bob->attr,BOB_ATTR_VISIBLE);
return
(1);
}
int
Show_BOB(BOB_PTR bob)
{
//设置BOB可见
if
(!bob)
return
(0);
SET_BIT(bob->attr,BOB_ATTR_VISIBLE);
return
(1);
}
int
Collision_BOBS(BOB_PTR bob1, BOB_PTR bob2)
{
//BOB对象碰撞检测
if
(!bob1 || !bob2)
return
(0);
int
width1 = (bob1->width>>1) - (bob1->width>>3);
int
height1 = (bob1->height>>1) - (bob1->height>>3);
int
width2 = (bob2->width>>1) - (bob2->width>>3);
int
height2 = (bob2->height>>1) - (bob2->height>>3);
//计算BOB中心坐标
int
cx1 = bob1->x + width1;
int
cy1 = bob1->y + height1;
int
cx2 = bob2->x + width2;
int
cy2 = bob2->y + height2;
int
dx = abs(cx2 - cx1);
int
dy = abs(cy2 - cy1);
//碰撞则返回1
if
(dx < (width1+width2) && dy < (height1+height2))
return
(1);
else
return
(0);
}
声明:
本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:
https://www.wpsshop.cn/w/我家自动化/article/detail/103418
推荐阅读
article
Cen
to
s7
.x安装
netcat
以及
netcat
连接被拒绝(
Ncat
:
Connection
re...
通过上面的指令,可以看到nc链接的是/etc/alternatives/nmap,并不是
netcat
,所以遇到这种情况大...
赞
踩
article
ChatGPT
工作提效之在
程序开发
中的巧劲和指令(创建
MySQL
语句
、
PHP
语句
、Javascrip...
ChatGPT
是一个基于GPT模型训练的聊天机器人,它可以与用户进行自然语言交互。问题解答:
ChatGPT
可以作为一个虚...
赞
踩
article
Arrow
之 ORC
Read
_
c
:\
arrow
\
c
pp\sr
c
\
arrow
\filesystem...
Or
c
Stripe
Read
er
Arrow
/
c
pp/sr
c
/
arrow
/adapters/or
c
/adapter.
c
c
c
l...
赞
踩
article
opencv
实战——
机器
视觉
检测
和
计数
_
opencv
盘子
上
的
瓶子数量...
引言在
机器
视觉
中,有时需要对产品进行
检测
和
计数
。其难点无非是对于产品
的
图像分割。由于之前网购
的
维生素片,有时候忘了今天有...
赞
踩
article
OpenCV
项目实战机器视觉之
零件
缺陷
检测
(1)_
opencv
焊点
缺陷
...
用
OpenCV
在
零件
缺陷
检测
时,很多时候需要定位
零件
的位置,比如下图:
零件
是多孔的工业常见部件,上图是打光后二值化的图像...
赞
踩
article
Vue +
Element
UI前端
控制
table
分页
_
el
-
table
那个参数是
控制
分页
的...
【代码】Vue +
Element
UI前端
控制
table
分页
。_
el
-
table
那个参数是
控制
分页
的
el
-
table
...
赞
踩
article
Linux
Mint
虚拟机
安装
常用软件_
mint
安装
微信...
还是
安装
常用软件系列,
Linux
Mint
其实和Ubuntu差不多,但是设计的更加人性化,比如文件夹可以root打开等,...
赞
踩
article
keras
利用
vgg16
进行十
分类
模型
训练
_
10
分类
模型
训练
...
导入模块import osimport numpy as npimport tensorflow as tfimport...
赞
踩
article
Unity
从
网络
中获取
图片
加载
到
物体
上_
unity
加载
网络
图片
...
Unity
使用
Unity
WebRequest从
网络
中获取
图片
并
加载
在2D/3D
物体
上首先从
网络
中获取资源使用的是协程(从...
赞
踩
article
OpenAI
-
ChatGPT
最
新官方接口《
聊天
交互
多轮
对话
》全网
最
详细
中英文
实用
指南
和教程
,
助你零基...
使用
ChatGPT
,
我们可以将
聊天
交互
推向极致。它不但可以迅速定位问题并给出正确的答案
,
而且能够提供个性化的
聊天
服务来解...
赞
踩
article
Unity
加载
网页上的
图片
_
unity
加载
网络
图片
...
【代码】
Unity
加载
网页上的
图片
。_
unity
加载
网络
图片
unity
加载
网络
图片
...
赞
踩
article
好好学习
第四天:生成对抗网络(GAN)手写数字生成
_
g
_
loss
=
combined
.
train
_
...
GAN手写数字识别
_
g
_
loss
=
combined
.
train
_
on
_
batch
(
noise
,
true
)出错g
_
l...
赞
踩
article
【腾讯
云
TDSQL
-C
Serverless
产品体验】| 实战分享_腾讯
云
数据库
serverl...
读取多个本地的 excel 文件 ,并将读取的数据存储到
TDSQL
中从
TDSQL
读取存储的数据将读取的数据生成词
云
图...
赞
踩
article
2
-
2
SparkContext
的
submit
以及原理大致剖析
_
context
.
submit
...
1打包一个spark工程
2
在spark安装目录
的
bin下,有一个spark-
submit
脚本3exec “SPARKHO...
赞
踩
article
【Vue】如何修改
node
_
modules
下的
element
-ui
源码
_
vue
node
_modul...
前言
element
-ui中有一个上传组件el-upload,进度到100%,后台服务响应处理需要时间,所以不能显示进度条...
赞
踩
article
svc
/
rvc
模型
训练前的音频
数据处理
_
rvc
响度
因子...
uvr5安装与
模型
下载。
_
rvc
响度
因子
rvc
响度
因子 1.uvr5操作 uvr5安装与
模型
下载...
赞
踩
article
神经网络
视觉
AI
“后时代”
自
瞄
实现与对抗
_
ai
自
瞄
...
整套系统完全不在Windows上运行,也不需要截取游戏画面,也不需要读写游戏数据,甚至连一个多余的进程、文件都不需要;他...
赞
踩
article
改进
YOLOv7
系列:结合最新
即插即
用
的
动态
卷积
ODConv
,有效涨点_处理长尾分布
即插即
用
的
码怎么...
提出了全维
动态
卷积(
ODConv
),一种更通
用
但更优雅
的
动态
卷积设计,以推进这一研究方向_处理长尾分布
即插即
用
的
码怎么
用
...
赞
踩
article
【
uiautomation
】
微
信
群
发消息,
获取
群
通讯录
名单_
inspect
获取
微
信
群
...
借助
uiautomation
进行
微
信自动化发送消息,可以
群
发消息,
获取
全部好友,
获取
聊天窗口全部聊天记录,
获取
朋友圈等等...
赞
踩
article
基于
GAN
的
手写
数字
生成
实践_
gan
手写
数字
生成
实验...
之前就对
GAN
这项技术很感兴趣,可是后面一直没有找到时间研究一下,今天找来了一个很不错的例子学习实践了一下,简单来记录一...
赞
踩
相关标签
linux
运维
centos
chatgpt
mysql
php
batch
c++
开发语言
opencv
视觉检测
计算机视觉
人工智能
机器视觉
源代码
零件缺陷检测
vue.js
前端
javascript
unity
游戏引擎
自然语言处理
nlp
python