铁血丹心

 找回密码
 我要成为铁血侠客
搜索
查看: 1777|回复: 2

[通用] 经过大量修改的DrawRLE8Pic过程

[复制链接]
发表于 2012-12-23 19:49 | 显示全部楼层 |阅读模式

马上注册,结交更多侠友!

您需要 登录 才可以下载或查看,没有账号?我要成为铁血侠客

x
本帖最后由 weyl 于 2012-12-23 19:51 编辑

这次对遮挡的修改大量依赖这个子程.同时增加了混合颜色效果.
推荐使用, 建议其余子程对此封装.
  1. //这是改写的绘制RLE8图片程序, 增加了选调色板, 遮挡控制, 亮度, 半透明, 混合色等
  2. //colorPanel: Pchar; 调色板的指针. 某些情况下需要使用静态调色板, 避免静态图跟随水的效果
  3. //num, px, py: integer; 图片的编号和位置
  4. //Pidx: Pinteger; Ppic: PByte; 图片的索引和内容的资源所在地
  5. //RectArea: Pchar; 画图的范围, 所指向地址应为连续4个integer, 表示一个矩形, 仅图片的部分或全部会出现在这个矩形内才画
  6. //Image: PChar; widthI, heightI, sizeI: integer; 映像的位置, 尺寸, 每单位长度. 如果Img不为空, 则会将图画到这个镜像上, 否则画到屏幕
  7. //shadow, alpha: integer; 图片的暗度和透明度, 仅在画到屏幕上时有效
  8. //BlockImageW: PChar; 大小与场景和战场映像相同. 如果此地址不为空, 则会记录该像素的场景深度depth, 用于遮挡计算.
  9. //BlockScreenR: PChar; widthR, heightR, sizeR: integer; 该映像应该与屏幕像素数相同, 保存屏幕上每一点的深度值
  10. //depth: integer; 所画物件的深度, 即场景坐标 x + y, 深度高的物件会遮挡深度低的.
  11. //当BlockImageW不为空时, 将该值写入BlockImageW, 如果该值超出范围(0~128), 会根据图片的y坐标计算一个,
  12. //但是需注意计算值在场景内包含高度的情况下是不准确的.
  13. //当Image为空, 即画到屏幕上时, 同时BlockScreenR不为空, 如果所绘像素的已有深度大于该值, 则按照alpha绘制该像素
  14. //即该值起作用的机会有两种: Image不为空(到映像), 且BlockImageW不为空; 或者Image为空(到屏幕), 且BlockScreenR不为空.
  15. //如果在画到屏幕时避免该值起作用, 可以设为128, 这是深度理论上的最大值(实际达不到)
  16. //MixColor: Uint32; MixAlpha: integer 图片的混合颜色和混合度, 仅在画到屏幕上时有效

  17. procedure DrawRLE8Pic3(colorPanel: Pchar; num, px, py: integer; Pidx: Pinteger; Ppic: PByte; RectArea: Pchar; Image: PChar; widthI, heightI, sizeI: integer; shadow, alpha: integer;
  18.   BlockImageW: PChar; BlockScreenR: PChar; widthR, heightR, sizeR: integer; depth: integer; MixColor: Uint32; MixAlpha: integer);
  19. var
  20.   w, h, xs, ys: smallint;
  21.   offset, length, p, isAlpha, lenInt: integer;
  22.   l, l1, ix, iy, pixdepth: integer;
  23.   pix, pix1, pix2, pix3, pix4, colorin, color1, color2, color3, color4: Uint32;
  24. begin
  25.   if num = 0 then
  26.     offset := 0
  27.   else
  28.   begin
  29.     inc(Pidx, num - 1);
  30.     offset := Pidx^;
  31.   end;

  32.   Inc(Ppic, offset);
  33.   w := Psmallint((Ppic))^;
  34.   Inc(Ppic, 2);
  35.   h := Psmallint((Ppic))^;
  36.   Inc(Ppic, 2);
  37.   xs := Psmallint((Ppic))^;
  38.   Inc(Ppic, 2);
  39.   ys := Psmallint((Ppic))^;
  40.   Inc(Ppic, 2);
  41.   pixdepth := 0;

  42.   lenInt := sizeof(integer);

  43.   if (px - xs + w >= pint(RectArea)^) and (px - xs < pint(RectArea)^ + pint(RectArea + lenInt * 2)^)
  44.     and (py - ys + h >= pint(RectArea + lenInt)^) and (py - ys < pint(RectArea + lenInt)^ + pint(RectArea + lenInt * 3)^) then
  45.   begin
  46.     for iy := 1 to h do
  47.     begin
  48.       l := Ppic^;
  49.       inc(Ppic, 1);
  50.       w := 1;
  51.       p := 0;
  52.       for ix := 1 to l do
  53.       begin
  54.         l1 := Ppic^;
  55.         inc(Ppic);
  56.         if p = 0 then
  57.         begin
  58.           w := w + l1;
  59.           p := 1;
  60.         end
  61.         else if p = 1 then
  62.         begin
  63.           p := 2 + l1;
  64.         end
  65.         else if p > 2 then
  66.         begin
  67.           p := p - 1;
  68.           if (w - xs + px >= pint(RectArea)^) and (iy - ys + py >= pint(RectArea + lenInt)^)
  69.             and (w - xs + px < pint(RectArea)^ + pint(RectArea + lenInt * 2)^) and (iy - ys + py < pint(RectArea + lenInt)^ + pint(RectArea + lenInt * 3)^) then
  70.           begin
  71.             if image = nil then
  72.             begin
  73.               pix := sdl_maprgb(screen.format, puint8(colorPanel + l1 * 3)^ * (4 + shadow), puint8(colorPanel + l1 * 3 + 1)^ * (4 + shadow), puint8(colorPanel + l1 * 3 + 2)^ * (4 + shadow));
  74.               if (alpha <> 0) then
  75.               begin
  76.                 if (BlockScreenR = nil) then
  77.                 begin
  78.                   isAlpha := 1;
  79.                 end
  80.                 else
  81.                 begin
  82.                   if ((w - xs + px) < widthR) and ((iy - ys + py) < heightR) then
  83.                   begin
  84.                     pixdepth := pint(BlockScreenR + ((w - xs + px) * heightR + (iy - ys + py)) * sizeR)^;
  85.                     if pixdepth > depth then
  86.                     begin
  87.                       isAlpha := 1;
  88.                     end
  89.                     else
  90.                       isAlpha := 0;
  91.                   end;
  92.                 end;
  93.                 if (isAlpha = 1) and (Alpha < 100) then
  94.                 begin
  95.                   colorin := getpixel(screen, w - xs + px, iy - ys + py);
  96.                   pix1 := pix and $FF;
  97.                   color1 := colorin and $FF;
  98.                   pix2 := pix shr 8 and $FF;
  99.                   color2 := colorin shr 8 and $FF;
  100.                   pix3 := pix shr 16 and $FF;
  101.                   color3 := colorin shr 16 and $FF;
  102.                   pix4 := pix shr 24 and $FF;
  103.                   color4 := colorin shr 24 and $FF;
  104.                   pix1 := (alpha * color1 + (100 - alpha) * pix1) div 100;
  105.                   pix2 := (alpha * color2 + (100 - alpha) * pix2) div 100;
  106.                   pix3 := (alpha * color3 + (100 - alpha) * pix3) div 100;
  107.                   pix4 := (alpha * color4 + (100 - alpha) * pix4) div 100;
  108.                   pix := pix1 + pix2 shl 8 + pix3 shl 16 + pix4 shl 24;
  109.                 end;
  110.               end;
  111.               if mixAlpha <> 0 then
  112.               begin
  113.                 colorin := MixColor;
  114.                 pix1 := pix and $FF;
  115.                 color1 := colorin and $FF;
  116.                 pix2 := pix shr 8 and $FF;
  117.                 color2 := colorin shr 8 and $FF;
  118.                 pix3 := pix shr 16 and $FF;
  119.                 color3 := colorin shr 16 and $FF;
  120.                 pix4 := pix shr 24 and $FF;
  121.                 color4 := colorin shr 24 and $FF;
  122.                 pix1 := (mixAlpha * color1 + (100 - mixAlpha) * pix1) div 100;
  123.                 pix2 := (mixAlpha * color2 + (100 - mixAlpha) * pix2) div 100;
  124.                 pix3 := (mixAlpha * color3 + (100 - mixAlpha) * pix3) div 100;
  125.                 pix4 := (mixAlpha * color4 + (100 - mixAlpha) * pix4) div 100;
  126.                 pix := pix1 + pix2 shl 8 + pix3 shl 16 + pix4 shl 24;
  127.               end;
  128.               if (Alpha < 100) or (pixdepth <= depth) then
  129.                 putpixel(screen, w - xs + px, iy - ys + py, pix);
  130.             end
  131.             else
  132.             begin
  133.               if ((w - xs + px) < widthI) and ((iy - ys + py) < heightI) then
  134.               begin
  135.                 if (BlockImageW <> nil) then
  136.                 begin
  137.                   if (depth < 0) or (depth > 128) then
  138.                     depth := py div 9 - 1;
  139.                   Pint(BlockImageW + ((w - xs + px) * heightI + (iy - ys + py)) * sizeI)^ := depth;
  140.                 end;
  141.                 Pint(image + ((w - xs + px) * heightI + (iy - ys + py)) * sizeI)^ :=
  142.                   sdl_maprgb(screen.format, puint8(colorPanel + l1 * 3)^ * (4 + shadow), puint8(colorPanel + l1 * 3 + 1)^ * (4 + shadow), puint8(colorPanel + l1 * 3 + 2)^ * (4 + shadow));
  143.               end;
  144.             end;
  145.           end;
  146.           w := w + 1;
  147.           if p = 2 then
  148.           begin
  149.             p := 0;
  150.           end;
  151.         end;
  152.       end;
  153.     end;
  154.   end;

  155. end;           
复制代码

评分

参与人数 1声望 +15 收起 理由
winson7891 + 15 很好的改进,但其实应用范围不大

查看全部评分

【武侠.中国】铁血丹心论坛(大武侠):致力于推广和发展武侠文化,让我们一起努力,做全球最大的武侠社区。
可能是目前为止最好的金庸群侠传MOD游戏交流论坛,各种经典武侠游戏等你来玩,各种开源制作工具等你来实现你的游戏开发之梦。
发表于 2012-12-23 19:57 | 显示全部楼层
速度如何?

点评

解码的方法没改,应该不会有什么改进  发表于 2012-12-23 22:50
【武侠.中国】铁血丹心论坛(大武侠):致力于推广和发展武侠文化,让我们一起努力,做全球最大的武侠社区。
可能是目前为止最好的金庸群侠传MOD游戏交流论坛,各种经典武侠游戏等你来玩,各种开源制作工具等你来实现你的游戏开发之梦。
发表于 2012-12-23 23:30 | 显示全部楼层
哎今时今日的MOD其实很少用这个RLE8算法了老实说
【武侠.中国】铁血丹心论坛(大武侠):致力于推广和发展武侠文化,让我们一起努力,做全球最大的武侠社区。
可能是目前为止最好的金庸群侠传MOD游戏交流论坛,各种经典武侠游戏等你来玩,各种开源制作工具等你来实现你的游戏开发之梦。

本版积分规则

小黑屋|手机版|铁血丹心

GMT+8, 2024-5-3 17:32

Powered by Discuz! X3.4 Licensed

Copyright © 2001-2021, Tencent Cloud.

快速回复 返回顶部 返回列表