原始翎風CLIENT8位 (8) CLUNIT的學習

D7mir發表於2024-05-07

這個裡面是繪圖,
有彙編,

那個繪畫效果的彙編看明白了,
實際是先建立了一個顏色的轉換索引表,顏色對應下標,資料是轉換後的顏色
在繪畫效果中
用函式功能找到混合表面的的指標,鎖定它
用匯編語言,將混合表面的每一個畫素查詢轉換索引表,轉換過去。
因為用了MM0暫存器,這是個MMX的指令裡面的,它是64位的,
所以有個8次小迴圈。

這個可以用指標來實現,也很簡單。

涉及到知識難點還是DX
sddsd: TDDSurfaceDesc
這個代表什麼?
它是透過
sddsd.dwSize := SizeOf(sddsd);
ssuf.Lock(TRect(nil^), sddsd);
返回了sddsd它的值,

sptr := PBYTE(integer(sddsd.lpSurface) + (y + i) * sddsd.lPitch + x );
//地址計算,一行的 首址 + 開始行,本行的位元組數 + 列的開始位元組數
sddsd.lPitch應該是一行的位元組數

由於還是256色,和32位色的原因

這個出現亂色斑。


DrawBlend
實際呼叫的DrawBlendEx
DrawBlendEx(dsuf, x, y, ssuf, 0, 0, ssuf.Width, ssuf.Height, blendmode);
這個混合Blend,不是廣義上的繪畫上的混合
是自己本身定義上的混合blendmode: integer

case blendmode of
0: pmix := @Color256Mix[0, 0]; //混合模式和動畫混合模式?
else
pmix := @Color256Anti[0, 0];
end;

實際是呼叫2個顏色表,
都是混合,混合的計算方法不一樣。
混合模式,底色 前色各一半相加?
//動畫模式,底色加底色比例的前色

因為它也是對8位色的處理,所以會出現亂色斑

它在多處被呼叫

在PLAY中
按行1貼圖前景, 2本行事件 地面物品 人物帶魔法效果的 飛的魔法效果

地圖前景資訊裡會要求是否混合
會進行呼叫,用的動畫混合模式
DrawBlend(m_ObjSurface, n + ax - 2, mmm, DSurface, 1);


在PLAY中
//地面物品閃亮,顯示物品名稱
也進行了呼叫,用的動畫混合模式
DrawBlend(m_ObjSurface, ix + ax, iy + ay, DSurface, 1);

在魔法效果中
這些效果的繪畫
大多也是用的DrawBlend(surface,
FlyX + px - UNITX div 2,
FlyY + py - UNITY div 2,
d, 1);


在角色中
繪圖
if m_nState and $00800000 <> 0 then //這個是什麼狀態?強制混合模式
begin
blend := TRUE; //混合模式
end;

應該是有遮擋狀態之類的,用的混合模式。
DrawBlend(dsurface, ddx, ddy, source, 0)

在開始畫面中,也有
// DrawBlend(MSurface, ex, ey, e, 1);
MSurface.DrawAdd(Rect(ex, ey, ex + e.Width, ey + e.Height),
e.ClientRect, e, False, 255); //24.1 改成DXD7的方法

我給改成DX的方法了。

事件的單元中有,
DrawBlend(backsurface, ax + m_nPx, ay + m_nPy, m_Dsurface, 1)


對於
DrawBlendEx,是起始的座標不是0,0了
於是
在PLAY單元中。
繪畫小地圖
DrawBlendEx(surface, (SCREENWIDTH - 120), 0, d, rc.Left, rc.Top, 120, 120, 0)

在繪畫場景中
有個繪畫提示的,實際是可以直接呼叫的
DrawBlendEx(dsuf, x, y, ssuf, 0, 0, ssuf.Width, ssuf.Height, blendmode);
DrawBlendEx(MSurface, hx, hy, d, 0, 0, HintWidth, HintHeight, 0);

對於桌面是32位色,這些8位的直寫記憶體用不了,
但是對於32位色,那些顏色處理後就不是古老版的256的傳奇調色盤顏色了
我想
能不能在內部有個 表面
專門來處理這種8位色,
全部處理好後,再貼到桌面的視窗上去?

再是關於還有關於霧,也還沒有看明白。

看了一點,
它用的資料有
1: pColorLevel := @HeavyDarkColorLevel;
2: pColorLevel := @LightDarkColorLevel;
3: pColorLevel := @DengunColorLevel;

這是3個256*256 的顏色表
但區分到了0-30,31-255
顏色分到原來的0到30變化

計算方法不一樣,是有30的等級的變化?但實際還是隻有256種顏色?

還有一個
TLightEffect = record //光效果?
Width: integer;
Height: integer;
PFog: Pbyte;

裡面的PFog: Pbyte;
是讀取的 這幾個檔案。
LightFiles: array[0..MAXLIGHT] of string = (
'Data\lig0a.dat', //確實有這幾個檔案
'Data\lig0b.dat',
'Data\lig0c.dat',
'Data\lig0d.dat',
'Data\lig0e.dat',
'Data\lig0f.dat'
);

應該是對應的畫素光斑,

而LightMask0-5
是對應的地圖座標亮度計算?


m_LightMap是地圖座標點的亮度
m_PFogScreen是霧的蒙板,這2者是對應的。

順序下來就是
地圖會新增某座標點的亮度
效果會新增某座標點亮度
演員會新增某座標點的亮度

各種新增的亮度會疊加,透過LightMask0-5計算

做好m_LightMap地圖座標點的亮度後

轉換成顯示畫素級的m_PFogScreen是霧的蒙板
6個等級的光斑應該是畫素級的,看上去就是一個比一個大的圓光斑,


在PLAY繪圖的最後
將顯示錶面和霧的蒙板混合,透過顏色表索引
1: pColorLevel := @HeavyDarkColorLevel;
2: pColorLevel := @LightDarkColorLevel;
3: pColorLevel := @DengunColorLevel;
來繪圖。

相關文章