Something went wrong. Try again.
the game where you go into mines and start crafting! but for consoles (forked directly from smartcmd's github)
Something went wrong. Try again.
17 kB · 503 lines
C++
at main
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503#include "stdafx.h"#include "..\..\Tesselator.h"#include "XUI_FontData.h"#include "XUI_Font.h"
extern IDirect3DDevice9 *g_pD3DDevice;
//--------------------------------------------------------------------------------------// Name: XUI_Font()// Desc: Constructor//--------------------------------------------------------------------------------------XUI_Font::XUI_Font(int iFontData, float scaleFactor, XUI_FontData *fontData) : m_iFontData(iFontData), m_fScaleFactor(scaleFactor){ m_fontData = fontData; refCount = 0;
m_fCursorX = 0.0f; m_fCursorY = 0.0f;
m_fXScaleFactor = m_fYScaleFactor = scaleFactor;
m_fSlantFactor = 0.0f; m_bRotate = FALSE; m_dRotCos = cos( 0.0 ); m_dRotSin = sin( 0.0 );
m_dwNestedBeginCount = 0L; // Initialize the window D3DDISPLAYMODE DisplayMode; g_pD3DDevice->GetDisplayMode( 0, &DisplayMode ); m_rcWindow.x1 = 0; m_rcWindow.y1 = 0; m_rcWindow.x2 = DisplayMode.Width; m_rcWindow.y2 = DisplayMode.Height;}
//--------------------------------------------------------------------------------------// Name: ~XUI_Font()// Desc: Destructor//--------------------------------------------------------------------------------------XUI_Font::~XUI_Font(){}
//--------------------------------------------------------------------------------------// Name: GetTextExtent()// Desc: Get the dimensions of a text string//--------------------------------------------------------------------------------------
VOID XUI_Font::GetTextExtent( const WCHAR* strText, FLOAT* pWidth, FLOAT* pHeight, BOOL bFirstLineOnly ) const{ assert( pWidth != NULL ); assert( pHeight != NULL );
// Set default text extent in output parameters int iWidth = 0; FLOAT fHeight = 0.0f;
if( strText ) { // Initialize counters that keep track of text extent int ix = 0; FLOAT fy = m_fontData->getFontHeight(); // One character high to start if( fy > fHeight ) fHeight = fy;
// Loop through each character and update text extent DWORD letter; while( (letter = *strText) != 0 ) { ++strText;
// Handle newline character if( letter == L'\n' ) { if( bFirstLineOnly ) break; ix = 0; fy += m_fontData->getFontYAdvance(); // since the height has changed, test against the height extent if( fy > fHeight ) fHeight = fy; }
// Handle carriage return characters by ignoring them. This helps when // displaying text from a file. if( letter == L'\r' ) continue;
// Translate unprintable characters XUI_FontData::SChar sChar = m_fontData->getChar(letter); // Get text extent for this character's glyph ix += sChar.getOffset(); ix += sChar.getWAdvance();
// Since the x widened, test against the x extent if (ix > iWidth) iWidth = ix; } }
// Convert the width to a float here, load/hit/store. :( FLOAT fWidth = static_cast<FLOAT>(iWidth); // Delay the use if fWidth to reduce LHS pain // Apply the scale factor to the result fHeight *= m_fYScaleFactor; // Store the final results *pHeight = fHeight;
fWidth *= m_fXScaleFactor; *pWidth = fWidth;}
//--------------------------------------------------------------------------------------// Name: GetTextWidth()// Desc: Returns the width in pixels of a text string//--------------------------------------------------------------------------------------FLOAT XUI_Font::GetTextWidth( const WCHAR* strText ) const{ FLOAT fTextWidth; FLOAT fTextHeight; GetTextExtent( strText, &fTextWidth, &fTextHeight ); return fTextWidth;}
//--------------------------------------------------------------------------------------// Name: Begin()// Desc: Prepares the font vertex buffers for rendering.//--------------------------------------------------------------------------------------VOID XUI_Font::Begin(){ PIXBeginNamedEvent( 0, "Text Rendering" );
// Set state on the first call if( 0 == m_dwNestedBeginCount ) { // Cache the global pointer into a register IDirect3DDevice9 *pD3dDevice = g_pD3DDevice; assert( pD3dDevice );
// Set the texture scaling factor as a vertex shader constant //D3DSURFACE_DESC TextureDesc; //m_pFontTexture->GetLevelDesc( 0, &TextureDesc ); // Get the description // Set render state assert(m_fontData->m_pFontTexture != NULL || m_fontData->m_iFontTexture > 0); if(m_fontData->m_pFontTexture != NULL) { pD3dDevice->SetTexture( 0, m_fontData->m_pFontTexture ); } else { glBindTexture(GL_TEXTURE_2D, m_fontData->m_iFontTexture); } //// Read the TextureDesc here to ensure no load/hit/store from GetLevelDesc() //FLOAT vTexScale[4]; //vTexScale[0] = 1.0f / TextureDesc.Width; // LHS due to int->float conversion //vTexScale[1] = 1.0f / TextureDesc.Height; //vTexScale[2] = 0.0f; //vTexScale[3] = 0.0f; // //pD3dDevice->SetRenderState( D3DRS_ALPHABLENDENABLE, TRUE ); //pD3dDevice->SetRenderState( D3DRS_SRCBLEND, D3DBLEND_SRCALPHA ); //pD3dDevice->SetRenderState( D3DRS_DESTBLEND, D3DBLEND_INVSRCALPHA ); //pD3dDevice->SetRenderState( D3DRS_BLENDOP, D3DBLENDOP_ADD ); //pD3dDevice->SetRenderState( D3DRS_ALPHATESTENABLE, TRUE ); //pD3dDevice->SetRenderState( D3DRS_ALPHAREF, 0x08 ); //pD3dDevice->SetRenderState( D3DRS_ALPHAFUNC, D3DCMP_GREATEREQUAL ); //pD3dDevice->SetRenderState( D3DRS_FILLMODE, D3DFILL_SOLID ); //pD3dDevice->SetRenderState( D3DRS_CULLMODE, D3DCULL_CCW ); //pD3dDevice->SetRenderState( D3DRS_ZENABLE, FALSE ); //pD3dDevice->SetRenderState( D3DRS_STENCILENABLE, FALSE ); //pD3dDevice->SetRenderState( D3DRS_VIEWPORTENABLE, FALSE ); //pD3dDevice->SetSamplerState( 0, D3DSAMP_MINFILTER, D3DTEXF_LINEAR ); //pD3dDevice->SetSamplerState( 0, D3DSAMP_MAGFILTER, D3DTEXF_LINEAR ); //pD3dDevice->SetSamplerState( 0, D3DSAMP_ADDRESSU, D3DTADDRESS_CLAMP ); //pD3dDevice->SetSamplerState( 0, D3DSAMP_ADDRESSV, D3DTADDRESS_CLAMP ); }
// Keep track of the nested begin/end calls. m_dwNestedBeginCount++;}
//--------------------------------------------------------------------------------------// Name: DrawText()// Desc: Draws text as textured polygons//--------------------------------------------------------------------------------------VOID XUI_Font::DrawText( DWORD dwColor, const WCHAR* strText, DWORD dwFlags, FLOAT fMaxPixelWidth ){ DrawText( m_fCursorX, m_fCursorY, dwColor, strText, dwFlags, fMaxPixelWidth );}
//--------------------------------------------------------------------------------------// Name: DrawShadowText()// Desc: Draws text as textured polygons//--------------------------------------------------------------------------------------VOID XUI_Font::DrawShadowText( FLOAT fOriginX, FLOAT fOriginY, DWORD dwColor, DWORD dwShadowColor, const WCHAR* strText, DWORD dwFlags, FLOAT fMaxPixelWidth){ float fXShadow=1.0f, fYShadow=1.0f; // 4J Stu - Don't move the drop shadow as much //DrawText( fOriginX + (1*m_fXScaleFactor), fOriginY + (1*m_fYScaleFactor), dwColor, strText, dwFlags, fMaxPixelWidth, true );
// 4J-PB - if we're in 480 widescreen, we need to draw the drop shadow at +2 pixels, so that when the scene is halved, it's at +1 if(!RenderManager.IsHiDef()) { if(RenderManager.IsWidescreen()) { fXShadow=2.0f; fYShadow=2.0f; } //else //{ // 480 SD mode - the draw text call will reposition the y //} } DrawText( fOriginX + fXShadow, fOriginY + fYShadow, dwColor, strText, dwFlags, fMaxPixelWidth, true ); DrawText( fOriginX, fOriginY, dwColor, strText, dwFlags, fMaxPixelWidth ); //DrawText( fOriginX + 1, fOriginY + 1, dwShadowColor, strText, dwFlags, fMaxPixelWidth); //DrawText( fOriginX, fOriginY, dwColor, strText, dwFlags, fMaxPixelWidth );}
//--------------------------------------------------------------------------------------// Name: DrawText()// Desc: Draws text as textured polygons// TODO: This function should use the Begin/SetVertexData/End() API when it// becomes available.//--------------------------------------------------------------------------------------VOID XUI_Font::DrawText( FLOAT fOriginX, FLOAT fOriginY, DWORD dwColor, const WCHAR* strText, DWORD dwFlags, FLOAT fMaxPixelWidth, bool darken /*= false*/ ){ if( NULL == strText ) return; if( L'\0' == strText[0] ) return; // 4J-PB - if we're in 480 widescreen mode, we need to ensure that the font characters are aligned on an even boundary if they are a 2x multiple if(!RenderManager.IsHiDef()) { if(RenderManager.IsWidescreen()) { int iScaleX=(int)m_fXScaleFactor; int iOriginX; if(iScaleX%2==0) { iOriginX=(int)fOriginX; if(iOriginX%2==1) { fOriginX+=1.0f; } } int iScaleY=(int)m_fYScaleFactor; int iOriginY; if(iScaleY%2==0) { iOriginY=(int)fOriginY; if(iOriginY%2==1) { fOriginY+=1.0f; } } } else { // 480 SD mode - y needs to be on a pixel boundary when multiplied by 1.5, so if it's an odd number, subtract 1/3 from it int iOriginY=(int)fOriginY; if(iOriginY%2==1) { fOriginY-=1.0f/3.0f; } } } // Create a PIX user-defined event that encapsulates all of the text draw calls. // This makes DrawText calls easier to recognize in PIX captures, and it makes // them take up fewer entries in the event list. PIXBeginNamedEvent( dwColor, "DrawText: %S", strText );
// Set up stuff to prepare for drawing text Begin();
if (darken) { int oldAlpha = dwColor & 0xff000000; dwColor = (dwColor & 0xfcfcfc) >> 2; dwColor += oldAlpha; }
float r = ((dwColor >> 16) & 0xff) / 255.0f; float g = ((dwColor >> 8) & 0xff) / 255.0f; float b = ((dwColor) & 0xff) / 255.0f; float a = ((dwColor >> 24) & 0xff) / 255.0f; if (a == 0) a = 1; // a = 1; glColor4f(r, g, b, a);
// Set the starting screen position if( ( fOriginX < 0.0f ) || ( ( dwFlags & ATGFONT_RIGHT ) && ( fOriginX <= 0.0f ) ) ) { fOriginX += ( m_rcWindow.x2 - m_rcWindow.x1 ); } // 4J-PB - not sure what this code was intending to do, but it removed a line of text that is slightly off the top of the control, rather than having it partially render// if( fOriginY < 0.0f )// {// fOriginY += ( m_rcWindow.y2 - m_rcWindow.y1 );// }
m_fCursorX = floorf( fOriginX ); m_fCursorY = floorf( fOriginY );
// Adjust for padding fOriginY -= m_fontData->getFontTopPadding(); XUI_FontData::SChar sChar = m_fontData->getChar(L'.'); FLOAT fEllipsesPixelWidth = m_fXScaleFactor * 3.0f * (sChar.getOffset() + sChar.getWAdvance());
if( dwFlags & ATGFONT_TRUNCATED ) { // Check if we will really need to truncate the string if( fMaxPixelWidth <= 0.0f ) { dwFlags &= ( ~ATGFONT_TRUNCATED ); } else { FLOAT w, h; GetTextExtent( strText, &w, &h, TRUE );
// If not, then clear the flag if( w <= fMaxPixelWidth ) dwFlags &= ( ~ATGFONT_TRUNCATED ); } }
// If vertically centered, offset the starting m_fCursorY value if( dwFlags & ATGFONT_CENTER_Y ) { FLOAT w, h; GetTextExtent( strText, &w, &h ); m_fCursorY = floorf( m_fCursorY - (h * 0.5f) ); }
// Add window offsets FLOAT Winx = static_cast<FLOAT>(m_rcWindow.x1); FLOAT Winy = static_cast<FLOAT>(m_rcWindow.y1); fOriginX += Winx; fOriginY += Winy; m_fCursorX += Winx; m_fCursorY += Winy;
// Set a flag so we can determine initial justification effects BOOL bStartingNewLine = TRUE;
DWORD dwNumEllipsesToDraw = 0;
// Begin drawing the vertices
DWORD dwNumChars = wcslen( strText ) + ( dwFlags & ATGFONT_TRUNCATED ? 3 : 0 );
bStartingNewLine = TRUE;
// Draw four vertices for each glyph while( *strText ) { WCHAR letter;
if( dwNumEllipsesToDraw ) { letter = L'.'; } else { // If starting text on a new line, determine justification effects if( bStartingNewLine ) { if( dwFlags & ( ATGFONT_RIGHT | ATGFONT_CENTER_X ) ) { // Get the extent of this line FLOAT w, h; GetTextExtent( strText, &w, &h, TRUE );
// Offset this line's starting m_fCursorX value if( dwFlags & ATGFONT_RIGHT ) m_fCursorX = floorf( fOriginX - w ); if( dwFlags & ATGFONT_CENTER_X ) m_fCursorX = floorf( fOriginX - w * 0.5f ); } bStartingNewLine = FALSE; }
// Get the current letter in the string letter = *strText++;
// Handle the newline character if( letter == L'\n' ) { m_fCursorX = fOriginX; m_fCursorY += m_fontData->getFontYAdvance() * m_fYScaleFactor; bStartingNewLine = TRUE;
continue; }
// Handle carriage return characters by ignoring them. This helps when // displaying text from a file. if( letter == L'\r' ) continue; }
// Translate unprintable characters XUI_FontData::SChar sChar = m_fontData->getChar( letter );
FLOAT fOffset = m_fXScaleFactor * ( FLOAT )sChar.getOffset(); FLOAT fAdvance = m_fXScaleFactor * ( FLOAT )sChar.getWAdvance(); // 4J Use the font max width otherwise scaling doesnt look right FLOAT fWidth = m_fXScaleFactor * (sChar.tu2() - sChar.tu1());//( FLOAT )pGlyph->wWidth; FLOAT fHeight = m_fYScaleFactor * m_fontData->getFontHeight();
if( 0 == dwNumEllipsesToDraw ) { if( dwFlags & ATGFONT_TRUNCATED ) { // Check if we will be exceeded the max allowed width if( m_fCursorX + fOffset + fWidth + fEllipsesPixelWidth + m_fSlantFactor > fOriginX + fMaxPixelWidth ) { // Yup, draw the three ellipses dots instead dwNumEllipsesToDraw = 3; continue; } } }
// Setup the screen coordinates m_fCursorX += fOffset; FLOAT X4 = m_fCursorX; FLOAT X1 = X4 + m_fSlantFactor; FLOAT X3 = X4 + fWidth; FLOAT X2 = X1 + fWidth; FLOAT Y1 = m_fCursorY; FLOAT Y3 = Y1 + fHeight; FLOAT Y2 = Y1; FLOAT Y4 = Y3;
m_fCursorX += fAdvance;
// Add the vertices to draw this glyph
FLOAT tu1 = sChar.tu1() / (float)m_fontData->getImageWidth(); FLOAT tv1 = sChar.tv1() / (float)m_fontData->getImageHeight(); FLOAT tu2 = sChar.tu2() / (float)m_fontData->getImageWidth(); FLOAT tv2 = sChar.tv2() / (float)m_fontData->getImageHeight();
Tesselator *t = Tesselator::getInstance(); t->begin(); t->vertexUV(X1, Y1, 0.0f, tu1, tv1); t->vertexUV(X2, Y2, 0.0f, tu2, tv1); t->vertexUV(X3, Y3, 0.0f, tu2, tv2); t->vertexUV(X4, Y4, 0.0f, tu1, tv2); t->end();
// If drawing ellipses, exit when they're all drawn if( dwNumEllipsesToDraw ) { if( --dwNumEllipsesToDraw == 0 ) break; }
dwNumChars--; }
// Undo window offsets m_fCursorX -= Winx; m_fCursorY -= Winy;
// Call End() to complete the begin/end pair for drawing text End();
// Close off the user-defined event opened with PIXBeginNamedEvent. PIXEndNamedEvent();}
//--------------------------------------------------------------------------------------// Name: End()// Desc: Paired call that restores state set in the Begin() call.//--------------------------------------------------------------------------------------VOID XUI_Font::End(){ assert( m_dwNestedBeginCount > 0 ); if( --m_dwNestedBeginCount > 0 ) { PIXEndNamedEvent(); return; }
PIXEndNamedEvent();}