void MRbSinCore::Freeze()
{
if (pHGE->freezeTex) pHGE->Texture_Free(pHGE->freezeTex);
pHGE->freezeTex = 0;
pHGE->freezeTex = pHGE->Texture_CreateFromScreen();
pHGE->bFreeze = true;
}
void MRbSinCore::Transition(int duration, const wchar_t * filename, float vague)
{
if (!pHGE->freezeTex || !pHGE->bFreeze) return;
if (duration <= 0)
{
pHGE->bFreeze = false;
GetAppPtr()->GraphicsUpdate();
return;
}
HTEXTURE newTex = pHGE->Texture_CreateFromScreen();
if (!newTex) return;
float tempx1, tempy1, tempx2, tempy2;
tempx1 = 0;
tempy1 = 0;
tempx2 = pHGE->nScreenWidth;
tempy2 = pHGE->nScreenHeight;
hgeQuad frzQuad, newQuad;
frzQuad.tex = pHGE->freezeTex;
QUAD_INIT(frzQuad);
QUAD_SET_VRECT(frzQuad, tempx1, tempy1, tempx2, tempy2);
newQuad.tex = newTex;
QUAD_INIT(newQuad);
QUAD_SET_VRECT(newQuad, tempx1, tempy1, tempx2, tempy2);
if (filename[0])
{
int suffix_idx;
HTEXTURE midTex = CRbBitmap::LoadTexture(filename, 0, suffix_idx);
int mw = pHGE->Texture_GetWidth(midTex);
int mh = pHGE->Texture_GetHeight(midTex);
float a2, gray = 0, rate = (float)(255.0 / duration);
int dw = pHGE->nScreenWidth < mw ? pHGE->nScreenWidth : mw;
int dh = pHGE->nScreenHeight < mh ? pHGE->nScreenHeight : mh;
int wrate = pHGE->nScreenWidth / mw;
int hrate = pHGE->nScreenHeight / mh;
BYTE a1, r1, g1, b1, r2;
DWORD * pMidTexData = pHGE->Texture_Lock(midTex, true);
pHGE->bFreeze = false;
if (vague > 1)
{
do
{
DWORD* pNewTexData = pHGE->Texture_Lock(newTex, false);
for (int ly = 0; ly < dh; ++ly)
{
int tempW1 = ly * mw;
for (int lx = 0; lx < dw; ++lx)
{
r2 = GET_ARGB_R(pMidTexData[tempW1 + lx]);
if ((BYTE)gray < r2)
{
// 计算透明度,这算法我自己都不知道如何吐槽了 = =b
a2 = 255.0 - 255.0 / vague * (r2 - gray);
if (vague < 24) a2 += (12 + rate * rate) * (16 - vague);
else a2 += 12 + rate * rate;
a2 = SinBound(a2, 0, 255);
if (wrate && hrate)
{
for (int j = 0; j < hrate + 1; ++j)
{
if ((pHGE->nScreenHeight - mh * j) > ly)
{
int tempH2 = (ly + mh * j) * pHGE->nScreenWidth;
GET_ARGB_8888(pNewTexData[tempH2 + lx], a1, r1, g1, b1);
pNewTexData[tempH2 + lx] = MAKE_ARGB_8888((BYTE)a2, r1, g1, b1);
for (int i = 1; i < wrate + 1; ++i)
{
int tempW3 = mw * i;
if ((pHGE->nScreenWidth - tempW3) > lx)
{
GET_ARGB_8888(pNewTexData[tempH2 + lx + tempW3], a1, r1, g1, b1);
pNewTexData[tempH2 + lx + tempW3] = MAKE_ARGB_8888((BYTE)a2, r1, g1, b1);
}
}
}
}
}
else if (wrate)
{
int tempH2 = ly * pHGE->nScreenWidth;
GET_ARGB_8888(pNewTexData[tempH2 + lx], a1, r1, g1, b1);
pNewTexData[tempH2 + lx] = MAKE_ARGB_8888((BYTE)a2, r1, g1, b1);
for (int i = 1; i < wrate + 1; ++i)
{
int tempW3 = mw * i;
if ((pHGE->nScreenWidth - tempW3) > lx)
{
GET_ARGB_8888(pNewTexData[tempH2 + lx + tempW3], a1, r1, g1, b1);
pNewTexData[tempH2 + lx + tempW3] = MAKE_ARGB_8888((BYTE)a2, r1, g1, b1);
}
}
}
else if (hrate)
{
for (int j = 0; j < hrate + 1; ++j)
{
if ((pHGE->nScreenHeight - mh * j) > ly)
{
int tempH2 = (ly + mh * j) * pHGE->nScreenWidth;
GET_ARGB_8888(pNewTexData[tempH2 + lx], a1, r1, g1, b1);
pNewTexData[tempH2 + lx] = MAKE_ARGB_8888((BYTE)a2, r1, g1, b1);
GET_ARGB_8888(pNewTexData[tempH2 + lx], a1, r1, g1, b1);
pNewTexData[tempH2 + lx] = MAKE_ARGB_8888((BYTE)a2, r1, g1, b1);
}
}
}
else
{
int tempH2 = ly * pHGE->nScreenWidth;
GET_ARGB_8888(pNewTexData[tempH2 + lx], a1, r1, g1, b1);
pNewTexData[tempH2 + lx] = MAKE_ARGB_8888((BYTE)a2, r1, g1, b1);
}
}
}
}
pHGE->Texture_Unlock(newTex);
GetAppPtr()->SystemUpdate();
if(pHGE->bActive || pHGE->bDontSuspend)
{
pHGE->Gfx_BeginScene();
pHGE->Gfx_RenderQuad(&frzQuad);
pHGE->Gfx_RenderQuad(&newQuad);
pHGE->Gfx_EndScene();
if (pHGE->bShowFps)
{
wsprintfW(pHGE->szTitleFps, L"%s - %d FPS", pHGE->szWinTitle, GetAppPtr()->GetRealFps());
SetWindowText(pHGE->hwnd, pHGE->szTitleFps);
}
}
GetAppPtr()->LimitFps(pHGE->nHGEFPS);
duration--;
gray += rate;
} while (duration);
}
else
{
do
{
gray += rate;
DWORD * pFrzTexData = pHGE->Texture_Lock(pHGE->freezeTex, false);
for (int ly = 0; ly < dh; ++ly)
{
int tempW1 = ly * mw;
int tempW2 = ly * pHGE->nScreenWidth;
for (int lx = 0; lx < mw; ++lx)
{
r2 = GET_ARGB_R(pMidTexData[tempW1 + lx]);
if ((BYTE)gray > r2)
{
pFrzTexData[tempW2 + lx] = 0;
if ((pHGE->nScreenWidth - mw) > lx)
{
pFrzTexData[tempW2 + lx + mw] = 0;
}
if ((pHGE->nScreenHeight - mh) > ly)
{
pFrzTexData[(ly + mh) * pHGE->nScreenWidth + lx] = 0;
if ((pHGE->nScreenWidth - mw) > lx)
pFrzTexData[(ly + mh) * pHGE->nScreenWidth + lx + mw] = 0;
}
}
}
}
pHGE->Texture_Unlock(pHGE->freezeTex);
GetAppPtr()->SystemUpdate();
if(pHGE->bActive || pHGE->bDontSuspend)
{
pHGE->Gfx_BeginScene();
pHGE->Gfx_RenderQuad(&newQuad);
pHGE->Gfx_RenderQuad(&frzQuad);
pHGE->Gfx_EndScene();
if (pHGE->bShowFps)
{
wsprintfW(pHGE->szTitleFps, L"%s - %d FPS", pHGE->szWinTitle, GetAppPtr()->GetRealFps());
SetWindowText(pHGE->hwnd, pHGE->szTitleFps);
}
}
GetAppPtr()->LimitFps(pHGE->nHGEFPS);
duration--;
} while (duration);
}
pHGE->Texture_Free(midTex);
}
else
{
float rate = 255.0 / duration;
float al = 0;
pHGE->bFreeze = false;
do
{
al += rate;
newQuad.v[0].col =
newQuad.v[1].col =
newQuad.v[2].col =
newQuad.v[3].col = 0x00ffffff + ((BYTE)al << 24);
GetAppPtr()->SystemUpdate();
if(pHGE->bActive || pHGE->bDontSuspend)
{
pHGE->Gfx_BeginScene();
//pHGE->Gfx_Clear(0);
pHGE->Gfx_RenderQuad(&frzQuad);
pHGE->Gfx_RenderQuad(&newQuad);
pHGE->Gfx_EndScene();
if (pHGE->bShowFps)
{
wsprintfW(pHGE->szTitleFps, L"%s - %d FPS", pHGE->szWinTitle, GetAppPtr()->GetRealFps());
SetWindowText(pHGE->hwnd, pHGE->szTitleFps);
}
}
GetAppPtr()->LimitFps(pHGE->nHGEFPS);
duration--;
} while (duration);
}
pHGE->Texture_Free(newTex);
newTex = 0;
pHGE->Texture_Free(pHGE->freezeTex);
pHGE->freezeTex = 0;
}