diff options
| author | Jørgen P. Tjernø <[email protected]> | 2013-12-02 19:31:46 -0800 |
|---|---|---|
| committer | Jørgen P. Tjernø <[email protected]> | 2013-12-02 19:46:31 -0800 |
| commit | f56bb35301836e56582a575a75864392a0177875 (patch) | |
| tree | de61ddd39de3e7df52759711950b4c288592f0dc /mp/src/public/scratchpad3d.cpp | |
| parent | Mark some more files as text. (diff) | |
| download | source-sdk-2013-f56bb35301836e56582a575a75864392a0177875.tar.xz source-sdk-2013-f56bb35301836e56582a575a75864392a0177875.zip | |
Fix line endings. WHAMMY.
Diffstat (limited to 'mp/src/public/scratchpad3d.cpp')
| -rw-r--r-- | mp/src/public/scratchpad3d.cpp | 1270 |
1 files changed, 635 insertions, 635 deletions
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 <stdio.h>
-#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 <stdio.h> +#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 + |