?? gfx.cpp
字號:
// Move to the next line.
if (byAttributes & 0x80)
pSurfaceMemory -= lSurfacePitch;
else
pSurfaceMemory += lSurfacePitch;
// Move to the next byte in the sprite.
pbyTileByte++;
}
// Restore the surface memory pointer to the beginning
// of the scanline.
pSurfaceMemory = pSaveVideoMemStart;
//-------------------------------------------------------------------------
// Draw the second part of the sprite if its a 8x16 sprite.
// Thats located in in bit 5 of reg $2000.
//-------------------------------------------------------------------------
if (CPU.Memory[0x2000] & 0x20)
{
BYTE byColor; // Index into the NES palette for the sprite.
BYTE* pbyTileByte; // Pointer to the pattern table byte.
BYTE* pSaveVideoMemStart = pSurfaceMemory;
// Save all the information about the sprite.
BYTE byYPos = abySPRRAM[(bySpriteNum*4)] + 8;
BYTE byTileNum = abySPRRAM[(bySpriteNum*4)+1] + 1;
BYTE byAttributes = abySPRRAM[(bySpriteNum*4)+2];
BYTE byXPos = abySPRRAM[(bySpriteNum*4)+3];
BYTE byUpperColor = (byAttributes & 0x3) << 2;
// Get the pointer to the tile byte in the pattern table for the sprite.
pbyTileByte = (byTileNum * 16) + PPU.apbyPatternTables[(CPU.Memory[0x2000]&0x08)>>3];
// Move the video memory pointer to where the sprite is supposed to be horizontally.
if (byAttributes & 0x40)
pSurfaceMemory += (byXPos * lBytesPerPixel) + (8 * lBytesPerPixel);
else
pSurfaceMemory += byXPos * lBytesPerPixel;
// Move the video memory pointer to where the sprite is supposed to be vertically.
if (byAttributes & 0x80)
pSurfaceMemory += ((byYPos + 8) * lSurfacePitch);
else
pSurfaceMemory += byYPos * lSurfacePitch;
// Draw the sprite by drawing each tile line then moving to the next byte.
for (int i = 0; i < 8; i++)
{
BYTE byTestBit = 0x80; // Color testing bit for the sprite tile.
BYTE byColorShiftVal = 7; // Number of bits to shift the color by.
while (byTestBit != 0)
{
// The color is the to lower bits from the pattern table
// obtained in the same way as a background tile plus the
// two uppercolor bits in the lower 2 bits of the attribute
// byte.
byColor = ((*pbyTileByte & byTestBit) >> byColorShiftVal) |
(((*(pbyTileByte+8) & byTestBit) >> byColorShiftVal) << 1);
// Draw the pixel on the screen if the color is not 0.
if (byColor != 0)
PutSpritePixel(byColor | byUpperColor);
// Move to the next pixel.
if (byAttributes & 0x40)
pSurfaceMemory -= lBytesPerPixel;
else
pSurfaceMemory += lBytesPerPixel;
byColorShiftVal--;
byTestBit >>= 1;
}
// Reset the horizontal video position for the next line.
if (byAttributes & 0x40)
pSurfaceMemory += (8 * lBytesPerPixel);
else
pSurfaceMemory -= (8 * lBytesPerPixel);
// Move to the next line.
if (byAttributes & 0x80)
pSurfaceMemory -= lSurfacePitch;
else
pSurfaceMemory += lSurfacePitch;
// Move to the next byte in the sprite.
pbyTileByte++;
}
// Restore the surface memory pointer to the beginning
// of the scanline.
pSurfaceMemory = pSaveVideoMemStart;
}
} // end DrawSprite()
//------------------------------------------------------------------------------
// Name: DrawSpriteLine()
// Desc: Draws a 8 pixel scanline for the sprite.
//------------------------------------------------------------------------------
VOID DrawSpriteLine(BYTE bySpriteNum)
{
BYTE byTestBit = 0x80; // Color testing bit for the sprite tile.
BYTE byColorShiftVal = 7; // Number of bits to shift the color by.
BYTE byColor; // Index into the NES palette for the sprite.
BYTE* pbyScanlineByte; // Pointer to the pattern table byte.
BYTE* pSaveVideoMemStart = pSurfaceMemory;
// Save all the information about the sprite.
BYTE byYPos = abySPRRAM[(bySpriteNum*4)];
BYTE byTileNum = abySPRRAM[(bySpriteNum*4)+1];
BYTE byAttributes = abySPRRAM[(bySpriteNum*4)+2];
BYTE byXPos = abySPRRAM[(bySpriteNum*4)+3];
BYTE byUpperColor = (byAttributes & 0x3) << 2;
// If one of the sprites scanlines is on this screen scaline,
// then we have to draw that sprite scanline.
if ((unsigned)(wScanline - byYPos) < 8)
{
// Get the pointer to the scanline byte in the pattern table for the sprite.
pbyScanlineByte = (byTileNum * 16) + PPU.apbyPatternTables[(CPU.Memory[0x2000]&0x08)>>3];
pbyScanlineByte += (wScanline - byYPos);
// Move the video memory pointer to where the sprite is supposed to be.
if (byAttributes & 0x40)
pSurfaceMemory += (byXPos * lBytesPerPixel) + (7 * lBytesPerPixel);
else
pSurfaceMemory += byXPos * lBytesPerPixel;
// Draw the sprite scanline.
while (byTestBit != 0)
{
// The color is the to lower bits from the pattern table
// obtained in the same way as a background tile plus the
// two uppercolor bits in the lower 2 bits of the attribute
// byte.
byColor = ((*pbyScanlineByte & byTestBit) >> byColorShiftVal) |
(((*(pbyScanlineByte+8) & byTestBit) >> byColorShiftVal) << 1) |
byUpperColor;
// Draw the pixel on the screen if the color is not 0.
if (byColor != 0)
PutSpritePixel(byColor);
// Move to the next pixel.
if (byAttributes & 0x40)
pSurfaceMemory -= lBytesPerPixel;
else
pSurfaceMemory += lBytesPerPixel;
byColorShiftVal--;
byTestBit >>= 1;
}
// Restore the surface memory pointer to the beginning
// of the scanline.
pSurfaceMemory = pSaveVideoMemStart;
}
} // end DrawSpriteLine()
//------------------------------------------------------------------------------
// Name: GetMaskInfo()
// Desc: Uses the color's bitmasks to calculate values which we
// will use to compile the pixel value.
//------------------------------------------------------------------------------
INT GetMaskInfo(DWORD dwBitmask, int* pnShift)
{
int nPrecision = 0;
int nShift = 0;
// Count the zeros on right hand side.
while (!(dwBitmask & 0x01))
{
dwBitmask >>= 1;
nShift++;
}
// Count the ones on right hand side.
while (dwBitmask & 0x01)
{
dwBitmask >>= 1;
nPrecision++;
}
// Save the shift value.
*pnShift = nShift;
// Return the number of ones.
return nPrecision;
} // end GetMaskInfo()
//------------------------------------------------------------------------------
// Name: CompilePixel()
// Desc: Stores the four bytes corresponding to the compiled pixel
// value in a class variable.
//------------------------------------------------------------------------------
VOID CompilePixel(LPDIRECTDRAWSURFACE7 lpSurf, int nColorIndex, int r, int g, int b)
{
DDPIXELFORMAT DDpf; // DirectDraw pixel format structure.
int rsz, gsz, bsz; // Bitsize of field.
int rsh, gsh, bsh; // 0抯 on left (the shift value).
DWORD dwCompiledPixel; // Our pixel with r,g,b values compiled.
// Get the pixel format.
ZeroMemory (&DDpf, sizeof(DDpf));
DDpf.dwSize = sizeof(DDpf);
lpSurf->GetPixelFormat(&DDpf);
// Get the shift and precision values and store them.
rsz = GetMaskInfo(DDpf.dwRBitMask, &rsh);
gsz = GetMaskInfo(DDpf.dwGBitMask, &gsh);
bsz = GetMaskInfo(DDpf.dwBBitMask, &bsh);
// Keep only the MSB bits of component.
r >>= (8-rsz);
g >>= (8-gsz);
b >>= (8-bsz);
// Shift them into place.
r <<= rsh;
g <<= gsh;
b <<= bsh;
// Store the compiled pixel.
dwCompiledPixel = (DWORD)(r | g | b);
abyColors[nColorIndex][3] = (BYTE)(dwCompiledPixel);
abyColors[nColorIndex][2] = (BYTE)(dwCompiledPixel >>= 8);
abyColors[nColorIndex][1] = (BYTE)(dwCompiledPixel >>= 8);
abyColors[nColorIndex][0] = (BYTE)(dwCompiledPixel >>= 8);
return;
} // end CompilePixel()
//------------------------------------------------------------------------------
// Name: PutBackgroundPixel()
// Desc: Puts a background pixel independant of the bit depth
// on the locked surface.
//------------------------------------------------------------------------------
VOID __stdcall PutBackgroundPixel(BYTE nColor)
{
// Copy the pointer to video memory so the main one doesn't get modified.
BYTE *pVideoMem = pSurfaceMemory;
// Speed up the array access in the loop by storing this here.
BYTE byColor = PPU.abyPalettes[nColor];
// Put the number of bytes for each pixel on the surface.
for (int i = 3; i >= FourMinusBPP; i--)
{
*pVideoMem = abyColors[byColor][i];
pVideoMem++;
}
} // end PutBackgroundPixel()
//------------------------------------------------------------------------------
// Name: PutSpritePixel()
// Desc: Puts a background pixel independant of the bit depth
// on the locked surface.
//------------------------------------------------------------------------------
VOID __stdcall PutSpritePixel(BYTE nColor)
{
// Copy the pointer to video memory so the main one doesn't get modified.
BYTE *pVideoMem = pSurfaceMemory;
// Speed up the array access in the loop by storing this here.
BYTE byColor = PPU.abyPalettes[0x10+nColor];
// Put the number of bytes for each pixel on the surface.
for (int i = 3; i >= FourMinusBPP; i--)
{
*pVideoMem = abyColors[byColor][i];
pVideoMem++;
}
} // end PutSpritePixel()
//------------------------------------------------------------------------------
// Name: ClearScreen()
// Desc: Clears the NES screen to the background color.
//------------------------------------------------------------------------------
VOID ClearScreen(COLORREF crColor)
{
DDBLTFX ddbltfx;
// Fill the NES screen surface with the background color.
ddbltfx.dwSize = sizeof(DDBLTFX);
ddbltfx.dwFillColor = crColor;
lpddsScreen->Blt(NULL, NULL, NULL, DDBLT_COLORFILL | DDBLT_WAIT, &ddbltfx);
} // end ClearScreen()
//------------------------------------------------------------------------------
// Name: UpdateBounds()
// Desc: Updates the rect for ......
//------------------------------------------------------------------------------
HRESULT UpdateBounds(HWND hwnd)
{
POINT ptWindow; // Point used for converting client to window coordinates.
// Get the client rectangle.
GetClientRect(hwnd, &rcScreen);
// Convert the top left coordinates.
ptWindow.x = rcScreen.left;
ptWindow.y = rcScreen.top;
ClientToScreen(hwnd, &ptWindow);
rcScreen.left = ptWindow.x;
rcScreen.top = ptWindow.y;
// Convert the bottom right coordinates.
ptWindow.x = rcScreen.right;
ptWindow.y = rcScreen.bottom;
ClientToScreen(hwnd, &ptWindow);
rcScreen.right = ptWindow.x;
rcScreen.bottom = ptWindow.y;
return S_OK;
} // end UpdateBounds()
//------------------------------------------------------------------------------
// Name: OutputText()
// Desc: Outputs text to the screen surface.
//------------------------------------------------------------------------------
VOID OutputText(LPSTR strText, INT nX, INT nY, COLORREF cfFront, COLORREF cfBack)
{
HDC hdc;
if (lpddsScreen->GetDC(&hdc) == DD_OK)
{
SetBkColor(hdc, cfBack);
SetTextColor(hdc, cfFront);
TextOut(hdc, nX, nY, strText, lstrlen(strText));
lpddsScreen->ReleaseDC(hdc);
}
} // end OutputText()
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -