From f56bb35301836e56582a575a75864392a0177875 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=B8rgen=20P=2E=20Tjern=C3=B8?= Date: Mon, 2 Dec 2013 19:31:46 -0800 Subject: Fix line endings. WHAMMY. --- mp/src/public/scratchpad3d.cpp | 1270 ++++++++++++++++++++-------------------- 1 file changed, 635 insertions(+), 635 deletions(-) (limited to 'mp/src/public/scratchpad3d.cpp') diff --git a/mp/src/public/scratchpad3d.cpp b/mp/src/public/scratchpad3d.cpp index 86ef77f6..96db2174 100644 --- a/mp/src/public/scratchpad3d.cpp +++ b/mp/src/public/scratchpad3d.cpp @@ -1,635 +1,635 @@ -//========= Copyright Valve Corporation, All rights reserved. ============// -// -// Purpose: -// -// $NoKeywords: $ -//=============================================================================// - -#include -#include "scratchpad3d.h" -#include "tier0/dbg.h" - -// memdbgon must be the last include file in a .cpp file!!! -#include "tier0/memdbgon.h" - -#ifndef POSIX -// NOTE - linux doesn't need any of this code! - -extern "C" -{ - extern void __stdcall Sleep( unsigned long ms ); -}; - - -class CFileRead -{ -public: - CFileRead( IFileSystem* pFileSystem, FileHandle_t fp ) - { - m_pFileSystem = pFileSystem; - m_fp = fp; - m_Pos = 0; - } - - bool Read( void *pDest, int len ) - { - int count = m_pFileSystem->Read( pDest, len, m_fp ); - m_Pos += count; - return count == len; - } - - IFileSystem* m_pFileSystem; - FileHandle_t m_fp; - int m_Pos; -}; - - -// ------------------------------------------------------------------------ // -// CCommand_Point. -// ------------------------------------------------------------------------ // - -void CScratchPad3D::CCommand_Point::Read( CFileRead *pFile ) -{ - pFile->Read( &m_flPointSize, sizeof(m_flPointSize) ); - pFile->Read( &m_Vert, sizeof(m_Vert) ); -} - -void CScratchPad3D::CCommand_Point::Write( IFileSystem* pFileSystem, FileHandle_t fp ) -{ - pFileSystem->Write( &m_flPointSize, sizeof(m_flPointSize), fp ); - pFileSystem->Write( &m_Vert, sizeof(m_Vert), fp ); -} - - -// ------------------------------------------------------------------------ // -// CCommand_Line. -// ------------------------------------------------------------------------ // - -void CScratchPad3D::CCommand_Line::Read( CFileRead *pFile ) -{ - pFile->Read( m_Verts, sizeof(m_Verts) ); -} - -void CScratchPad3D::CCommand_Line::Write( IFileSystem* pFileSystem, FileHandle_t fp ) -{ - pFileSystem->Write( m_Verts, sizeof(m_Verts), fp ); -} - - -// ------------------------------------------------------------------------ // -// CCommand_Polygon. -// ------------------------------------------------------------------------ // - -void CScratchPad3D::CCommand_Polygon::Read( CFileRead *pFile ) -{ - int count; - pFile->Read( &count, sizeof(count) ); - m_Verts.RemoveAll(); - m_Verts.AddMultipleToTail( count ); - - if( count ) - pFile->Read( &m_Verts[0], sizeof(CSPVert)*count ); -} - -void CScratchPad3D::CCommand_Polygon::Write( IFileSystem* pFileSystem, FileHandle_t fp ) -{ - int count = m_Verts.Size(); - pFileSystem->Write( &count, sizeof(count), fp ); - - if( count ) - pFileSystem->Write( &m_Verts[0], sizeof(CSPVert)*count, fp ); -} - - -// ------------------------------------------------------------------------ // -// CCommand_Matrix. -// ------------------------------------------------------------------------ // - -void CScratchPad3D::CCommand_Matrix::Read( CFileRead *pFile ) -{ - pFile->Read( &m_mMatrix, sizeof(m_mMatrix) ); -} - -void CScratchPad3D::CCommand_Matrix::Write( IFileSystem* pFileSystem, FileHandle_t fp ) -{ - pFileSystem->Write( &m_mMatrix, sizeof(m_mMatrix), fp ); -} - - -// ------------------------------------------------------------------------ // -// CCommand_RenderState. -// ------------------------------------------------------------------------ // - -void CScratchPad3D::CCommand_RenderState::Read( CFileRead *pFile ) -{ - pFile->Read( &m_State, sizeof(m_State) ); - pFile->Read( &m_Val, sizeof(m_Val) ); -} - -void CScratchPad3D::CCommand_RenderState::Write( IFileSystem* pFileSystem, FileHandle_t fp ) -{ - pFileSystem->Write( &m_State, sizeof(m_State), fp ); - pFileSystem->Write( &m_Val, sizeof(m_Val), fp ); -} - - -// ------------------------------------------------------------------------ // -// CCommand_Text. -// ------------------------------------------------------------------------ // - -void CScratchPad3D::CCommand_Text::Read( CFileRead *pFile ) -{ - int strLen; - pFile->Read( &strLen, sizeof( strLen ) ); - m_String.SetSize( strLen ); - pFile->Read( m_String.Base(), strLen ); - - pFile->Read( &m_TextParams, sizeof( m_TextParams ) ); -} - - -void CScratchPad3D::CCommand_Text::Write( IFileSystem* pFileSystem, FileHandle_t fp ) -{ - int strLen = m_String.Count(); - pFileSystem->Write( &strLen, sizeof( strLen ), fp ); - pFileSystem->Write( m_String.Base(), strLen, fp ); - - pFileSystem->Write( &m_TextParams, sizeof( m_TextParams ), fp ); -} - - -// ------------------------------------------------------------------------ // -// CScratchPad3D internals. -// ------------------------------------------------------------------------ // - -CScratchPad3D::CScratchPad3D( char const *pFilename, IFileSystem* pFileSystem, bool bAutoClear ) -{ - m_pFileSystem = pFileSystem; - m_pFilename = pFilename; - m_bAutoFlush = true; - - if( bAutoClear ) - Clear(); // Clear whatever is in the file.. -} - -void CScratchPad3D::AutoFlush() -{ - if( m_bAutoFlush ) - Flush(); -} - -void CScratchPad3D::DrawRectGeneric( int iPlane, int otherDim1, int otherDim2, float planeDist, const Vector2D &vMin, const Vector2D &vMax, const CSPColor &vColor ) -{ - Vector verts[4]; - - verts[0][iPlane] = verts[1][iPlane] = verts[2][iPlane] = verts[3][iPlane] = planeDist; - - verts[0][otherDim1] = vMin.x; - verts[0][otherDim2] = vMin.y; - - verts[1][otherDim1] = vMin.x; - verts[1][otherDim2] = vMax.y; - - verts[2][otherDim1] = vMax.x; - verts[2][otherDim2] = vMax.y; - - verts[3][otherDim1] = vMax.x; - verts[3][otherDim2] = vMin.y; - - DrawPolygon( CSPVertList(verts, 4, vColor) ); -} - -void CScratchPad3D::DeleteCommands() -{ - for( int i=0; i < m_Commands.Size(); i++ ) - delete m_Commands[i]; - - m_Commands.RemoveAll(); -} - -bool CScratchPad3D::LoadCommandsFromFile( ) -{ - DeleteCommands(); - - FileHandle_t fp = m_pFileSystem->Open( m_pFilename, "rb" ); - if( !fp ) - return false; - - long fileEndPos = m_pFileSystem->Size( fp ); - - CFileRead fileRead( m_pFileSystem, fp ); - while( fileRead.m_Pos != fileEndPos ) - { - unsigned char iCommand; - fileRead.Read( &iCommand, sizeof(iCommand) ); - - CBaseCommand *pCmd = NULL; - if( iCommand == COMMAND_POINT ) - pCmd = new CCommand_Point; - else if( iCommand == COMMAND_LINE ) - pCmd = new CCommand_Line; - else if( iCommand == COMMAND_POLYGON ) - pCmd = new CCommand_Polygon; - else if( iCommand == COMMAND_MATRIX ) - pCmd = new CCommand_Matrix; - else if( iCommand == COMMAND_RENDERSTATE ) - pCmd = new CCommand_RenderState; - else if ( iCommand == COMMAND_TEXT ) - pCmd = new CCommand_Text; - - if( !pCmd ) - { - Assert( !"LoadCommandsFromFile: invalid file" ); - m_pFileSystem->Close( fp ); - return false; - } - - pCmd->Read( &fileRead ); - m_Commands.AddToTail( pCmd ); - } - - m_pFileSystem->Close( fp ); - return true; -} - - -// ------------------------------------------------------------------------ // -// CScratchPad3D's IScratchPad3D implementation. -// ------------------------------------------------------------------------ // - -void CScratchPad3D::Release() -{ - Flush(); - delete this; -} - -void CScratchPad3D::SetMapping( - const Vector &vInputMin, - const Vector &vInputMax, - const Vector &vOutputMin, - const Vector &vOutputMax ) -{ - CCommand_Matrix *cmd = new CCommand_Matrix; - m_Commands.AddToTail( cmd ); - - Vector vDivisor(1,1,1); - for( int i=0; i < 3; i++ ) - vDivisor[i] = fabs(vInputMax[i] - vInputMin[i]) < 0.0001f ? 0.001f : (vInputMax[i] - vInputMin[i]); - - Vector vScale = (vOutputMax - vOutputMin) / vDivisor; - Vector vShift = -vInputMin * vScale + vOutputMin; - - cmd->m_mMatrix.Init( - vScale.x, 0, 0, vShift.x, - 0, vScale.y, 0, vShift.y, - 0, 0, vScale.z, vShift.z, - 0, 0, 0, 1 ); - - - AutoFlush(); -} - -bool CScratchPad3D::GetAutoFlush() -{ - return m_bAutoFlush; -} - -void CScratchPad3D::SetAutoFlush( bool bAutoFlush ) -{ - m_bAutoFlush = bAutoFlush; - if( m_bAutoFlush ) - Flush(); -} - -void CScratchPad3D::DrawPoint( CSPVert const &v, float flPointSize ) -{ - CCommand_Point *cmd = new CCommand_Point; - m_Commands.AddToTail( cmd ); - - cmd->m_Vert = v; - cmd->m_flPointSize = flPointSize; - - AutoFlush(); -} - -void CScratchPad3D::DrawLine( CSPVert const &v1, CSPVert const &v2 ) -{ - CCommand_Line *cmd = new CCommand_Line; - m_Commands.AddToTail( cmd ); - - cmd->m_Verts[0] = v1; - cmd->m_Verts[1] = v2; - - AutoFlush(); -} - -void CScratchPad3D::DrawPolygon( CSPVertList const &verts ) -{ - CCommand_Polygon *cmd = new CCommand_Polygon; - m_Commands.AddToTail( cmd ); - - cmd->m_Verts.AddVectorToTail( verts.m_Verts ); - - AutoFlush(); -} - -void CScratchPad3D::DrawRectYZ( float xPos, const Vector2D &vMin, const Vector2D &vMax, const CSPColor &vColor ) -{ - DrawRectGeneric( 0, 1, 2, xPos, vMin, vMax, vColor ); -} - -void CScratchPad3D::DrawRectXZ( float yPos, const Vector2D &vMin, const Vector2D &vMax, const CSPColor &vColor ) -{ - DrawRectGeneric( 1, 0, 2, yPos, vMin, vMax, vColor ); -} - -void CScratchPad3D::DrawRectXY( float zPos, const Vector2D &vMin, const Vector2D &vMax, const CSPColor &vColor ) -{ - DrawRectGeneric( 2, 0, 1, zPos, vMin, vMax, vColor ); -} - -void CScratchPad3D::SetRenderState( RenderState state, unsigned long val ) -{ - CCommand_RenderState *cmd = new CCommand_RenderState; - m_Commands.AddToTail( cmd ); - - cmd->m_State = (unsigned long)state; - cmd->m_Val = val; -} - -void CScratchPad3D::DrawWireframeBox( const Vector &vMin, const Vector &vMax, const Vector &vColor ) -{ - // Bottom 4. - DrawLine( - CSPVert(Vector(vMin.x, vMin.y, vMin.z), vColor), - CSPVert(Vector(vMax.x, vMin.y, vMin.z), vColor) ); - - DrawLine( - CSPVert(Vector(vMin.x, vMin.y, vMin.z), vColor), - CSPVert(Vector(vMin.x, vMax.y, vMin.z), vColor) ); - - DrawLine( - CSPVert(Vector(vMax.x, vMin.y, vMin.z), vColor), - CSPVert(Vector(vMax.x, vMax.y, vMin.z), vColor) ); - - DrawLine( - CSPVert(Vector(vMax.x, vMax.y, vMin.z), vColor), - CSPVert(Vector(vMin.x, vMax.y, vMin.z), vColor) ); - - // Top 4. - DrawLine( - CSPVert(Vector(vMin.x, vMin.y, vMax.z), vColor), - CSPVert(Vector(vMax.x, vMin.y, vMax.z), vColor) ); - - DrawLine( - CSPVert(Vector(vMin.x, vMin.y, vMax.z), vColor), - CSPVert(Vector(vMin.x, vMax.y, vMax.z), vColor) ); - - DrawLine( - CSPVert(Vector(vMax.x, vMin.y, vMax.z), vColor), - CSPVert(Vector(vMax.x, vMax.y, vMax.z), vColor) ); - - DrawLine( - CSPVert(Vector(vMax.x, vMax.y, vMax.z), vColor), - CSPVert(Vector(vMin.x, vMax.y, vMax.z), vColor) ); - - // Connecting 4. - DrawLine( - CSPVert(Vector(vMin.x, vMin.y, vMin.z), vColor), - CSPVert(Vector(vMin.x, vMin.y, vMax.z), vColor) ); - - DrawLine( - CSPVert(Vector(vMin.x, vMax.y, vMin.z), vColor), - CSPVert(Vector(vMin.x, vMax.y, vMax.z), vColor) ); - - DrawLine( - CSPVert(Vector(vMax.x, vMax.y, vMin.z), vColor), - CSPVert(Vector(vMax.x, vMax.y, vMax.z), vColor) ); - - DrawLine( - CSPVert(Vector(vMax.x, vMin.y, vMin.z), vColor), - CSPVert(Vector(vMax.x, vMin.y, vMax.z), vColor) ); -} - - -void CScratchPad3D::DrawText( const char *pStr, const CTextParams ¶ms ) -{ - CCommand_Text *cmd = new CCommand_Text; - m_Commands.AddToTail( cmd ); - - cmd->m_String.CopyArray( pStr, strlen( pStr ) + 1 ); - cmd->m_TextParams = params; - - AutoFlush(); -} - - -void CScratchPad3D::Clear() -{ - FileHandle_t fp; - - while( ( fp = m_pFileSystem->Open(m_pFilename, "wb") ) == NULL ) - { -#ifdef _WIN32 - Sleep( 5 ); -#elif POSIX - usleep( 5 ); -#endif - } - - m_pFileSystem->Close( fp ); - - DeleteCommands(); -} - - -void CScratchPad3D::Flush() -{ - FileHandle_t fp; - - while( ( fp = m_pFileSystem->Open(m_pFilename, "ab+") ) == NULL ) - { -#ifdef _WIN32 - Sleep( 5 ); -#elif POSIX - usleep( 5 ); -#endif - } - - // Append the new commands to the file. - for( int i=0; i < m_Commands.Size(); i++ ) - { - m_pFileSystem->Write( &m_Commands[i]->m_iCommand, sizeof(m_Commands[i]->m_iCommand), fp ); - m_Commands[i]->Write( m_pFileSystem, fp ); - } - - m_pFileSystem->Close( fp ); - - DeleteCommands(); -} - -void CScratchPad3D::DrawImageBW( - unsigned char const *pData, - int width, - int height, - int pitchInBytes, - bool bOutlinePixels, - bool bOutlineImage, - Vector *vCorners ) -{ - SPRGBA *pRGBA = new SPRGBA[width*height]; - for( int y=0; y < height; y++ ) - { - SPRGBA *pDest = &pRGBA[ y * width ]; - unsigned char const *pSrc = &pData[ y * pitchInBytes ]; - for( int x=0; x < width; x++ ) - { - pDest->r = pDest->g = pDest->b = *pSrc; - ++pSrc; - ++pDest; - } - } - - DrawImageRGBA( pRGBA, width, height, width*sizeof(SPRGBA), bOutlinePixels, bOutlineImage, vCorners ); - delete [] pRGBA; -} - - -void CScratchPad3D::DrawPolygonsForPixels( - SPRGBA *pData, - int width, - int height, - int pitchInBytes, - Vector *vCorners ) -{ - // Scan top-down. - Vector vCurLeft = vCorners[1]; - Vector vCurRight = vCorners[2]; - - Vector vLeftInc = (vCorners[0] - vCorners[1]) / height; - Vector vRightInc = (vCorners[3] - vCorners[2]) / height; - - Vector vNextLeft = vCurLeft + vLeftInc; - Vector vNextRight = vCurRight + vRightInc; - - Vector vPolyBox[4]; - Vector &vTopLeft = vPolyBox[0]; - Vector &vTopRight = vPolyBox[1]; - Vector &vBottomRight = vPolyBox[2]; - Vector &vBottomLeft = vPolyBox[3]; - - for( int y=0; y < height; y++ ) - { - vTopLeft = vCurLeft; - vBottomLeft = vNextLeft; - - Vector vTopXInc = (vCurRight - vCurLeft) / width; - Vector vBottomXInc = (vNextRight - vNextLeft) / width; - - vTopRight = vTopLeft + vTopXInc; - vBottomRight = vBottomLeft + vBottomXInc; - - SPRGBA *pSrc = &pData[ y * (pitchInBytes/sizeof(SPRGBA)) ]; - for( int x=0; x < width; x++ ) - { - if ( pData ) - DrawPolygon( CSPVertList( vPolyBox, 4, Vector(pSrc->r/255.1f, pSrc->g/255.1f, pSrc->b/255.1f) ) ); - else - DrawPolygon( CSPVertList( vPolyBox, 4, Vector(1,1,1) ) ); - - ++pSrc; - vTopLeft += vTopXInc; - vTopRight += vTopXInc; - vBottomLeft += vBottomXInc; - vBottomRight += vBottomXInc; - } - - vCurLeft += vLeftInc; - vNextLeft += vLeftInc; - vCurRight += vRightInc; - vNextRight += vRightInc; - } -} - - -void CScratchPad3D::DrawImageRGBA( - SPRGBA *pData, - int width, - int height, - int pitchInBytes, - bool bOutlinePixels, - bool bOutlineImage, - Vector *vCorners ) -{ - Assert( pitchInBytes % sizeof(SPRGBA) == 0 ); - - Vector vDefaultCorners[4]; - if ( !vCorners ) - { - vCorners = vDefaultCorners; - vDefaultCorners[0].Init( -100, -100 ); - vDefaultCorners[1].Init( -100, 100 ); - vDefaultCorners[2].Init( 100, 100 ); - vDefaultCorners[3].Init( 100, -100 ); - } - - // Don't auto-flush while drawing all these primitives. - bool bOldAutoFlush = m_bAutoFlush; - m_bAutoFlush = false; - - // Draw solids. - SetRenderState( IScratchPad3D::RS_FillMode, IScratchPad3D::FillMode_Solid ); - DrawPolygonsForPixels( pData, width, height, pitchInBytes, vCorners ); - - // Draw wireframe. - if ( bOutlinePixels ) - { - SetRenderState( IScratchPad3D::RS_FillMode, IScratchPad3D::FillMode_Wireframe ); - DrawPolygonsForPixels( NULL, width, height, pitchInBytes, vCorners ); - } - - // Draw an outline around the whole image. - if ( bOutlineImage ) - { - SetRenderState( IScratchPad3D::RS_FillMode, IScratchPad3D::FillMode_Wireframe ); - DrawPolygon( CSPVertList( vCorners, 4 ) ); - } - - // Restore the old auto-flush state. - m_bAutoFlush = bOldAutoFlush; - AutoFlush(); -} - - -// ------------------------------------------------------------------------ // -// Global functions. -// ------------------------------------------------------------------------ // -IFileSystem* ScratchPad3D_SetupFileSystem() -{ - // Get a filesystem interface. - CSysModule *pModule = Sys_LoadModule( "filesystem_stdio" ); - if( !pModule ) - return NULL; - - CreateInterfaceFn fn = Sys_GetFactory( pModule ); - IFileSystem *pFileSystem; - if( !fn || (pFileSystem = (IFileSystem *)fn( FILESYSTEM_INTERFACE_VERSION, NULL )) == NULL ) - { - Sys_UnloadModule( pModule ); - return NULL; - } - - return pFileSystem; -} - -IScratchPad3D* ScratchPad3D_Create( char const *pFilename ) -{ - IFileSystem *pFileSystem = ScratchPad3D_SetupFileSystem(); - if( !pFileSystem ) - return NULL; - - CScratchPad3D *pRet = new CScratchPad3D( pFilename, pFileSystem, true ); - return pRet; -} -#endif // POSIX - +//========= Copyright Valve Corporation, All rights reserved. ============// +// +// Purpose: +// +// $NoKeywords: $ +//=============================================================================// + +#include +#include "scratchpad3d.h" +#include "tier0/dbg.h" + +// memdbgon must be the last include file in a .cpp file!!! +#include "tier0/memdbgon.h" + +#ifndef POSIX +// NOTE - linux doesn't need any of this code! + +extern "C" +{ + extern void __stdcall Sleep( unsigned long ms ); +}; + + +class CFileRead +{ +public: + CFileRead( IFileSystem* pFileSystem, FileHandle_t fp ) + { + m_pFileSystem = pFileSystem; + m_fp = fp; + m_Pos = 0; + } + + bool Read( void *pDest, int len ) + { + int count = m_pFileSystem->Read( pDest, len, m_fp ); + m_Pos += count; + return count == len; + } + + IFileSystem* m_pFileSystem; + FileHandle_t m_fp; + int m_Pos; +}; + + +// ------------------------------------------------------------------------ // +// CCommand_Point. +// ------------------------------------------------------------------------ // + +void CScratchPad3D::CCommand_Point::Read( CFileRead *pFile ) +{ + pFile->Read( &m_flPointSize, sizeof(m_flPointSize) ); + pFile->Read( &m_Vert, sizeof(m_Vert) ); +} + +void CScratchPad3D::CCommand_Point::Write( IFileSystem* pFileSystem, FileHandle_t fp ) +{ + pFileSystem->Write( &m_flPointSize, sizeof(m_flPointSize), fp ); + pFileSystem->Write( &m_Vert, sizeof(m_Vert), fp ); +} + + +// ------------------------------------------------------------------------ // +// CCommand_Line. +// ------------------------------------------------------------------------ // + +void CScratchPad3D::CCommand_Line::Read( CFileRead *pFile ) +{ + pFile->Read( m_Verts, sizeof(m_Verts) ); +} + +void CScratchPad3D::CCommand_Line::Write( IFileSystem* pFileSystem, FileHandle_t fp ) +{ + pFileSystem->Write( m_Verts, sizeof(m_Verts), fp ); +} + + +// ------------------------------------------------------------------------ // +// CCommand_Polygon. +// ------------------------------------------------------------------------ // + +void CScratchPad3D::CCommand_Polygon::Read( CFileRead *pFile ) +{ + int count; + pFile->Read( &count, sizeof(count) ); + m_Verts.RemoveAll(); + m_Verts.AddMultipleToTail( count ); + + if( count ) + pFile->Read( &m_Verts[0], sizeof(CSPVert)*count ); +} + +void CScratchPad3D::CCommand_Polygon::Write( IFileSystem* pFileSystem, FileHandle_t fp ) +{ + int count = m_Verts.Size(); + pFileSystem->Write( &count, sizeof(count), fp ); + + if( count ) + pFileSystem->Write( &m_Verts[0], sizeof(CSPVert)*count, fp ); +} + + +// ------------------------------------------------------------------------ // +// CCommand_Matrix. +// ------------------------------------------------------------------------ // + +void CScratchPad3D::CCommand_Matrix::Read( CFileRead *pFile ) +{ + pFile->Read( &m_mMatrix, sizeof(m_mMatrix) ); +} + +void CScratchPad3D::CCommand_Matrix::Write( IFileSystem* pFileSystem, FileHandle_t fp ) +{ + pFileSystem->Write( &m_mMatrix, sizeof(m_mMatrix), fp ); +} + + +// ------------------------------------------------------------------------ // +// CCommand_RenderState. +// ------------------------------------------------------------------------ // + +void CScratchPad3D::CCommand_RenderState::Read( CFileRead *pFile ) +{ + pFile->Read( &m_State, sizeof(m_State) ); + pFile->Read( &m_Val, sizeof(m_Val) ); +} + +void CScratchPad3D::CCommand_RenderState::Write( IFileSystem* pFileSystem, FileHandle_t fp ) +{ + pFileSystem->Write( &m_State, sizeof(m_State), fp ); + pFileSystem->Write( &m_Val, sizeof(m_Val), fp ); +} + + +// ------------------------------------------------------------------------ // +// CCommand_Text. +// ------------------------------------------------------------------------ // + +void CScratchPad3D::CCommand_Text::Read( CFileRead *pFile ) +{ + int strLen; + pFile->Read( &strLen, sizeof( strLen ) ); + m_String.SetSize( strLen ); + pFile->Read( m_String.Base(), strLen ); + + pFile->Read( &m_TextParams, sizeof( m_TextParams ) ); +} + + +void CScratchPad3D::CCommand_Text::Write( IFileSystem* pFileSystem, FileHandle_t fp ) +{ + int strLen = m_String.Count(); + pFileSystem->Write( &strLen, sizeof( strLen ), fp ); + pFileSystem->Write( m_String.Base(), strLen, fp ); + + pFileSystem->Write( &m_TextParams, sizeof( m_TextParams ), fp ); +} + + +// ------------------------------------------------------------------------ // +// CScratchPad3D internals. +// ------------------------------------------------------------------------ // + +CScratchPad3D::CScratchPad3D( char const *pFilename, IFileSystem* pFileSystem, bool bAutoClear ) +{ + m_pFileSystem = pFileSystem; + m_pFilename = pFilename; + m_bAutoFlush = true; + + if( bAutoClear ) + Clear(); // Clear whatever is in the file.. +} + +void CScratchPad3D::AutoFlush() +{ + if( m_bAutoFlush ) + Flush(); +} + +void CScratchPad3D::DrawRectGeneric( int iPlane, int otherDim1, int otherDim2, float planeDist, const Vector2D &vMin, const Vector2D &vMax, const CSPColor &vColor ) +{ + Vector verts[4]; + + verts[0][iPlane] = verts[1][iPlane] = verts[2][iPlane] = verts[3][iPlane] = planeDist; + + verts[0][otherDim1] = vMin.x; + verts[0][otherDim2] = vMin.y; + + verts[1][otherDim1] = vMin.x; + verts[1][otherDim2] = vMax.y; + + verts[2][otherDim1] = vMax.x; + verts[2][otherDim2] = vMax.y; + + verts[3][otherDim1] = vMax.x; + verts[3][otherDim2] = vMin.y; + + DrawPolygon( CSPVertList(verts, 4, vColor) ); +} + +void CScratchPad3D::DeleteCommands() +{ + for( int i=0; i < m_Commands.Size(); i++ ) + delete m_Commands[i]; + + m_Commands.RemoveAll(); +} + +bool CScratchPad3D::LoadCommandsFromFile( ) +{ + DeleteCommands(); + + FileHandle_t fp = m_pFileSystem->Open( m_pFilename, "rb" ); + if( !fp ) + return false; + + long fileEndPos = m_pFileSystem->Size( fp ); + + CFileRead fileRead( m_pFileSystem, fp ); + while( fileRead.m_Pos != fileEndPos ) + { + unsigned char iCommand; + fileRead.Read( &iCommand, sizeof(iCommand) ); + + CBaseCommand *pCmd = NULL; + if( iCommand == COMMAND_POINT ) + pCmd = new CCommand_Point; + else if( iCommand == COMMAND_LINE ) + pCmd = new CCommand_Line; + else if( iCommand == COMMAND_POLYGON ) + pCmd = new CCommand_Polygon; + else if( iCommand == COMMAND_MATRIX ) + pCmd = new CCommand_Matrix; + else if( iCommand == COMMAND_RENDERSTATE ) + pCmd = new CCommand_RenderState; + else if ( iCommand == COMMAND_TEXT ) + pCmd = new CCommand_Text; + + if( !pCmd ) + { + Assert( !"LoadCommandsFromFile: invalid file" ); + m_pFileSystem->Close( fp ); + return false; + } + + pCmd->Read( &fileRead ); + m_Commands.AddToTail( pCmd ); + } + + m_pFileSystem->Close( fp ); + return true; +} + + +// ------------------------------------------------------------------------ // +// CScratchPad3D's IScratchPad3D implementation. +// ------------------------------------------------------------------------ // + +void CScratchPad3D::Release() +{ + Flush(); + delete this; +} + +void CScratchPad3D::SetMapping( + const Vector &vInputMin, + const Vector &vInputMax, + const Vector &vOutputMin, + const Vector &vOutputMax ) +{ + CCommand_Matrix *cmd = new CCommand_Matrix; + m_Commands.AddToTail( cmd ); + + Vector vDivisor(1,1,1); + for( int i=0; i < 3; i++ ) + vDivisor[i] = fabs(vInputMax[i] - vInputMin[i]) < 0.0001f ? 0.001f : (vInputMax[i] - vInputMin[i]); + + Vector vScale = (vOutputMax - vOutputMin) / vDivisor; + Vector vShift = -vInputMin * vScale + vOutputMin; + + cmd->m_mMatrix.Init( + vScale.x, 0, 0, vShift.x, + 0, vScale.y, 0, vShift.y, + 0, 0, vScale.z, vShift.z, + 0, 0, 0, 1 ); + + + AutoFlush(); +} + +bool CScratchPad3D::GetAutoFlush() +{ + return m_bAutoFlush; +} + +void CScratchPad3D::SetAutoFlush( bool bAutoFlush ) +{ + m_bAutoFlush = bAutoFlush; + if( m_bAutoFlush ) + Flush(); +} + +void CScratchPad3D::DrawPoint( CSPVert const &v, float flPointSize ) +{ + CCommand_Point *cmd = new CCommand_Point; + m_Commands.AddToTail( cmd ); + + cmd->m_Vert = v; + cmd->m_flPointSize = flPointSize; + + AutoFlush(); +} + +void CScratchPad3D::DrawLine( CSPVert const &v1, CSPVert const &v2 ) +{ + CCommand_Line *cmd = new CCommand_Line; + m_Commands.AddToTail( cmd ); + + cmd->m_Verts[0] = v1; + cmd->m_Verts[1] = v2; + + AutoFlush(); +} + +void CScratchPad3D::DrawPolygon( CSPVertList const &verts ) +{ + CCommand_Polygon *cmd = new CCommand_Polygon; + m_Commands.AddToTail( cmd ); + + cmd->m_Verts.AddVectorToTail( verts.m_Verts ); + + AutoFlush(); +} + +void CScratchPad3D::DrawRectYZ( float xPos, const Vector2D &vMin, const Vector2D &vMax, const CSPColor &vColor ) +{ + DrawRectGeneric( 0, 1, 2, xPos, vMin, vMax, vColor ); +} + +void CScratchPad3D::DrawRectXZ( float yPos, const Vector2D &vMin, const Vector2D &vMax, const CSPColor &vColor ) +{ + DrawRectGeneric( 1, 0, 2, yPos, vMin, vMax, vColor ); +} + +void CScratchPad3D::DrawRectXY( float zPos, const Vector2D &vMin, const Vector2D &vMax, const CSPColor &vColor ) +{ + DrawRectGeneric( 2, 0, 1, zPos, vMin, vMax, vColor ); +} + +void CScratchPad3D::SetRenderState( RenderState state, unsigned long val ) +{ + CCommand_RenderState *cmd = new CCommand_RenderState; + m_Commands.AddToTail( cmd ); + + cmd->m_State = (unsigned long)state; + cmd->m_Val = val; +} + +void CScratchPad3D::DrawWireframeBox( const Vector &vMin, const Vector &vMax, const Vector &vColor ) +{ + // Bottom 4. + DrawLine( + CSPVert(Vector(vMin.x, vMin.y, vMin.z), vColor), + CSPVert(Vector(vMax.x, vMin.y, vMin.z), vColor) ); + + DrawLine( + CSPVert(Vector(vMin.x, vMin.y, vMin.z), vColor), + CSPVert(Vector(vMin.x, vMax.y, vMin.z), vColor) ); + + DrawLine( + CSPVert(Vector(vMax.x, vMin.y, vMin.z), vColor), + CSPVert(Vector(vMax.x, vMax.y, vMin.z), vColor) ); + + DrawLine( + CSPVert(Vector(vMax.x, vMax.y, vMin.z), vColor), + CSPVert(Vector(vMin.x, vMax.y, vMin.z), vColor) ); + + // Top 4. + DrawLine( + CSPVert(Vector(vMin.x, vMin.y, vMax.z), vColor), + CSPVert(Vector(vMax.x, vMin.y, vMax.z), vColor) ); + + DrawLine( + CSPVert(Vector(vMin.x, vMin.y, vMax.z), vColor), + CSPVert(Vector(vMin.x, vMax.y, vMax.z), vColor) ); + + DrawLine( + CSPVert(Vector(vMax.x, vMin.y, vMax.z), vColor), + CSPVert(Vector(vMax.x, vMax.y, vMax.z), vColor) ); + + DrawLine( + CSPVert(Vector(vMax.x, vMax.y, vMax.z), vColor), + CSPVert(Vector(vMin.x, vMax.y, vMax.z), vColor) ); + + // Connecting 4. + DrawLine( + CSPVert(Vector(vMin.x, vMin.y, vMin.z), vColor), + CSPVert(Vector(vMin.x, vMin.y, vMax.z), vColor) ); + + DrawLine( + CSPVert(Vector(vMin.x, vMax.y, vMin.z), vColor), + CSPVert(Vector(vMin.x, vMax.y, vMax.z), vColor) ); + + DrawLine( + CSPVert(Vector(vMax.x, vMax.y, vMin.z), vColor), + CSPVert(Vector(vMax.x, vMax.y, vMax.z), vColor) ); + + DrawLine( + CSPVert(Vector(vMax.x, vMin.y, vMin.z), vColor), + CSPVert(Vector(vMax.x, vMin.y, vMax.z), vColor) ); +} + + +void CScratchPad3D::DrawText( const char *pStr, const CTextParams ¶ms ) +{ + CCommand_Text *cmd = new CCommand_Text; + m_Commands.AddToTail( cmd ); + + cmd->m_String.CopyArray( pStr, strlen( pStr ) + 1 ); + cmd->m_TextParams = params; + + AutoFlush(); +} + + +void CScratchPad3D::Clear() +{ + FileHandle_t fp; + + while( ( fp = m_pFileSystem->Open(m_pFilename, "wb") ) == NULL ) + { +#ifdef _WIN32 + Sleep( 5 ); +#elif POSIX + usleep( 5 ); +#endif + } + + m_pFileSystem->Close( fp ); + + DeleteCommands(); +} + + +void CScratchPad3D::Flush() +{ + FileHandle_t fp; + + while( ( fp = m_pFileSystem->Open(m_pFilename, "ab+") ) == NULL ) + { +#ifdef _WIN32 + Sleep( 5 ); +#elif POSIX + usleep( 5 ); +#endif + } + + // Append the new commands to the file. + for( int i=0; i < m_Commands.Size(); i++ ) + { + m_pFileSystem->Write( &m_Commands[i]->m_iCommand, sizeof(m_Commands[i]->m_iCommand), fp ); + m_Commands[i]->Write( m_pFileSystem, fp ); + } + + m_pFileSystem->Close( fp ); + + DeleteCommands(); +} + +void CScratchPad3D::DrawImageBW( + unsigned char const *pData, + int width, + int height, + int pitchInBytes, + bool bOutlinePixels, + bool bOutlineImage, + Vector *vCorners ) +{ + SPRGBA *pRGBA = new SPRGBA[width*height]; + for( int y=0; y < height; y++ ) + { + SPRGBA *pDest = &pRGBA[ y * width ]; + unsigned char const *pSrc = &pData[ y * pitchInBytes ]; + for( int x=0; x < width; x++ ) + { + pDest->r = pDest->g = pDest->b = *pSrc; + ++pSrc; + ++pDest; + } + } + + DrawImageRGBA( pRGBA, width, height, width*sizeof(SPRGBA), bOutlinePixels, bOutlineImage, vCorners ); + delete [] pRGBA; +} + + +void CScratchPad3D::DrawPolygonsForPixels( + SPRGBA *pData, + int width, + int height, + int pitchInBytes, + Vector *vCorners ) +{ + // Scan top-down. + Vector vCurLeft = vCorners[1]; + Vector vCurRight = vCorners[2]; + + Vector vLeftInc = (vCorners[0] - vCorners[1]) / height; + Vector vRightInc = (vCorners[3] - vCorners[2]) / height; + + Vector vNextLeft = vCurLeft + vLeftInc; + Vector vNextRight = vCurRight + vRightInc; + + Vector vPolyBox[4]; + Vector &vTopLeft = vPolyBox[0]; + Vector &vTopRight = vPolyBox[1]; + Vector &vBottomRight = vPolyBox[2]; + Vector &vBottomLeft = vPolyBox[3]; + + for( int y=0; y < height; y++ ) + { + vTopLeft = vCurLeft; + vBottomLeft = vNextLeft; + + Vector vTopXInc = (vCurRight - vCurLeft) / width; + Vector vBottomXInc = (vNextRight - vNextLeft) / width; + + vTopRight = vTopLeft + vTopXInc; + vBottomRight = vBottomLeft + vBottomXInc; + + SPRGBA *pSrc = &pData[ y * (pitchInBytes/sizeof(SPRGBA)) ]; + for( int x=0; x < width; x++ ) + { + if ( pData ) + DrawPolygon( CSPVertList( vPolyBox, 4, Vector(pSrc->r/255.1f, pSrc->g/255.1f, pSrc->b/255.1f) ) ); + else + DrawPolygon( CSPVertList( vPolyBox, 4, Vector(1,1,1) ) ); + + ++pSrc; + vTopLeft += vTopXInc; + vTopRight += vTopXInc; + vBottomLeft += vBottomXInc; + vBottomRight += vBottomXInc; + } + + vCurLeft += vLeftInc; + vNextLeft += vLeftInc; + vCurRight += vRightInc; + vNextRight += vRightInc; + } +} + + +void CScratchPad3D::DrawImageRGBA( + SPRGBA *pData, + int width, + int height, + int pitchInBytes, + bool bOutlinePixels, + bool bOutlineImage, + Vector *vCorners ) +{ + Assert( pitchInBytes % sizeof(SPRGBA) == 0 ); + + Vector vDefaultCorners[4]; + if ( !vCorners ) + { + vCorners = vDefaultCorners; + vDefaultCorners[0].Init( -100, -100 ); + vDefaultCorners[1].Init( -100, 100 ); + vDefaultCorners[2].Init( 100, 100 ); + vDefaultCorners[3].Init( 100, -100 ); + } + + // Don't auto-flush while drawing all these primitives. + bool bOldAutoFlush = m_bAutoFlush; + m_bAutoFlush = false; + + // Draw solids. + SetRenderState( IScratchPad3D::RS_FillMode, IScratchPad3D::FillMode_Solid ); + DrawPolygonsForPixels( pData, width, height, pitchInBytes, vCorners ); + + // Draw wireframe. + if ( bOutlinePixels ) + { + SetRenderState( IScratchPad3D::RS_FillMode, IScratchPad3D::FillMode_Wireframe ); + DrawPolygonsForPixels( NULL, width, height, pitchInBytes, vCorners ); + } + + // Draw an outline around the whole image. + if ( bOutlineImage ) + { + SetRenderState( IScratchPad3D::RS_FillMode, IScratchPad3D::FillMode_Wireframe ); + DrawPolygon( CSPVertList( vCorners, 4 ) ); + } + + // Restore the old auto-flush state. + m_bAutoFlush = bOldAutoFlush; + AutoFlush(); +} + + +// ------------------------------------------------------------------------ // +// Global functions. +// ------------------------------------------------------------------------ // +IFileSystem* ScratchPad3D_SetupFileSystem() +{ + // Get a filesystem interface. + CSysModule *pModule = Sys_LoadModule( "filesystem_stdio" ); + if( !pModule ) + return NULL; + + CreateInterfaceFn fn = Sys_GetFactory( pModule ); + IFileSystem *pFileSystem; + if( !fn || (pFileSystem = (IFileSystem *)fn( FILESYSTEM_INTERFACE_VERSION, NULL )) == NULL ) + { + Sys_UnloadModule( pModule ); + return NULL; + } + + return pFileSystem; +} + +IScratchPad3D* ScratchPad3D_Create( char const *pFilename ) +{ + IFileSystem *pFileSystem = ScratchPad3D_SetupFileSystem(); + if( !pFileSystem ) + return NULL; + + CScratchPad3D *pRet = new CScratchPad3D( pFilename, pFileSystem, true ); + return pRet; +} +#endif // POSIX + -- cgit v1.2.3