/* --------------------------------------- 绘制图块 (支持对齐) --------------------------------------- */ static bool_t qst_crh_blit ( __CR_IN__ void_t* parm, __CR_IN__ uint_t argc, __CR_IN__ ansi_t** argv ) { sBLIT blit; sRECT rect; sRECT dest; sRECT wins; int32u idxs; sIMAGE* draw; sIMAGE* srce; uint_t ww,hh; uint_t align; /* 参数解析 <X> <Y> <SpriteName> [Index] [Width Height Align] */ if (argc < 4) return (FALSE); if (s_resx == NULL) return (FALSE); draw = ((sQstView2D*)parm)->paint; if (draw == NULL) return (FALSE); /* 查找目标图片对象 */ if (argc > 4) idxs = str2intxA(argv[4]); else idxs = 0; srce = egui_res_get_img(s_resx, argv[3], idxs, &rect); if (srce == NULL) return (FALSE); /* 计算对齐输出图块 */ dest.x1 = (sint_t)str2intxA(argv[1]); dest.y1 = (sint_t)str2intxA(argv[2]); rect_set_wh(&dest, dest.x1, dest.y1, rect.ww, rect.hh); if (argc > 7) { ww = str2intxA(argv[5]); hh = str2intxA(argv[6]); align = str2intxA(argv[7]); rect_set_wh(&wins, dest.x1, dest.y1, ww, hh); egui_rect_align(&dest, &wins, align); } blit.dx = dest.x1; blit.dy = dest.y1; blit.sx = rect.x1; blit.sy = rect.y1; blit.sw = dest.ww; blit.sh = dest.hh; qst_crh_blit_int(draw, srce, &blit); return (TRUE); }
/* --------------------------------------- 改变屏幕大小 --------------------------------------- */ static bool_t iGFX2_DX8M_reset ( __CR_IN__ iGFX2* that ) { RECT rect; iGFX2_DX8M* real; /* 重新获取窗口大小 */ real = (iGFX2_DX8M*)that; if (!GetClientRect(real->m_hdle.hwnd, &rect)) return (FALSE); /* 如果发生了改变则复位设备 */ if ((uint_t)rect.right != that->__back__.position.ww || (uint_t)rect.bottom != that->__back__.position.hh) { real->m_sprt->OnLostDevice(); if (!real->m_hdle.call->main_reset(real->m_main, FALSE, rect.right, rect.bottom, D3DFMT_UNKNOWN, D3DFMT_UNKNOWN, FALSE, D3DMULTISAMPLE_NONE)) return (FALSE); real->m_sprt->OnResetDevice(); rect_set_wh(&that->__back__.clip_win, 0, 0, rect.right, rect.bottom); struct_cpy(&that->__back__.position, &that->__back__.clip_win, sRECT); } return (TRUE); }
/* ======================================= 生成 DX8 图形离屏表面 ======================================= */ CR_API iGFX2_DX8S* create_dx8_bitmap ( __CR_IN__ iGFX2_DX8M* device, __CR_IN__ sD3D8_TEXR* texture, __CR_IN__ bool_t dynamic ) { iGFX2_DX8S* rett; /* 必须是 2D 贴图 */ if (texture->face != 1) return (NULL); /* 生成对象并设置图片参数 */ rett = struct_new(iGFX2_DX8S); if (rett == NULL) return (NULL); if (!image_set(&rett->__back__, NULL, (leng_t)(-1L), 0, 0, texture->info.Width, texture->info.Height, image_d3d_to_crh(texture->info.Format), FALSE, 8)) { rect_set_wh(&rett->__back__.clip_win, 0, 0, texture->info.Width, texture->info.Height); struct_cpy(&rett->__back__.position, &rett->__back__.clip_win, sRECT); } /* 返回生成的对象 */ rett->__vptr__ = &s_bitmap_vtbl; rett->m_flags = dynamic ? D3DLOCK_DISCARD : 0; rett->m_device = device; rett->m_texture = texture; return (rett); }
/* --------------------------------------- 绘制椭圆 (宽高) --------------------------------------- */ static bool_t qst_crh_ellps_wh ( __CR_IN__ void_t* parm, __CR_IN__ uint_t argc, __CR_IN__ ansi_t** argv ) { sRECT rect; sIMAGE* draw; sint_t sx, sy; uint_t ww, hh; /* 参数解析 <X> <Y> <Width> <Height> */ if (argc < 5) return (FALSE); draw = ((sQstView2D*)parm)->paint; if (draw == NULL) return (FALSE); sx = (sint_t)str2intxA(argv[1]); sy = (sint_t)str2intxA(argv[2]); ww = (uint_t)str2intxA(argv[3]); hh = (uint_t)str2intxA(argv[4]); rect_set_wh(&rect, sx, sy, ww, hh); draw_ellipse(draw, &rect, s_color, s_pixdraw); return (TRUE); }
/* --------------------------------------- 绘制文字 (实体/透明) --------------------------------------- */ static bool_t qst_crh_text ( __CR_IN__ void_t* parm, __CR_IN__ uint_t argc, __CR_IN__ ansi_t** argv ) { sRECT rect; bool_t rett; bool_t tran; ansi_t* temp; ansi_t* text; sIMAGE* draw; uint_t ww,hh; uint_t align; /* 参数解析 <X> <Y> <EscText> [Width Height Align] */ if (argc < 4) return (FALSE); if (s_font == NULL) return (FALSE); draw = ((sQstView2D*)parm)->paint; if (draw == NULL) return (FALSE); /* 必须使用转义字符串 */ temp = str_fmtA("\"%s\"", argv[3]); if (temp == NULL) return (FALSE); text = str_esc_dupU(temp); mem_free(temp); if (text == NULL) return (FALSE); /* 区分实体和透明, 两个命令合并起来了 */ if (str_cmpA(argv[0], "crh:texts") == 0) tran = FALSE; else tran = TRUE; rect.x1 = (sint_t)str2intxA(argv[1]); rect.y1 = (sint_t)str2intxA(argv[2]); if (argc > 6) { ww = str2intxA(argv[4]); hh = str2intxA(argv[5]); align = str2intxA(argv[6]); rect_set_wh(&rect, rect.x1, rect.y1, ww, hh); } else { align = 0; } rett = qst_crh_text_int(draw, tran, &rect, text, align); mem_free(text); return (rett); }
/* --------------------------------------- 绘制图块 (支持对齐) --------------------------------------- */ static bool_t qst_crh_blit2 ( __CR_IN__ void_t* parm, __CR_IN__ uint_t argc, __CR_IN__ ansi_t** argv ) { sBLIT blit; sRECT rect; sRECT dest; sRECT* wins; int32u idxs; uint_t algn; sIMAGE* draw; sIMAGE* srce; /* 参数解析 <SpriteName> <RectName> <Align> [Index] */ if (argc < 4) return (FALSE); if (s_resx == NULL) return (FALSE); draw = ((sQstView2D*)parm)->paint; if (draw == NULL) return (FALSE); /* 查找目标矩形对象 */ wins = egui_res_get_rct(s_resx, argv[2]); if (wins == NULL) return (FALSE); /* 查找目标图片对象 */ if (argc > 4) idxs = str2intxA(argv[4]); else idxs = 0; srce = egui_res_get_img(s_resx, argv[1], idxs, &rect); if (srce == NULL) return (FALSE); /* 计算对齐输出图块 */ algn = str2intxA(argv[3]); rect_set_wh(&dest, wins->x1, wins->y1, rect.ww, rect.hh); egui_rect_align(&dest, wins, algn); blit.dx = dest.x1; blit.dy = dest.y1; blit.sx = rect.x1; blit.sy = rect.y1; blit.sw = dest.ww; blit.sh = dest.hh; qst_crh_blit_int(draw, srce, &blit); return (TRUE); }
/* ======================================= 生成 FB 图形绘制接口 ======================================= */ CR_API iGFX2_FB* create_fb_canvas ( __CR_IN__ const ansi_t* fb ) { iGFX2_FB* rett; /* 创建对象 */ rett = struct_new(iGFX2_FB); if (rett == NULL) return (NULL); struct_zero(&rett->__back__, sIMAGE); /* 初始化 FB */ if (fb == NULL) fb = "/dev/fb0"; rett->m_file = open(fb, O_RDWR); if (rett->m_file < 0) return (NULL); if (ioctl(rett->m_file, FBIOGET_FSCREENINFO, &rett->m_finfo) < 0) goto _failure; if (ioctl(rett->m_file, FBIOGET_VSCREENINFO, &rett->m_vinfo) < 0) goto _failure; if (rett->m_vinfo.bits_per_pixel <= 8 || rett->m_vinfo.red.msb_right || rett->m_vinfo.green.msb_right || rett->m_vinfo.blue.msb_right) goto _failure; /* 填充参数结构 */ rett->__back__.bpl = rett->m_finfo.line_length; if (rett->__back__.bpl % 16 == 0) rett->__back__.align = 16; else if (rett->__back__.bpl % 8 == 0) rett->__back__.align = 8; else if (rett->__back__.bpl % 4 == 0) rett->__back__.align = 4; rect_set_wh(&rett->__back__.clip_win, 0, 0, rett->m_vinfo.xres, rett->m_vinfo.yres); struct_cpy(&rett->__back__.position, &rett->__back__.clip_win, sRECT); rett->__back__.size = rett->__back__.bpl; rett->__back__.size *= rett->m_vinfo.yres; /* 识别颜色格式 */ if (rett->m_vinfo.bits_per_pixel == 16) { if (rett->m_vinfo.red.length == 5 && rett->m_vinfo.green.length == 6 && rett->m_vinfo.blue.length == 5 && rett->m_vinfo.red.offset == 11 && rett->m_vinfo.green.offset == 5 && rett->m_vinfo.blue.offset == 0) { rett->__back__.fmt = CR_ARGB565; rett->__vptr__ = &s_img16_vtbl; } else if (rett->m_vinfo.red.length == 5 && rett->m_vinfo.green.length == 5 && rett->m_vinfo.blue.length == 5 && rett->m_vinfo.red.offset == 10 && rett->m_vinfo.green.offset == 5 && rett->m_vinfo.blue.offset == 0) { if (rett->m_vinfo.transp.length == 0) { rett->__back__.fmt = CR_ARGBX555; rett->__vptr__ = &s_img15_vtbl; } else { rett->__back__.fmt = CR_ARGB1555; rett->__vptr__ = &s_img17_vtbl; } } else if (rett->m_vinfo.red.length == 4 && rett->m_vinfo.green.length == 4 && rett->m_vinfo.blue.length == 4 && rett->m_vinfo.red.offset == 8 && rett->m_vinfo.green.offset == 4 && rett->m_vinfo.blue.offset == 0) { rett->__back__.fmt = CR_ARGB4444; rett->__vptr__ = &s_img12_vtbl; } else { goto _failure; } rett->__back__.bpc = 2; } else if (rett->m_vinfo.bits_per_pixel == 32) { rett->__back__.bpc = 4; rett->__back__.fmt = CR_ARGB8888; rett->__vptr__ = &s_img32_vtbl; } else if (rett->m_vinfo.bits_per_pixel == 24) { rett->__back__.bpc = 3; rett->__back__.fmt = CR_ARGB888; rett->__vptr__ = &s_img24_vtbl; } else { goto _failure; } rett->__back__.data = (byte_t*)mem_malloc(rett->__back__.size + 16); if (rett->__back__.data == NULL) goto _failure; mem_zero(rett->__back__.data, rett->__back__.size); /* 映射前台缓冲 */ rett->m_size = (uint_t)rett->__back__.size; rett->m_main = mmap(NULL, rett->m_size, PROT_READ | PROT_WRITE, MAP_SHARED, rett->m_file, 0); if (rett->m_main == MAP_FAILED) { mem_free(rett->__back__.data); goto _failure; } mem_zero(rett->m_main, rett->m_size); return (rett); _failure: close(rett->m_file); return (NULL); }
/* ======================================= 生成 DX8 图形绘制接口 ======================================= */ CR_API iGFX2_DX8M* create_dx8_canvas ( __CR_IN__ const sDX8_HDLE* hdle, __CR_IN__ uint_t scn_cw, __CR_IN__ uint_t scn_ch, __CR_IN__ bool_t full ) { RECT rect; HRESULT retc; sD3D8_TEXR* fill; iGFX2_DX8M* rett; /* 使用伪全屏 */ if (full) { scn_cw = GetSystemMetrics(SM_CXSCREEN); scn_ch = GetSystemMetrics(SM_CYSCREEN); if (!SetWindowPos(hdle->hwnd, HWND_TOP, 0, 0, scn_cw, scn_ch, SWP_SHOWWINDOW)) return (NULL); } else if (scn_cw == 0 || scn_ch == 0) { /* 非法宽高, 获取窗口大小 */ if (!GetClientRect(hdle->hwnd, &rect)) return (NULL); scn_cw = rect.right; scn_ch = rect.bottom; } /* 生成对象 */ rett = struct_new(iGFX2_DX8M); if (rett == NULL) return (NULL); struct_zero(&rett->__back__, sIMAGE); /* 创建 D3D8 设备 */ if (hdle->main == NULL) { rett->m_main = hdle->call->create_main(hdle->hwnd, FALSE, scn_cw, scn_ch, D3DFMT_UNKNOWN, D3DFMT_UNKNOWN, FALSE, D3DMULTISAMPLE_NONE); if (rett->m_main == NULL) goto _failure1; } else { rett->m_main = hdle->main; } /* 创建填充用的纹理 */ fill = hdle->call->create_tex2(rett->m_main, 1, 1, D3DFMT_A8R8G8B8, D3DPOOL_MANAGED, 0, 1); if (fill == NULL) goto _failure2; rett->m_fill = (iGFX2*)create_dx8_bitmap(rett, fill, FALSE); if (rett->m_fill == NULL) { hdle->call->release_texr(fill); goto _failure2; } if (!CR_VCALL(rett->m_fill)->clear(rett->m_fill, 0xFFFFFFFFUL, 0)) goto _failure3; /* 生成精灵绘制对象 */ retc = D3DXCreateSprite(rett->m_main->dev, &rett->m_sprt); if (FAILED(retc)) goto _failure3; /* 返回生成的对象 */ rett->__vptr__ = &s_canvas_vtbl; struct_cpy(&rett->m_hdle, hdle, sDX8_HDLE); rect_set_wh(&rett->__back__.clip_win, 0, 0, scn_cw, scn_ch); struct_cpy(&rett->__back__.position, &rett->__back__.clip_win, sRECT); return (rett); _failure3: CR_VCALL(rett->m_fill)->release(rett->m_fill); _failure2: if (hdle->main == NULL) hdle->call->release_main(rett->m_main); _failure1: mem_free(rett); return (NULL); }