Files
player/Project/Src/MyWin/MyWinCore/mywin_pic.c
2025-07-06 18:46:13 +08:00

233 lines
6.1 KiB
C
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

#include "mywin_pic.h"
#include "string.h"
// 定义图片缓冲区名称最大大小
#define WIN_PICBUFF_NAME_MAXLEN 100
// 定义图片缓冲池的个数
#define PICBUFF_NUM 30
typedef struct {
WIN_PicStruct pic;
char name[WIN_PICBUFF_NAME_MAXLEN];
} _pic_data;
typedef struct {
u32 buff_size; // 总大小
u32 buff_used; // 使用了多少
// u32 buff_tail; //尾部
_pic_data *pic_data;
} WIN_PicBuffStruct;
static WIN_PicBuffStruct *g_pic_buff;
// 创建一个指定大小的字形缓冲区
WIN_PicBuffStruct *WIN_CreatPicBuff(u32 size) {
WIN_PicBuffStruct *ret = mycalloc(sizeof(WIN_PicBuffStruct));
if (ret == 0)
return ret;
ret->pic_data = mymalloc_exm(sizeof(_pic_data) * size);
if (ret->pic_data == 0) {
myfree(ret);
ret = 0;
return ret;
}
mymemset(ret->pic_data, 0, sizeof(_pic_data) * size);
ret->buff_size = size;
return ret;
}
// 删除一个图片缓冲区
void WIN_DeletePicBuff(WIN_PicBuffStruct *pb) {
if (pb) {
for (int i = 0; i < pb->buff_used; i++) {
_pic_data *pic_data = &pb->pic_data[i];
if (pic_data->pic.data)
myfree(pic_data->pic.data);
}
myfree(pb->pic_data);
myfree(pb);
}
}
_pic_data *WIN_PicUsed(WIN_PicBuffStruct *pb, int index) {
_pic_data *pic_data = 0;
pic_data = &pb->pic_data[index];
if (index != 0) {
_pic_data *pic_temp = mymalloc(sizeof(_pic_data));
_pic_data *pic_first = &pb->pic_data[index - 1];
mymemcpy(pic_temp, pic_data, sizeof(_pic_data));
mymemcpy(pic_data, pic_first, sizeof(_pic_data));
mymemcpy(pic_first, pic_temp, sizeof(_pic_data));
myfree(pic_temp);
pic_data = pic_first;
}
return pic_data;
}
// 搜索缓冲区中的图片数据
WIN_PicStruct *WIN_SearchPicData(WIN_PicBuffStruct *pb, const char *name) {
WIN_PicStruct *ret = 0;
if (pb) {
for (int i = 0; i < pb->buff_used; i++) {
int index = i;
_pic_data *pic_data = 0;
pic_data = &pb->pic_data[index];
if (strcmp(pic_data->name, name) == 0) {
// 使用了一次,排名向前
pic_data = WIN_PicUsed(pb, index);
ret = &pic_data->pic;
break;
}
}
}
return ret;
}
// 在index的位置留出插入新字符的空间
int WIN_InsertPic(WIN_PicBuffStruct *pb, _pic_data *data, int index) {
if (pb == 0)
return 0;
if (index > pb->buff_used)
return 0;
int num = pb->buff_used - index;
_pic_data *pic_data = &pb->pic_data[index];
// index之后的向后移
if (pb->buff_used >= pb->buff_size) {
// 缓冲池已满,删除最后一个
_pic_data *end = &pb->pic_data[pb->buff_used - 1];
myfree(end->pic.data);
printf("%s:del pic,%s\r\n", __func__, end->name);
mymemset(end->name, 0, WIN_PICBUFF_NAME_MAXLEN);
} else {
pb->buff_used++;
}
// 直接向后移
for (int i = num; i > 0; i--) {
_pic_data *end = &pic_data[i];
_pic_data *first = &pic_data[i - 1];
mymemcpy(end, first, sizeof(_pic_data));
}
// 插入新的字符
mymemcpy(pic_data, data, sizeof(_pic_data));
printf("%s:add pic,%s\r\n", __func__, pic_data->name);
return 1;
}
// 添加图片数据
int WIN_AddPicData(WIN_PicBuffStruct *pb, WIN_PicStruct *pic,
const char *name) {
if (pb) {
_pic_data *pic_data = mymalloc(sizeof(_pic_data));
int len = strlen(name);
if (len + 1 > WIN_PICBUFF_NAME_MAXLEN) {
printf("%s:err,pic name to long\r\n", __func__);
}
mymemcpy(pic_data->name, (void *)name, len + 1);
mymemcpy(&pic_data->pic, pic, sizeof(WIN_PicStruct));
if (WIN_InsertPic(pb, pic_data, pb->buff_used / 2) == 0)
printf("%s:insert pic err \r\n", __func__);
myfree(pic_data);
}
return 0;
}
// 根据名称获取图片
WIN_PicStruct *WIN_GetPic(const char *name) {
if (name == 0)
return 0;
WIN_PicStruct *ret = 0;
if (g_pic_buff == 0)
g_pic_buff = WIN_CreatPicBuff(PICBUFF_NUM);
ret = WIN_SearchPicData(g_pic_buff, name);
if (ret == 0) {
WIN_PicStruct pic = {0};
if (WIN_DecodeImg(&pic, name) == 0) {
WIN_AddPicData(g_pic_buff, &pic, name);
}
ret = WIN_SearchPicData(g_pic_buff, name);
}
return ret;
}
// 根据名称获取图片,去除图片的透明度信息
WIN_PicStruct *WIN_GetPicNoAlpha(const char *name) {
WIN_PicStruct *ret = 0;
if (g_pic_buff == 0)
g_pic_buff = WIN_CreatPicBuff(PICBUFF_NUM);
ret = WIN_SearchPicData(g_pic_buff, name);
if (ret == 0) {
WIN_PicStruct pic = {0};
if (WIN_DecodeImg(&pic, name) == 0) {
if (pic.format == PIC_FORMAT_ARGB8888) {
u32 *data = (u32 *)pic.data;
pic.data = mymalloc_exm(pic.xsize * pic.ysize * 2);
for (int i = 0; i < pic.xsize * pic.ysize; i++)
pic.data[i] = COLOR888TO565(data[i]);
pic.format = PIC_FORMAT_RGB565;
myfree(data);
}
WIN_AddPicData(g_pic_buff, &pic, name);
}
ret = WIN_SearchPicData(g_pic_buff, name);
}
return ret;
}
// 判断pic是否在另一个pic内
int WIN_PicInsidePic(WIN_PicStruct *base, WIN_PicStruct *child) {
int ret = 0;
if (base && child && base->data && child->data && base->xsize &&
base->ysize && child->xsize && child->ysize) {
if (base->format == child->format) {
int base_size = base->xsize * base->ysize;
int child_size = child->xsize * child->ysize;
if (base->format == PIC_FORMAT_ARGB8888) {
base_size *= 2;
child_size *= 2;
}
if ((child->data >= base->data) &&
(child->data + child_size <= base->data + base_size)) {
ret = 1;
}
}
}
return ret;
}
// 图像是否存在
int WIN_GetPicLive(WIN_PicStruct *pic) {
int ret = 0;
WIN_PicBuffStruct *pb = g_pic_buff;
if (pb && pic && pic->data) {
for (int i = 0; i < pb->buff_used; i++) {
int index = i;
_pic_data *pic_data = 0;
pic_data = &pb->pic_data[index];
if (WIN_PicInsidePic(&pic_data->pic, pic)) {
ret = 1;
break;
}
}
}
return ret;
}
// 安全地绘制pic,返回0没有pic图像
int WIN_DrawPic(WIN_PicStruct *pic, int x, int y, int xsize, int ysize) {
if (pic && WIN_GetPicLive(pic)) {
if (pic->format == PIC_FORMAT_ARGB8888) {
WIN_FillRectAlpha(x, y, xsize, ysize, pic->data, 0, 0, pic->xsize,
pic->ysize);
} else {
WIN_FillRect(x, y, xsize, ysize, pic->data, 0, 0, pic->xsize, pic->ysize);
}
return 1;
}
return 0;
}