304 lines
7.4 KiB
C++
304 lines
7.4 KiB
C++
#ifdef STARTUPANIMATION
|
|
|
|
#include "ntos.h"
|
|
|
|
#include "precomp.h"
|
|
#include "mslogo.h"
|
|
#include "renderer.h"
|
|
#include "xbs_app.h"
|
|
#include "xbs_math.h"
|
|
|
|
#pragma pack(1)
|
|
|
|
typedef struct _IMAGE_RUN1 {
|
|
UINT fOne : 1;
|
|
UINT Size : 3;
|
|
UINT Intensity : 4;
|
|
} IMAGE_RUN1;
|
|
|
|
typedef struct _IMAGE_RUN2 {
|
|
UINT fOne : 1;
|
|
UINT fTwo : 1;
|
|
UINT Size : 10;
|
|
UINT Intensity : 4;
|
|
} IMAGE_RUN2;
|
|
|
|
#pragma pack()
|
|
|
|
// MS Logo sync event
|
|
extern "C" {
|
|
INITIALIZED_KEVENT(g_EventLogo, NotificationEvent, FALSE);
|
|
INITIALIZED_KEVENT(g_EventLogoWaiting, NotificationEvent, FALSE);
|
|
}
|
|
|
|
IDirect3DVertexBuffer8 *g_pVBMicrosoftLogo;
|
|
IDirect3DTexture8* g_pTexMicrosoftLogo;
|
|
PBYTE g_ImageLogo;
|
|
UINT g_ImageLogoSize;
|
|
|
|
typedef struct _TheVerts {
|
|
float x,y,z,w;
|
|
float u, v;
|
|
} TheVerts;
|
|
|
|
const TheVerts Verts[] =
|
|
{
|
|
{270.0f, 400.0f, 0.5f, 1.0f, 0.0f, 0.0f},
|
|
{370.0f, 417.0f, 0.5f, 1.0f, 100.0f, 17.0f},
|
|
{270.0f, 417.0f, 0.5f, 1.0f, 0.0f, 17.0f},
|
|
{370.0f, 400.0f, 0.5f, 1.0f, 100.0f, 0.0f},
|
|
{370.0f, 417.0f, 0.5f, 1.0f, 100.0f, 17.0f},
|
|
{270.0f, 400.0f, 0.5f, 1.0f, 0.0f, 0.0f},
|
|
};
|
|
|
|
BOOL InitVB(IDirect3DDevice8 *pDev)
|
|
{
|
|
IDirect3DVertexBuffer8 *pVB;
|
|
void *pVerts;
|
|
|
|
if (FAILED(IDirect3DDevice8_CreateVertexBuffer(pDev,
|
|
sizeof(Verts),
|
|
D3DUSAGE_WRITEONLY,
|
|
D3DFVF_XYZRHW | D3DFVF_TEX1,
|
|
D3DPOOL_MANAGED,
|
|
&pVB)))
|
|
{
|
|
return FALSE;
|
|
}
|
|
|
|
g_pVBMicrosoftLogo = pVB;
|
|
|
|
IDirect3DVertexBuffer8_Lock(pVB, 0, sizeof(Verts), (BYTE **)(&pVerts), 0);
|
|
memcpy((void*)pVerts, (void*)Verts, sizeof(Verts));
|
|
IDirect3DVertexBuffer8_Unlock(pVB);
|
|
|
|
return TRUE;
|
|
}
|
|
|
|
const float F_15 = 15.0f;
|
|
const float F_P_5 = 0.5f;
|
|
|
|
COLORREF ColorFromIntensity(UINT intensity4bits)
|
|
{
|
|
UINT Base = 0xCC;
|
|
|
|
UINT cr = (UINT)((Base * intensity4bits) / F_15 + F_P_5);
|
|
|
|
return D3DCOLOR_ARGB(0xFF, cr, cr, cr);
|
|
}
|
|
|
|
BOOL InitTexture(IDirect3DDevice8 *pDev)
|
|
{
|
|
IDirect3DTexture8* pTex;
|
|
D3DLOCKED_RECT lock;
|
|
UINT x = 0, i, j;
|
|
DWORD dwLine;
|
|
DWORD dwAddr;
|
|
IMAGE_RUN1 *pRun1;
|
|
IMAGE_RUN2 *pRun2;
|
|
UINT Size;
|
|
UINT Intensity;
|
|
|
|
if (FAILED(IDirect3DDevice8_CreateTexture(pDev,
|
|
100,
|
|
17,
|
|
1,
|
|
0,
|
|
D3DFMT_LIN_X8R8G8B8,
|
|
0,
|
|
&pTex)))
|
|
{
|
|
return FALSE;
|
|
}
|
|
|
|
g_pTexMicrosoftLogo = pTex;
|
|
|
|
IDirect3DTexture8_LockRect(pTex, 0, &lock, NULL, 0);
|
|
dwLine = (DWORD)lock.pBits;
|
|
dwAddr = dwLine;
|
|
i = 0;
|
|
|
|
while(i < g_ImageLogoSize)
|
|
{
|
|
Size = 0;
|
|
Intensity = 0;
|
|
|
|
pRun1 = (IMAGE_RUN1*)&g_ImageLogo[i];
|
|
if (pRun1->fOne)
|
|
{
|
|
Size = pRun1->Size;
|
|
Intensity = pRun1->Intensity;
|
|
i += 1;
|
|
}
|
|
else
|
|
{
|
|
pRun2 = (IMAGE_RUN2*)&g_ImageLogo[i];
|
|
if (pRun2->fTwo)
|
|
{
|
|
Size = pRun2->Size;
|
|
Intensity = pRun2->Intensity;
|
|
i += 2;
|
|
}
|
|
}
|
|
|
|
for (j = 0; j < Size; j++)
|
|
{
|
|
if (Intensity == 0)
|
|
{
|
|
*(DWORD*)dwAddr = 0xFF000000;
|
|
}
|
|
else
|
|
{
|
|
*(DWORD*)dwAddr = ColorFromIntensity(Intensity);
|
|
}
|
|
if (x >= 99)
|
|
{
|
|
x = 0;
|
|
dwLine += lock.Pitch;
|
|
dwAddr = dwLine;
|
|
}
|
|
else
|
|
{
|
|
x++;
|
|
dwAddr += sizeof(DWORD);
|
|
}
|
|
}
|
|
}
|
|
|
|
IDirect3DTexture8_UnlockRect(pTex, 0);
|
|
|
|
return TRUE;
|
|
}
|
|
|
|
void UnInitMicrosoftLogo()
|
|
{
|
|
if (g_ImageLogo != NULL)
|
|
{
|
|
MemFree(g_ImageLogo);
|
|
}
|
|
|
|
if (g_pVBMicrosoftLogo != NULL)
|
|
{
|
|
g_pVBMicrosoftLogo->Release();
|
|
}
|
|
|
|
if (g_pTexMicrosoftLogo != NULL)
|
|
{
|
|
g_pTexMicrosoftLogo->Release();
|
|
}
|
|
}
|
|
|
|
void RenderMicrosoftLogo()
|
|
{
|
|
if (g_ImageLogo == NULL)
|
|
{
|
|
return;
|
|
}
|
|
|
|
if (!InitVB(gpd3dDev) || !InitTexture(gpd3dDev))
|
|
{
|
|
UnInitMicrosoftLogo();
|
|
return;
|
|
}
|
|
|
|
IDirect3DDevice8 *pDev = gpd3dDev;
|
|
IDirect3DSurface8 *pSurface;
|
|
pDev->GetBackBuffer(-1, D3DBACKBUFFER_TYPE_MONO, &pSurface);
|
|
pDev->SetRenderTarget(pSurface, NULL);
|
|
|
|
const DWORD RenderStates[] =
|
|
{
|
|
D3DRS_FILLMODE, D3DFILL_SOLID,
|
|
D3DRS_BACKFILLMODE, D3DFILL_SOLID,
|
|
D3DRS_CULLMODE, D3DCULL_NONE,
|
|
D3DRS_DITHERENABLE, TRUE,
|
|
D3DRS_ALPHATESTENABLE, FALSE,
|
|
D3DRS_ALPHABLENDENABLE, FALSE,
|
|
D3DRS_FOGENABLE, FALSE,
|
|
D3DRS_EDGEANTIALIAS, FALSE,
|
|
D3DRS_STENCILENABLE, FALSE,
|
|
D3DRS_LIGHTING, FALSE,
|
|
D3DRS_MULTISAMPLEMASK, 0xffffffff,
|
|
D3DRS_LOGICOP, D3DLOGICOP_NONE,
|
|
D3DRS_COLORWRITEENABLE, D3DCOLORWRITEENABLE_ALL,
|
|
D3DRS_YUVENABLE, FALSE,
|
|
};
|
|
|
|
const DWORD TextureStates[] =
|
|
{
|
|
D3DTSS_COLOROP, D3DTOP_SELECTARG1,
|
|
D3DTSS_COLORARG1, D3DTA_TEXTURE,
|
|
D3DTSS_ALPHAOP, D3DTOP_DISABLE,
|
|
D3DTSS_TEXCOORDINDEX, 0,
|
|
D3DTSS_ADDRESSU, D3DTADDRESS_CLAMP,
|
|
D3DTSS_ADDRESSV, D3DTADDRESS_CLAMP,
|
|
D3DTSS_COLORKEYOP, D3DTCOLORKEYOP_DISABLE,
|
|
D3DTSS_COLORSIGN, 0,
|
|
D3DTSS_ALPHAKILL, D3DTALPHAKILL_DISABLE,
|
|
D3DTSS_MINFILTER, D3DTEXF_LINEAR,
|
|
D3DTSS_MAGFILTER, D3DTEXF_LINEAR,
|
|
};
|
|
|
|
int i;
|
|
|
|
for (i = 0; i < sizeof(RenderStates) / (sizeof(DWORD) * 2); i++)
|
|
{
|
|
pDev->SetRenderState((D3DRENDERSTATETYPE)RenderStates[2*i],
|
|
RenderStates[2*i + 1]);
|
|
}
|
|
|
|
for (i = 0; i < sizeof(TextureStates) / (sizeof(DWORD) * 2); i++)
|
|
{
|
|
pDev->SetTextureStageState(0,
|
|
(D3DTEXTURESTAGESTATETYPE)TextureStates[2*i],
|
|
TextureStates[2*i + 1]);
|
|
}
|
|
|
|
IDirect3DDevice8_SetStreamSource(pDev, 0, g_pVBMicrosoftLogo, sizeof(Verts[0]));
|
|
IDirect3DDevice8_SetVertexShader(pDev, D3DFVF_XYZRHW | D3DFVF_TEX1);
|
|
IDirect3DDevice8_SetTexture(pDev, 0, (D3DBaseTexture*)g_pTexMicrosoftLogo);
|
|
|
|
IDirect3DDevice8_DrawPrimitive(pDev,
|
|
D3DPT_TRIANGLELIST,
|
|
0,
|
|
2);
|
|
|
|
pSurface->Release();
|
|
UnInitMicrosoftLogo();
|
|
pDev->PersistDisplay();
|
|
}
|
|
|
|
extern "C"
|
|
VOID AniSetLogo(PVOID pv, ULONG Size)
|
|
{
|
|
if (KeReadStateEvent(&g_EventLogo) == 0)
|
|
{
|
|
if (gpd3dDev != NULL && pv != NULL && Size <= PAGE_SIZE)
|
|
{
|
|
g_ImageLogo = (PBYTE)MemAlloc(Size);
|
|
if (g_ImageLogo != NULL)
|
|
{
|
|
memcpy(g_ImageLogo, pv, Size);
|
|
g_ImageLogoSize = Size;
|
|
}
|
|
}
|
|
|
|
KeSetEvent(&g_EventLogo, EVENT_INCREMENT, FALSE);
|
|
}
|
|
}
|
|
|
|
void WaitOnMicrosoftLogo()
|
|
{
|
|
// Signal the initialization thread that we're waiting for the logo. Note
|
|
// that this returns with the dispatcher database lock held, which the
|
|
// following wait call will release. This avoids an unnecessary context
|
|
// switch.
|
|
KeSetEvent(&g_EventLogoWaiting, EVENT_INCREMENT, TRUE);
|
|
|
|
KeWaitForSingleObject(&g_EventLogo, Executive, KernelMode, FALSE, NULL);
|
|
RenderMicrosoftLogo();
|
|
}
|
|
|
|
#endif // STARTUPANIMATION
|
|
|