*/ void Debug_Uni(const REBSER *ser) /* ** Print debug unicode string followed by a newline. ** ***********************************************************************/ { REBCNT ul; REBCNT bl; REBYTE buf[1024]; REBUNI *up = UNI_HEAD(ser); REBINT size = Length_As_UTF8(up, SERIES_TAIL(ser), TRUE, OS_CRLF); REBINT disabled = GC_Disabled; GC_Disabled = 1; while (size > 0) { ul = Encode_UTF8(buf, MIN(size, 1020), up, &bl, TRUE, OS_CRLF); Debug_String(buf, bl, 0, 0); size -= ul; up += ul; } Debug_Line(); assert(GC_Disabled == 1); GC_Disabled = disabled; }
//-------------------------------------------------------- // //-------------------------------------------------------- Bool TLFileSys::TFileCollada::CreateDatum(TLAsset::TMesh& Mesh,TRefRef DatumRef,TRefRef DatumShapeType,const TLAsset::TMesh& GeometryMesh) { TPtr<TLMaths::TShape> pShape; if ( DatumShapeType == TLMaths::TSphere2D::GetTypeRef() ) { // get box of points for extents TLMaths::TBox2D Box; Box.Accumulate( GeometryMesh.GetVertexes() ); pShape = new TLMaths::TShapeSphere2D( Box ); } else if ( DatumShapeType == TLMaths::TSphere::GetTypeRef() ) { // get box of points for extents TLMaths::TBox Box; Box.Accumulate( GeometryMesh.GetVertexes() ); pShape = new TLMaths::TShapeSphere( Box ); } else if ( DatumShapeType == TLMaths::TOblong2D::GetTypeRef() ) { // gr: no limit on vertexes any more... TOblong2D shape needs to turn into a TPolygon2D shape pShape = new TLMaths::TShapePolygon2D( GeometryMesh.GetVertexes() ); } else if ( DatumShapeType == TLMaths::TCapsule2D::GetTypeRef() ) { // get box of points for extents TLMaths::TBox2D Box; Box.Accumulate( GeometryMesh.GetVertexes() ); pShape = new TLMaths::TShapeCapsule2D( Box ); } else if ( DatumShapeType == TLMaths::TBox2D::GetTypeRef() ) { // get box of points for extents TLMaths::TBox2D Box; Box.Accumulate( GeometryMesh.GetVertexes() ); pShape = new TLMaths::TShapeBox2D( Box ); } else if ( DatumShapeType == TLMaths::TBox::GetTypeRef() ) { // get box of points for extents TLMaths::TBox Box; Box.Accumulate( GeometryMesh.GetVertexes() ); pShape = new TLMaths::TShapeBox( Box ); } // created okay if ( pShape ) { // add datum Mesh.AddDatum( DatumRef, pShape ); return TRUE; } #ifdef _DEBUG TTempString Debug_String("Unknown datum shape type "); DatumShapeType.GetString( Debug_String ); TLDebug_Break(Debug_String); #endif return FALSE; }
*/ void Debug_Str(const char *str) /* ** Print a string followed by a newline. ** ***********************************************************************/ { Debug_String(cb_cast(str), UNKNOWN, 0, 1); }
//---------------------------------------------- // create a menu. default just loads menu definition from assets, overload to create custom menus //---------------------------------------------- TPtr<TLAsset::TMenu> TLMenu::TMenuController::CreateMenu(TRefRef MenuRef) { // find menu asset - note: this has to be block loaded because its not too easy to make this an async operation TPtr<TLAsset::TMenu> pMenuAsset = TLAsset::GetAssetPtr<TLAsset::TMenu>( MenuRef ); if ( !pMenuAsset ) { TTempString Debug_String("Failed to find menu asset "); MenuRef.GetString( Debug_String ); TLDebug_Warning( Debug_String ); } return pMenuAsset; }
*/ void Debug_Line(void) /* ***********************************************************************/ { Debug_String(cb_cast(""), UNKNOWN, 0, 1); }
//------------------------------------------------- // process a click and detect clicks on/off our render node. return SyncWait if we didnt process it and want to process again //------------------------------------------------- SyncBool TLGui::TWidgetThumbStick::ProcessClick(TClick& Click,TLRender::TScreen& Screen,TLRender::TRenderTarget& RenderTarget,TLRender::TRenderNode& RenderNode,const TLMaths::TShapeSphere2D& BoundsDatum,const TLMaths::TShape* pClickDatum) { Bool bClickAction = TLGui::g_pWidgetManager->IsClickActionRef(Click.GetActionRef()); Bool bMoveAction = TLGui::g_pWidgetManager->IsMoveActionRef(Click.GetActionRef()); Bool bCurrentAction = FALSE; Bool bActionPair = FALSE; if(m_ActionBeingProcessedRef.IsValid()) { bCurrentAction = (Click.GetActionRef() == m_ActionBeingProcessedRef); bActionPair = TLGui::g_pWidgetManager->IsActionPair(m_ActionBeingProcessedRef, Click.GetActionRef()); } Bool bTestIntersection = FALSE; if(m_ActionBeingProcessedRef.IsValid()) { if(bClickAction && bCurrentAction) { if(Click.GetActionType() == TLGui_WidgetActionType_Up ) { OnClickEnd( Click ); m_ActionBeingProcessedRef.SetInvalid(); return SyncTrue; } } else if(bMoveAction && bActionPair) { bTestIntersection = TRUE; } } else if(bClickAction) { if(Click.GetActionType() == TLGui_WidgetActionType_Up ) { if(bCurrentAction) { OnClickEnd( Click ); m_ActionBeingProcessedRef.SetInvalid(); return SyncTrue; } } else { // No 'click' action in progress yet. Test intersection bTestIntersection = TRUE; } } if(!bTestIntersection) return SyncFalse; // see if ray intersects our object, and creates a valid ray SyncBool Intersection = IsIntersecting(Screen, RenderTarget, RenderNode, BoundsDatum, pClickDatum, Click ); if ( Intersection == SyncTrue ) { if(bClickAction) m_ActionBeingProcessedRef = Click.GetActionRef(); } else if ( Intersection == SyncFalse ) { OnClickEnd( Click ); if(bClickAction) m_ActionBeingProcessedRef.SetInvalid(); return SyncFalse; } else if ( Intersection == SyncWait ) { return SyncWait; } /* SyncBool Result = TWidget::ProcessClick(Click, Screen, RenderTarget, RenderNode); if(Result != SyncTrue) return Result; */ // Custom OnClick effectively... // get the 2d circle bounds as the thumbstick // if not valid, wait till next frame (off-screen?) const TLMaths::TShapeSphere2D& BoundsSphere = RenderNode.GetWorldBoundsSphere2D(); if ( !BoundsSphere.IsValid() ) return SyncWait; // get vector from center of the sphere to the click point float2 ClickVector = Click.GetWorldRay().GetStart().xy() - BoundsSphere.GetCenter().xy(); // normalise vector to 0..1 in the sphere ClickVector /= BoundsSphere.GetSphere().GetRadius(); // get length to work out normalised vector and if we're in the deadzone float VectorLen = ClickVector.Length(); // in the dead zone, return TRUE (processed click) but don't send out a message // this "ignores" the click if ( VectorLen <= m_DeadZone ) return SyncTrue; // send out thumb stick message TRef ActionOutRef = m_ActionOutDown; if ( ActionOutRef.IsValid() ) { #ifdef _DEBUG TTempString Debug_String("WidgetThumbstick ("); m_RenderNodeRef.GetString( Debug_String ); Debug_String.Append(") sending thumbstick message: "); ActionOutRef.GetString( Debug_String ); Debug_String.Appendf(": %.2f, %.2f", ClickVector.x, ClickVector.y ); TLDebug_Print( Debug_String ); #endif // make up fake input message TLMessaging::TMessage Message(TRef_Static(A,c,t,i,o)); Message.Write( ActionOutRef ); Message.ExportData("RawData", ClickVector ); // send message PublishMessage( Message ); } return SyncTrue; }
//-------------------------------------------------------- // parse XML tag to Binary data[tree] //-------------------------------------------------------- Bool TLFile::ParseXMLDataTree(TXmlTag& Tag,TBinaryTree& Data) { /* XML examples // root data <Data><u32>100</u32></Data> // put in "translate" child <Data DataRef="translate"><float3>0,40,0</float3></Data> // "Node" data inside "NodeList" data <Data DataRef="NodeList"> <Bool>TRUE</Bool> // written to "NodeList" <Data DataRef="Node"><TRef>ohai</TRef></Data> </Data> */ // read the data ref const TString* pDataRefString = Tag.GetProperty("DataRef"); TRef DataRef( pDataRefString ? *pDataRefString : "" ); // establish the data we're writing data to TPtr<TBinaryTree> pDataChild; // add a child to the node data if it has a ref, otherwise data is added to root of the node if ( DataRef.IsValid() ) { pDataChild = Data.AddChild( DataRef ); // failed to add child data... if ( !pDataChild ) { TLDebug_Break("failed to add child data"); return FALSE; } } // import contents of data TBinaryTree& NodeData = pDataChild ? *pDataChild.GetObjectPointer() : Data; // if the tag has no children (eg. type like <float />) but DOES have data (eg. 1.0) throw up an error and fail // assume the data is malformed and someone has forgotten to add the type specifier. // if something automated has output it and doesnt know the type it should still output it as hex raw data if ( !Tag.GetChildren().GetSize() && Tag.GetDataString().GetLength() > 0 ) { TTempString Debug_String("<Data "); DataRef.GetString( Debug_String ); Debug_String.Append("> tag with no children, but DOES have data inside (eg. 1.0). Missing type specifier? (eg. <flt3>)\n"); Debug_String.Append( Tag.GetDataString() ); TLDebug_Break( Debug_String ); return SyncFalse; } // deal with child tags for ( u32 c=0; c<Tag.GetChildren().GetSize(); c++ ) { TPtr<TXmlTag>& pChildTag = Tag.GetChildren().ElementAt(c); SyncBool TagImportResult = SyncFalse; if ( pChildTag->GetTagName() == "data" ) { // import child data if ( ParseXMLDataTree( *pChildTag, NodeData ) ) TagImportResult = SyncTrue; else TagImportResult = SyncFalse; if ( TagImportResult != SyncTrue ) Data.Debug_PrintTree(); } else { TRef DataTypeRef = TLFile::GetDataTypeFromString( pChildTag->GetTagName() ); // update type of data // gr: DONT do this, if the type is mixed, this overwrites it. Setting the DataTypeHint should be automaticly done when we Write() in ImportBinaryData //NodeData.SetDataTypeHint( DataTypeRef ); TagImportResult = TLFile::ImportBinaryData( pChildTag->GetDataString(), NodeData, DataTypeRef ); // gr: just to check the data hint is being set from the above function... if ( TagImportResult == SyncTrue && !NodeData.GetDataTypeHint().IsValid() && NodeData.GetSize() > 0 ) { TTempString Debug_String("Data imported is missing data type hint after successfull write? We just wrote data type "); DataTypeRef.GetString( Debug_String ); Debug_String.Append(". This can be ignored if the data is mixed types"); TLDebug_Break( Debug_String ); Data.Debug_PrintTree(); } } // failed if ( TagImportResult == SyncFalse ) { TTempString str; str << "failed to import <data> tag \"" << pChildTag->GetTagName() << "\""; TLDebug_Break( str ); return FALSE; } // async is unsupported if ( TagImportResult == SyncWait ) { TLDebug_Break("todo: async Scheme import"); return FALSE; } } return TRUE; }
TRef TLFile::GetDataTypeFromString(const TString& String) { // turn string into a ref and check against the ref types... TRef StringRef( String ); // add "tootle data xml" supported types to this case statement switch ( StringRef.GetData() ) { case TLBinary_TypeRef(TRef): case TLBinary_TypeRef(Bool): case TLBinary_TypeRef(float): case TLBinary_TypeRef(float2): case TLBinary_TypeRef(float3): case TLBinary_TypeRef(float4): case TLBinary_TypeRef(u8): case TLBinary_TypeRef(u16): case TLBinary_TypeRef(u32): case TLBinary_TypeRef(u64): case TLBinary_TypeRef(s8): case TLBinary_TypeRef(s16): case TLBinary_TypeRef(s32): case TLBinary_TypeRef(s64): case TLBinary_TypeRef_Hex8: case TLBinary_TypeRef_Hex16: case TLBinary_TypeRef_Hex32: case TLBinary_TypeRef_Hex64: case TLBinary_TypeRef(TQuaternion): case TLBinary_TypeRef(TEuler): case TLBinary_TypeRef(TAxisAngle): case TLBinary_TypeRef(TColour): case TLBinary_TypeRef(TColour24): case TLBinary_TypeRef(TColour32): case TLBinary_TypeRef(TColour64): case TLBinary_TypeRef_String: case TLBinary_TypeRef_WideString: { // matches an existing data type ref return StringRef; } break; default: break; }; #ifdef _DEBUG TTempString Debug_String("Warning: using old data type name "); Debug_String.Append( String ); TLDebug_Print( Debug_String ); #endif // old string -> type detection if ( String == "float" ) return TLBinary::GetDataTypeRef<float>(); if ( String == "float2" ) return TLBinary::GetDataTypeRef<float2>(); if ( String == "float3" ) return TLBinary::GetDataTypeRef<float3>(); if ( String == "float4" ) return TLBinary::GetDataTypeRef<float4>(); if ( String == "quaternion" ) return TLBinary::GetDataTypeRef<TLMaths::TQuaternion>(); if ( String == "colour" ) return TLBinary::GetDataTypeRef<TColour>(); // unknown type #ifdef _DEBUG Debug_String.Set("Unsupported data type "); Debug_String.Append( String ); TLDebug_Break( Debug_String ); #endif return TRef_Invalid; }