//============================================================================== // Copyright (C) 2002 Radical Entertainment Ltd. All rights reserved. // // File: debuginfo.cpp // // Description: In-game visual debug output // // History: 2002/07/02 + Migrated from Mirth -- Darwin Chau // //============================================================================== //======================================== // System Includes //======================================== #include // FTech #include #include // Pure3D #include #include #include #include #include #include //======================================== // Project Includes //======================================== #include #include #include #ifdef DEBUGINFO_ENABLED //****************************************************************************** // // Global Data, Local Data, Local Classes // //****************************************************************************** //The Adlib font. static unsigned char gFont[] = #include // Static pointer to instance of singleton. DebugInfo* DebugInfo::_Instance = NULL; static void Next() { DebugInfo::GetInstance()->OnNext(); } static void Switch() { DebugInfo::GetInstance()->OnSwitch(); } //****************************************************************************** // // Public Member Functions // //****************************************************************************** //============================================================================== // DebugInfo::DebugInfo //============================================================================== // // Description: // // Parameters: // // Return: // //============================================================================== DebugInfo::DebugInfo() : _pDebugFont(NULL), _pTypeFace(NULL), _NumSection(0), _StackSize(0), _CurrentSection(0), _DebugMenuTime(0.0f), _isRenderEnabled(false), _isCreationSectionOpen(false), _mode(OFF), _shader(NULL) { for(int i=0; iRelease (); } if(_shader) _shader->Release(); int i; for(i=0; iPushHeap( GMA_DEBUG ); _Instance = new DebugInfo; HeapMgr()->PopHeap ( GMA_DEBUG ); MEMTRACK_POP_GROUP( "DebugInfo" ); } //============================================================================== // DebugInfo::CreateNewSection //============================================================================== // // Description: Creates a new section // // Parameters: // // Return: // //============================================================================== void DebugInfo::CreateNewSection( const char* section ) { HeapMgr()->PushHeap( GMA_DEBUG ); //Lazy section allocation if(_ppSections[_NumSection]) { _ppSections[_NumSection]->Reset( section ); } else { if( _pDebugFont == NULL ) { // // find the font // _pDebugFont = p3d::find("adlibn_20"); if( _pDebugFont == NULL ) { // Convert memory buffer into a texturefont. // p3d::load(gFont, DEFAULTFONT_SIZE, GMA_DEBUG); _pDebugFont = p3d::find("adlibn_20"); rAssertMsg(_pDebugFont, ("ERROR - debug font not found.")); } _pDebugFont->AddRef(); } _ppSections[_NumSection] = new Section( _pDebugFont, section ); } //_pStack[_StackSize++] = _NumSection; _NumSection++; HeapMgr()->PopHeap( GMA_DEBUG ); } //============================================================================== // DebugInfo::DestroyInstance //============================================================================== // // Description: // // Parameters: // // Return: // //============================================================================== void DebugInfo::DestroyInstance() { delete(GMA_DEBUG, _Instance); } //============================================================================== // DebugInfo::GetInstance //============================================================================== // // Description: // // Parameters: // // Return: // //============================================================================== DebugInfo* DebugInfo::GetInstance() { if(!_Instance) { CreateInstance(); } return _Instance; } //============================================================================== // DebugInfo::InitializeStaticVariables //============================================================================== // // Description: Initializes all the sections that we're ever going to use // // Parameters: none // // Return: none // //============================================================================== void DebugInfo::InitializeStaticVariables() { GetInstance()->CreateNewSection( "Vehicle Terrain Type" ); GetInstance()->CreateNewSection( "Vehicle Shit" ); } //============================================================================== // DebugInfo::OnSwitch //============================================================================== // // Description: // // Parameters: // // Return: // //============================================================================== void DebugInfo::OnSwitch() { _mode = (Mode) ((_mode + 1) % MODE_MAX); if(_mode == OFF) { _isRenderEnabled = false; _isBackgroundEnabled = false; } else if(_mode == BACKGROUND) { _isRenderEnabled = true; _isBackgroundEnabled = true; } else if(_mode == NOBACKGROUND) { _isRenderEnabled = true; _isBackgroundEnabled = false; } } //============================================================================== // DebugInfo::Push //============================================================================== // // Description: // // Parameters: // // Return: // //============================================================================== bool DebugInfo::Push(char* szSection) { MEMTRACK_PUSH_GROUP( "DebugInfo" ); HeapMgr()->PushHeap (GMA_DEBUG); rAssert(szSection); rAssert(_StackSizeGetName(); if(0==strcmp(szSection,szName)) { _pStack[_StackSize++] = i; bFound = true; break; } } //Create a new section if(!bFound) { CreateNewSection( szSection ); } MEMTRACK_POP_GROUP( "DebugInfo" ); HeapMgr()->PopHeap (GMA_DEBUG); //Return true if this is the current section return (bFound && i==_CurrentSection); } //============================================================================== // DebugInfo::GetCurrentSection //============================================================================== // // Description: // // Parameters: // // Return: // //============================================================================== const char* DebugInfo::GetCurrentSection() { Section *pSect = _ppSections[_CurrentSection]; if (pSect && _isRenderEnabled) return (pSect->GetName()); else return (NULL); } //============================================================================== // DebugInfo::Pop //============================================================================== // // Description: // // Parameters: // // Return: // //============================================================================== void DebugInfo::Pop() { rAssert( _NumSection > 0 ); rAssert( _StackSize >= 0 ); --_StackSize; } //============================================================================== // int SignedMod //============================================================================== // // Description: // // Parameters: // // Return: // //============================================================================== int SignedMod(int a, int b) { rAssert(b>0); if (a>=0) return (a%b); else return (b - ((-a)%b)); } //============================================================================== // DebugInfo::Toggle //============================================================================== // // Description: // // Parameters: // // Return: // //============================================================================== void DebugInfo::Toggle(int step) { _CurrentSection = SignedMod(_CurrentSection+step, _NumSection); _DebugMenuTime = 1.0f; } //============================================================================== // DebugInfo::SetAutoReset //============================================================================== // // Description: // // Parameters: // // Return: // //============================================================================== void DebugInfo::SetAutoReset(bool autoreset) { rAssert(_NumSection>0); rAssert(_StackSize>0); _ppSections[_pStack[_StackSize-1]]->SetAutoReset(autoreset); } //============================================================================== // DebugInfo::Reset //============================================================================== // // Description: // // Parameters: // // Return: // //============================================================================== void DebugInfo::Reset(char* sectionName) { rAssert(_NumSection>0); rAssert(_StackSize>0); _ppSections[_pStack[_StackSize-1]]->Reset(sectionName); } //============================================================================== // DebugInfo::AddLine //============================================================================== // // Description: // // Parameters: // // Return: // //============================================================================== void DebugInfo::AddLine(const rmt::Vector& a, const rmt::Vector& b, tColour colour) { rAssert(_NumSection>0); rAssert(_StackSize>0); _ppSections[_pStack[_StackSize-1]]->AddLine(a, b, colour); } //============================================================================== // DebugInfo::AddHVector //============================================================================== // // Description: // // Parameters: // // Return: // //============================================================================== void DebugInfo::AddHVector(rmt::Vector o, rmt::Vector v, float h, tColour colour) { // Add the origin to the vector v.Add(o); // Add the elevation v.Add(rmt::Vector(0, h, 0)); o.Add(rmt::Vector(0, h, 0)); // Then, its a regular line AddLine(o, v, colour); } //============================================================================== // DebugInfo::AddStar //============================================================================== // // Description: // // Parameters: // // Return: // //============================================================================== void DebugInfo::AddStar(const rmt::Vector& vx, tColour colour, float scale) { rAssert(_NumSection>0); rAssert(_StackSize>0); //Draw a kind of star rmt::Vector a, b; a = b = vx; a.x += scale; b.x -= scale; AddLine( a, b, colour ); a = b = vx; a.y += scale; b.y -= scale; AddLine( a, b, colour ); a = b = vx; a.z += scale; b.z -= scale; AddLine( a, b, colour ); } //============================================================================== // DebugInfo::AddBox //============================================================================== // // Description: // // Parameters: // // Return: // //============================================================================== void DebugInfo::AddBox(const rmt::Vector& a, const rmt::Vector& b, tColour colour) { //Draw all 12 lines that make up the box for(int i=0;i<4;i++) { AddLine(rmt::Vector((i&2)?a.x:b.x,(i&1)?a.y:b.y,a.z), rmt::Vector((i&2)?a.x:b.x,(i&1)?a.y:b.y,b.z),colour); AddLine(rmt::Vector((i&2)?a.x:b.x,a.y,(i&1)?a.z:b.z), rmt::Vector((i&2)?a.x:b.x,b.y,(i&1)?a.z:b.z),colour); AddLine(rmt::Vector(a.x,(i&2)?a.y:b.y,(i&1)?a.z:b.z), rmt::Vector(b.x,(i&2)?a.y:b.y,(i&1)?a.z:b.z),colour); } } //============================================================================== // DebugInfo::AddBox //============================================================================== // // Description: // // Parameters: // // Return: // //============================================================================== void DebugInfo::AddBox(const rmt::Vector ¢er, const float r, tColour colour) { rmt::Vector a,b; a.Sub(center, rmt::Vector(r,r,r)); b.Add(center, rmt::Vector(r,r,r)); AddBox(a,b,colour); } //============================================================================== // DebugInfo::AddCircle //============================================================================== // // Description: // // Parameters: // // Return: // //============================================================================== void DebugInfo::AddCircle( const rmt::Vector& center, const float r, tColour colour ) { rmt::Vector a,b; int i; int n = 8; for( i = 0; i < n; i++ ) { a.x = center.x + r * rmt::Cos( i * rmt::PI_2 / n ); a.y = center.y; a.z = center.z + r * rmt::Sin( i * rmt::PI_2 / n ); b.x = center.x + r * rmt::Cos( ( i + 1 ) * rmt::PI_2 / n ); b.y = center.y; b.z = center.z + r * rmt::Sin( ( i + 1 ) * rmt::PI_2 / n ); AddLine( a, b, colour ); } } //============================================================================== // DebugInfo::AddText //============================================================================== // // Description: // // Parameters: // // Return: // //============================================================================== void DebugInfo::AddText(const char *szName, const rmt::Vector &pos, tColour colour) { rAssert(_NumSection>0); rAssert(_StackSize>0); _ppSections[_pStack[_StackSize-1]]->AddText(szName, pos, colour); } //============================================================================== // DebugInfo::AddScreenLine //============================================================================== // // Description: // // Parameters: // // Return: // //============================================================================== void DebugInfo::AddScreenLine(const rmt::Vector& a, const rmt::Vector& b, tColour colour) { rAssert(_NumSection>0); rAssert(_StackSize>0); _ppSections[_pStack[_StackSize-1]]->AddScreenLine(a, b, colour); } //============================================================================== // DebugInfo::AddScreenText //============================================================================== // // Description: // // Parameters: // // Return: // //============================================================================== void DebugInfo::AddScreenText(const char* szName, tColour colour ) { rAssert(_NumSection>0); rAssert(_StackSize>0); _ppSections[_pStack[_StackSize-1]]->AddScreenText(szName, colour); } //============================================================================== // DebugInfo::AddScreenText //============================================================================== // // Description: // // Parameters: // // Return: // //============================================================================== void DebugInfo::AddScreenText(const char* szName, const rmt::Vector &a, tColour colour ) { rAssert(_NumSection>0); rAssert(_StackSize>0); _ppSections[_pStack[_StackSize-1]]->AddScreenText(szName, a,colour); } //============================================================================== // DebugInfo::RenderBackground //============================================================================== // // Description: // // Parameters: // // Return: // //============================================================================== void DebugInfo::RenderBackground() { p3d::stack->Push(); p3d::stack->LoadIdentity(); pddiProjectionMode mode = p3d::pddi->GetProjectionMode(); p3d::pddi->SetProjectionMode(PDDI_PROJECTION_DEVICE); p3d::pddi->SetCullMode(PDDI_CULL_NONE); if( _shader == NULL ) { // // init the shader // _shader = p3d::device->NewShader("simple"); _shader->SetInt(PDDI_SP_SHADEMODE, PDDI_SHADE_FLAT); } _shader->SetInt(PDDI_SP_BLENDMODE, PDDI_BLEND_ALPHA); pddiPrimStream* stream = p3d::pddi->BeginPrims(_shader, PDDI_PRIM_TRIANGLES, PDDI_V_C, 6); float nearplane, farplane, fov, aspect; p3d::pddi->GetCamera(&nearplane, &farplane, &fov, &aspect); nearplane += 0.01f; float width, height; width = (float)p3d::display->GetWidth(); height = (float)p3d::display->GetHeight(); pddiColour colour(0, 0, 0, 200); stream->Colour(colour); stream->Coord(0, height, nearplane); stream->Colour(colour); stream->Coord(width, height, nearplane); stream->Colour(colour); stream->Coord(width, 0, nearplane); stream->Colour(colour); stream->Coord(0, height, nearplane); stream->Colour(colour); stream->Coord(width, 0, nearplane); stream->Colour(colour); stream->Coord(0, 0, nearplane); p3d::pddi->EndPrims(stream); p3d::pddi->SetProjectionMode(mode); p3d::stack->Pop(); } //============================================================================== // DebugInfo::Render //============================================================================== // // Description: // // Parameters: // // Return: // //============================================================================== void DebugInfo::Render() { //rAssert(_StackSize==0); // skip if disabled or no sections if(! _isRenderEnabled) return; if(_NumSection == 0) return; // this makes the text easier to read if(_isBackgroundEnabled) RenderBackground(); // render the title with the name of the current section char sectionName[255] = "DebugInfo : "; Section *pSect = _ppSections[_CurrentSection]; sprintf(sectionName, "DebugInfo : %s", pSect->GetName()); p3d::pddi->DrawString(sectionName, 40, 50, tColour(0,255,255)); // render the current section pSect->Render(); //Clear all the sections after we display int i; for(i=0;i<_NumSection;i++) { if(_ppSections[i]->GetAutoReset()) { _ppSections[i]->Reset(_ppSections[i]->GetName()); } } } #endif // DEBUGINFO_ENABLED