/** Stops all related sounds * @param[in] _pstSoundPointer Concerned SoundPointer * @return orxSTATUS_SUCCESS / orxSTATUS_FAILURE */ orxSTATUS orxFASTCALL orxSoundPointer_Stop(orxSOUNDPOINTER *_pstSoundPointer) { orxU32 i; orxSTATUS eResult = orxSTATUS_SUCCESS; /* Checks */ orxASSERT(sstSoundPointer.u32Flags & orxSOUNDPOINTER_KU32_STATIC_FLAG_READY); orxSTRUCTURE_ASSERT(_pstSoundPointer); /* For all sounds */ for(i = 0; i < orxSOUNDPOINTER_KU32_SOUND_NUMBER; i++) { orxSOUND *pstSound; /* Gets sound */ pstSound = _pstSoundPointer->astSoundList[i].pstSound; /* Valid? */ if(pstSound != orxNULL) { /* Updates its flags */ orxFLAG_SET(_pstSoundPointer->astSoundList[i].u32Flags, orxSOUNDPOINTER_HOLDER_KU32_FLAG_NONE, orxSOUNDPOINTER_HOLDER_KU32_FLAG_AUTO_PLAY); /* Stops it */ orxSound_Stop(pstSound); /* Delegates update to the sound */ orxStructure_Update(pstSound, orxStructure_GetOwner(_pstSoundPointer), orxNULL); } } /* Done! */ return eResult; }
/** Clears cache (if any TimeLine track is still in active use, it'll remain in memory until not referenced anymore) * @return orxSTATUS_SUCCESS / orxSTATUS_FAILURE */ orxSTATUS orxFASTCALL orxTimeLine_ClearCache() { orxTIMELINE_TRACK *pstTrack, *pstNewTrack; orxU64 u64Key; orxHANDLE hIterator, hNextIterator; orxSTATUS eResult = orxSTATUS_SUCCESS; /* Checks */ orxASSERT(sstTimeLine.u32Flags & orxTIMELINE_KU32_STATIC_FLAG_READY); /* For all tracks */ for(hIterator = orxHashTable_GetNext(sstTimeLine.pstTrackTable, orxHANDLE_UNDEFINED, &u64Key, (void **)&pstTrack); hIterator != orxHANDLE_UNDEFINED; hIterator = hNextIterator, pstTrack = pstNewTrack) { /* Gets next track */ hNextIterator = orxHashTable_GetNext(sstTimeLine.pstTrackTable, hIterator, &u64Key, (void **)&pstNewTrack); /* Is cached? */ if(orxFLAG_TEST(pstTrack->u32Flags, orxTIMELINE_TRACK_KU32_FLAG_CACHED)) { /* Updates its flags */ orxFLAG_SET(pstTrack->u32Flags, orxTIMELINE_TRACK_KU32_FLAG_NONE, orxTIMELINE_TRACK_KU32_FLAG_CACHED); /* Deletes its extra reference */ orxTimeLine_DeleteTrack(pstTrack); } } /* Done! */ return eResult; }
/** Adds a delayed FX * @param[in] _pstFXPointer Concerned FXPointer * @param[in] _pstFX FX to add * @param[in] _fDelay Delay time * @return orxSTATUS_SUCCESS / orxSTATUS_FAILURE */ orxSTATUS orxFASTCALL orxFXPointer_AddDelayedFX(orxFXPOINTER *_pstFXPointer, orxFX *_pstFX, orxFLOAT _fDelay) { orxU32 u32Index; orxSTATUS eResult; /* Checks */ orxASSERT(sstFXPointer.u32Flags & orxFXPOINTER_KU32_STATIC_FLAG_READY); orxSTRUCTURE_ASSERT(_pstFXPointer); orxSTRUCTURE_ASSERT(_pstFX); orxASSERT(_fDelay >= orxFLOAT_0); /* Finds an empty slot */ for(u32Index = 0; (u32Index < orxFXPOINTER_KU32_FX_NUMBER) && (_pstFXPointer->astFXList[u32Index].pstFX != orxNULL); u32Index++); /* Found? */ if(u32Index < orxFXPOINTER_KU32_FX_NUMBER) { orxSTRUCTURE *pstOwner; orxFX_EVENT_PAYLOAD stPayload; /* Gets owner */ pstOwner = orxStructure_GetOwner(_pstFXPointer); /* Increases its reference counter */ orxStructure_IncreaseCounter(_pstFX); /* Adds it to holder */ _pstFXPointer->astFXList[u32Index].pstFX = _pstFX; /* Inits its start time */ _pstFXPointer->astFXList[u32Index].fStartTime = _pstFXPointer->fTime + _fDelay; /* Updates its flags */ orxFLAG_SET(_pstFXPointer->astFXList[u32Index].u32Flags, orxFXPOINTER_HOLDER_KU32_FLAG_NONE, orxFXPOINTER_HOLDER_KU32_MASK_ALL); /* Inits event payload */ orxMemory_Zero(&stPayload, sizeof(orxFX_EVENT_PAYLOAD)); stPayload.pstFX = _pstFX; stPayload.zFXName = orxFX_GetName(_pstFX); /* Sends event */ orxEVENT_SEND(orxEVENT_TYPE_FX, orxFX_EVENT_ADD, pstOwner, pstOwner, &stPayload); /* Updates result */ eResult = orxSTATUS_SUCCESS; } else { /* Logs message */ orxDEBUG_PRINT(orxDEBUG_LEVEL_OBJECT, "No available slots for FX."); /* Updates result */ eResult = orxSTATUS_FAILURE; } /* Done! */ return eResult; }
/** Enables/disables a given log level * @param[in] _eLevel Debug level to enable/disable * @param[in] _bEnable Enable / disable */ void orxFASTCALL _orxDebug_EnableLevel(orxDEBUG_LEVEL _eLevel, orxBOOL _bEnable) { /* Checks */ orxASSERT(sstDebug.u32Flags & orxDEBUG_KU32_STATIC_FLAG_READY); /* Enable? */ if(_bEnable != orxFALSE) { /* All levels? */ if(_eLevel == orxDEBUG_LEVEL_ALL) { /* Updates level flags */ orxFLAG_SET(sstDebug.u32LevelFlags, 0xFFFFFFFF, 0); } else { /* Checks */ orxASSERT(_eLevel < orxDEBUG_LEVEL_NUMBER); /* Updates level flags */ orxFLAG_SET(sstDebug.u32LevelFlags, 1 << _eLevel, 0); } } else { /* All levels? */ if(_eLevel == orxDEBUG_LEVEL_ALL) { /* Updates level flags */ orxFLAG_SET(sstDebug.u32LevelFlags, 0, 0xFFFFFFFF); } else { /* Checks */ orxASSERT(_eLevel < orxDEBUG_LEVEL_NUMBER); /* Updates level flags */ orxFLAG_SET(sstDebug.u32LevelFlags, 0, 1 << _eLevel); } } /* Done! */ return; }
static orxSTATUS orxFASTCALL ProcessFontParams(orxU32 _u32ParamCount, const orxSTRING _azParams[]) { orxSTATUS eResult = orxSTATUS_FAILURE; // Has a valid font parameter? if(_u32ParamCount > 1) { // Inits FreeType if(!FT_Init_FreeType(&sstFontGen.pstFontLibrary)) { // Loads font's default face if(!FT_New_Face(sstFontGen.pstFontLibrary, _azParams[1], 0, &sstFontGen.pstFontFace)) { // Sets unicode map if(!FT_Select_Charmap(sstFontGen.pstFontFace, ft_encoding_unicode)) { // Updates character size sstFontGen.vCharacterSize.fX = sstFontGen.vCharacterSize.fY; // Updates character spacing sstFontGen.vCharacterSpacing.fX = orx2F(2.0f); sstFontGen.vCharacterSpacing.fY = orx2F(2.0f); // Stores scale sstFontGen.fFontScale = sstFontGen.vCharacterSize.fY / orxS2F(sstFontGen.pstFontFace->bbox.yMax - sstFontGen.pstFontFace->bbox.yMin); // Sets pixel's size eResult = FT_Set_Pixel_Sizes(sstFontGen.pstFontFace, (FT_UInt)orxF2U(sstFontGen.vCharacterSize.fX) - 2, (FT_UInt)orxF2U(sstFontGen.vCharacterSize.fY) - 2) ? orxSTATUS_FAILURE : orxSTATUS_SUCCESS; } } } // Success? if(eResult != orxSTATUS_FAILURE) { // Updates status orxFLAG_SET(sstFontGen.u32Flags, orxFONTGEN_KU32_STATIC_FLAG_FONT, orxFONTGEN_KU32_STATIC_FLAG_NONE); // Logs message orxFONTGEN_LOG(FONT, "Using font '%s'.", _azParams[1]); } else { // Logs message orxFONTGEN_LOG(FONT, "Couldn't load font '%s'.", _azParams[1]); } } else { // Logs message orxFONTGEN_LOG(FONT, "No font specified, aborting."); } // Done! return eResult; }
/** Inits the TimeLine module * @return orxSTATUS_SUCCESS / orxSTATUS_FAILURE */ orxSTATUS orxFASTCALL orxTimeLine_Init() { orxSTATUS eResult = orxSTATUS_FAILURE; /* Not already Initialized? */ if(!(sstTimeLine.u32Flags & orxTIMELINE_KU32_STATIC_FLAG_READY)) { /* Cleans static controller */ orxMemory_Zero(&sstTimeLine, sizeof(orxTIMELINE_STATIC)); /* Creates track table */ sstTimeLine.pstTrackTable = orxHashTable_Create(orxTIMELINE_KU32_TRACK_TABLE_SIZE, orxHASHTABLE_KU32_FLAG_NONE, orxMEMORY_TYPE_MAIN); /* Valid? */ if(sstTimeLine.pstTrackTable != orxNULL) { /* Registers structure type */ eResult = orxSTRUCTURE_REGISTER(TIMELINE, orxSTRUCTURE_STORAGE_TYPE_LINKLIST, orxMEMORY_TYPE_MAIN, orxTIMELINE_KU32_BANK_SIZE, &orxTimeLine_Update); } else { /* Logs message */ orxDEBUG_PRINT(orxDEBUG_LEVEL_OBJECT, "Failed to create TimeLine track table."); } } else { /* Logs message */ orxDEBUG_PRINT(orxDEBUG_LEVEL_OBJECT, "Tried to initialize the TimeLine module when it was already initialized."); /* Already initialized */ eResult = orxSTATUS_SUCCESS; } /* Initialized? */ if(eResult != orxSTATUS_FAILURE) { /* Inits Flags */ orxFLAG_SET(sstTimeLine.u32Flags, orxTIMELINE_KU32_STATIC_FLAG_READY, orxTIMELINE_KU32_STATIC_FLAG_NONE); /* Adds event handler */ orxEvent_AddHandler(orxEVENT_TYPE_RESOURCE, orxTimeLine_EventHandler); } else { /* Deletes track table if needed */ if(sstTimeLine.pstTrackTable != orxNULL) { orxHashTable_Delete(sstTimeLine.pstTrackTable); } } /* Done! */ return eResult; }
/** Exits from the event module */ void orxFASTCALL orxEvent_Exit() { /* Initialized? */ if(orxFLAG_TEST(sstEvent.u32Flags, orxEVENT_KU32_STATIC_FLAG_READY)) { /* Deletes hashtable */ orxHashTable_Delete(sstEvent.pstHandlerStorageTable); /* Deletes bank */ orxBank_Delete(sstEvent.pstHandlerStorageBank); /* Updates flags */ orxFLAG_SET(sstEvent.u32Flags, orxEVENT_KU32_STATIC_FLAG_NONE, orxEVENT_KU32_STATIC_MASK_ALL); } return; }
static orxSTATUS orxFASTCALL ProcessMonospaceParams(orxU32 _u32ParamCount, const orxSTRING _azParams[]) { orxSTATUS eResult = orxSTATUS_SUCCESS; // Defined? if(_u32ParamCount > 0) { // Updates status flags orxFLAG_SET(sstFontGen.u32Flags, orxFONTGEN_KU32_STATIC_FLAG_MONOSPACE, orxFONTGEN_KU32_STATIC_FLAG_NONE); // Logs message orxFONTGEN_LOG(MODE, "Output mode set to monospace."); } // Done! return eResult; }
static orxSTATUS orxFASTCALL ProcessAdvanceParams(orxU32 _u32ParamCount, const orxSTRING _azParams[]) { orxSTATUS eResult = orxSTATUS_SUCCESS; // Defined? if(_u32ParamCount > 0) { // Updates status flags orxFLAG_SET(sstFontGen.u32Flags, orxFONTGEN_KU32_STATIC_FLAG_ADVANCE, orxFONTGEN_KU32_STATIC_FLAG_NONE); // Logs message orxFONTGEN_LOG(PACKING, "Using original glyph advance values."); } // Done! return eResult; }
static orxSTATUS orxFASTCALL ProcessSizeParams(orxU32 _u32ParamCount, const orxSTRING _azParams[]) { orxSTATUS eResult; // Has a valid size parameter? if(_u32ParamCount > 1) { orxFLOAT fSize; // Gets it if((eResult = orxString_ToFloat(_azParams[1], &fSize, orxNULL)) != orxSTATUS_FAILURE) { // Stores it sstFontGen.vCharacterSize.fY = fSize; // Updates status orxFLAG_SET(sstFontGen.u32Flags, orxFONTGEN_KU32_STATIC_FLAG_SIZE, orxFONTGEN_KU32_STATIC_FLAG_NONE); // Logs message orxFONTGEN_LOG(SIZE, "Character size set to '%g'.", fSize); } else { // Logs message orxFONTGEN_LOG(SIZE, "Invalid character size found in '%s', aborting.", _azParams[1]); } } else { // Logs message orxFONTGEN_LOG(SIZE, "No character size found, aborting."); // Updates result eResult = orxSTATUS_FAILURE; } // Done! return eResult; }
/** Adds a delayed FX using its config ID * @param[in] _pstFXPointer Concerned FXPointer * @param[in] _zFXConfigID Config ID of the FX to add * @param[in] _fDelay Delay time * @return orxSTATUS_SUCCESS / orxSTATUS_FAILURE */ orxSTATUS orxFASTCALL orxFXPointer_AddDelayedFXFromConfig(orxFXPOINTER *_pstFXPointer, const orxSTRING _zFXConfigID, orxFLOAT _fDelay) { orxU32 u32Index; orxSTATUS eResult; /* Checks */ orxASSERT(sstFXPointer.u32Flags & orxFXPOINTER_KU32_STATIC_FLAG_READY); orxSTRUCTURE_ASSERT(_pstFXPointer); orxASSERT((_zFXConfigID != orxNULL) && (_zFXConfigID != orxSTRING_EMPTY)); orxASSERT(_fDelay >= orxFLOAT_0); /* Finds an empty slot */ for(u32Index = 0; (u32Index < orxFXPOINTER_KU32_FX_NUMBER) && (_pstFXPointer->astFXList[u32Index].pstFX != orxNULL); u32Index++); /* Found? */ if(u32Index < orxFXPOINTER_KU32_FX_NUMBER) { orxFX *pstFX; /* Creates FX */ pstFX = orxFX_CreateFromConfig(_zFXConfigID); /* Valid? */ if(pstFX != orxNULL) { orxSTRUCTURE *pstOwner; orxFX_EVENT_PAYLOAD stPayload; /* Gets owner */ pstOwner = orxStructure_GetOwner(_pstFXPointer); /* Increases its reference counter */ orxStructure_IncreaseCounter(pstFX); /* Adds it to holder */ _pstFXPointer->astFXList[u32Index].pstFX = pstFX; /* Inits its start time */ _pstFXPointer->astFXList[u32Index].fStartTime = _pstFXPointer->fTime + _fDelay; /* Updates its owner */ orxStructure_SetOwner(pstFX, _pstFXPointer); /* Updates its flags */ orxFLAG_SET(_pstFXPointer->astFXList[u32Index].u32Flags, orxFXPOINTER_HOLDER_KU32_FLAG_INTERNAL, orxFXPOINTER_HOLDER_KU32_MASK_ALL); /* Inits event payload */ orxMemory_Zero(&stPayload, sizeof(orxFX_EVENT_PAYLOAD)); stPayload.pstFX = pstFX; stPayload.zFXName = orxFX_GetName(pstFX); /* Sends event */ orxEVENT_SEND(orxEVENT_TYPE_FX, orxFX_EVENT_ADD, pstOwner, pstOwner, &stPayload); /* Updates result */ eResult = orxSTATUS_SUCCESS; } else { /* Logs message */ orxDEBUG_PRINT(orxDEBUG_LEVEL_OBJECT, "Loading FX <%s> from config failed.", _zFXConfigID); /* Updates result */ eResult = orxSTATUS_FAILURE; } } else { /* Logs message */ orxDEBUG_PRINT(orxDEBUG_LEVEL_SOUND, "Failed to find an empty slot to put FX <%s> into.", _zFXConfigID); /* Updates result */ eResult = orxSTATUS_FAILURE; } /* Done! */ return eResult; }
/** Event handler */ static orxSTATUS orxFASTCALL orxTimeLine_EventHandler(const orxEVENT *_pstEvent) { orxSTATUS eResult = orxSTATUS_SUCCESS; /* Add or update? */ if((_pstEvent->eID == orxRESOURCE_EVENT_ADD) || (_pstEvent->eID == orxRESOURCE_EVENT_UPDATE)) { orxRESOURCE_EVENT_PAYLOAD *pstPayload; /* Gets payload */ pstPayload = (orxRESOURCE_EVENT_PAYLOAD *)_pstEvent->pstPayload; /* Is config group? */ if(pstPayload->u32GroupID == orxString_ToCRC(orxCONFIG_KZ_RESOURCE_GROUP)) { orxHANDLE hIterator; orxU64 u64Key; orxTIMELINE_TRACK *pstTrack; /* For all tracks */ for(hIterator = orxHashTable_GetNext(sstTimeLine.pstTrackTable, orxHANDLE_UNDEFINED, &u64Key, (void **)&pstTrack); hIterator != orxHANDLE_UNDEFINED; hIterator = orxHashTable_GetNext(sstTimeLine.pstTrackTable, hIterator, &u64Key, (void **)&pstTrack)) { /* Match origin? */ if(orxConfig_GetOriginID(pstTrack->zReference) == pstPayload->u32NameID) { orxTIMELINE *pstTimeLine; orxTIMELINE_TRACK *pstNewTrack; orxU32 u32Counter, u32ID, u32Flags; const orxSTRING zReference; /* Backups counter, ID, flags & reference */ u32Counter = pstTrack->u32RefCounter; u32ID = pstTrack->u32ID; u32Flags = orxFLAG_GET(pstTrack->u32Flags, orxTIMELINE_TRACK_KU32_MASK_BACKUP); zReference = pstTrack->zReference; /* Deletes it (but keeps it reference in the hashtable to prevent infinite loop upon table changes) */ orxMemory_Free(pstTrack); /* Creates new track */ pstNewTrack = orxTimeLine_CreateTrack(zReference); /* Success? */ if(pstNewTrack != orxNULL) { /* Restores its counter */ pstNewTrack->u32RefCounter = u32Counter; /* Restores its flags */ orxFLAG_SET(pstNewTrack->u32Flags, u32Flags, orxTIMELINE_TRACK_KU32_MASK_BACKUP); } else { /* Removes old reference from the table */ orxHashTable_Remove(sstTimeLine.pstTrackTable, u32ID); } /* For all timelines */ for(pstTimeLine = orxTIMELINE(orxStructure_GetFirst(orxSTRUCTURE_ID_TIMELINE)); pstTimeLine != orxNULL; pstTimeLine = orxTIMELINE(orxStructure_GetNext(pstTimeLine))) { orxU32 u32Index; /* For all its track */ for(u32Index = 0; u32Index < orxTIMELINE_KU32_TRACK_NUMBER; u32Index++) { /* Matches? */ if(pstTimeLine->astTrackList[u32Index].pstTrack == pstTrack) { /* Updates its data */ pstTimeLine->astTrackList[u32Index].pstTrack = pstNewTrack; } } } } } } } /* Done! */ return eResult; }
/** Updates the FXPointer (Callback for generic structure update calling) * @param[in] _pstStructure Generic Structure or the concerned Body * @param[in] _pstCaller Structure of the caller * @param[in] _pstClockInfo Clock info used for time updates * @return orxSTATUS_SUCCESS / orxSTATUS_FAILURE */ static orxSTATUS orxFASTCALL orxFXPointer_Update(orxSTRUCTURE *_pstStructure, const orxSTRUCTURE *_pstCaller, const orxCLOCK_INFO *_pstClockInfo) { orxFXPOINTER *pstFXPointer; orxOBJECT *pstObject; orxSTATUS eResult = orxSTATUS_SUCCESS; /* Profiles */ orxPROFILER_PUSH_MARKER("orxFXPointer_Update"); /* Checks */ orxASSERT(sstFXPointer.u32Flags & orxFXPOINTER_KU32_STATIC_FLAG_READY); orxSTRUCTURE_ASSERT(_pstStructure); orxSTRUCTURE_ASSERT(_pstCaller); /* Gets FXPointer */ pstFXPointer = orxFXPOINTER(_pstStructure); /* Gets calling object */ pstObject = orxOBJECT(_pstCaller); /* Is enabled? */ if(orxFXPointer_IsEnabled(pstFXPointer) != orxFALSE) { orxFLOAT fLastTime; orxU32 i; orxSTRUCTURE *pstOwner; /* Gets owner */ pstOwner = orxStructure_GetOwner(pstFXPointer); /* Backups last time */ fLastTime = pstFXPointer->fTime; /* Computes its new time cursor */ pstFXPointer->fTime += _pstClockInfo->fDT; /* For all FXs */ for(i = 0; i < orxFXPOINTER_KU32_FX_NUMBER; i++) { orxFX *pstFX; /* Gets FX */ pstFX = pstFXPointer->astFXList[i].pstFX; /* Valid? */ if(pstFX != orxNULL) { orxFLOAT fFXLocalStartTime, fFXLocalEndTime; /* Gets FX local times */ fFXLocalStartTime = fLastTime - pstFXPointer->astFXList[i].fStartTime; fFXLocalEndTime = pstFXPointer->fTime - pstFXPointer->astFXList[i].fStartTime; /* Is the FX reached? */ if(fFXLocalEndTime >= orxFLOAT_0) { /* Is the first time? */ if(!orxFLAG_TEST(pstFXPointer->astFXList[i].u32Flags, orxFXPOINTER_HOLDER_KU32_FLAG_PLAYED)) { orxFX_EVENT_PAYLOAD stPayload; /* Inits event payload */ orxMemory_Zero(&stPayload, sizeof(orxFX_EVENT_PAYLOAD)); stPayload.pstFX = pstFX; stPayload.zFXName = orxFX_GetName(pstFX); /* Sends event */ orxEVENT_SEND(orxEVENT_TYPE_FX, orxFX_EVENT_START, pstOwner, pstOwner, &stPayload); } /* Updates its status */ orxFLAG_SET(pstFXPointer->astFXList[i].u32Flags, orxFXPOINTER_HOLDER_KU32_FLAG_PLAYED, orxFXPOINTER_HOLDER_KU32_FLAG_NONE); /* Applies FX from last time to now */ if(orxFX_Apply(pstFX, pstObject, fFXLocalStartTime, fFXLocalEndTime) == orxSTATUS_FAILURE) { orxFX_EVENT_PAYLOAD stPayload; /* Inits event payload */ orxMemory_Zero(&stPayload, sizeof(orxFX_EVENT_PAYLOAD)); stPayload.pstFX = pstFX; stPayload.zFXName = orxFX_GetName(pstFX); /* Is a looping FX? */ if(orxFX_IsLooping(pstFX) != orxFALSE) { /* Sends event */ orxEVENT_SEND(orxEVENT_TYPE_FX, orxFX_EVENT_LOOP, pstOwner, pstOwner, &stPayload); /* Updates its start time */ pstFXPointer->astFXList[i].fStartTime = pstFXPointer->fTime; } else { /* Decreases its reference counter */ orxStructure_DecreaseCounter(pstFX); /* Removes its reference */ pstFXPointer->astFXList[i].pstFX = orxNULL; /* Sends event */ orxEVENT_SEND(orxEVENT_TYPE_FX, orxFX_EVENT_STOP, pstOwner, pstOwner, &stPayload); /* Sends event */ orxEVENT_SEND(orxEVENT_TYPE_FX, orxFX_EVENT_REMOVE, pstOwner, pstOwner, &stPayload); /* Is internal? */ if(orxFLAG_TEST(pstFXPointer->astFXList[i].u32Flags, orxFXPOINTER_HOLDER_KU32_FLAG_INTERNAL)) { /* Removes its owner */ orxStructure_SetOwner(pstFX, orxNULL); /* Deletes it */ orxFX_Delete(pstFX); } } } } } } } /* Profiles */ orxPROFILER_POP_MARKER(); /* Done! */ return eResult; }
/** Adds a sound using its config ID * @param[in] _pstSoundPointer Concerned SoundPointer * @param[in] _zSoundConfigID Config ID of the sound to add * @return orxSTATUS_SUCCESS / orxSTATUS_FAILURE */ orxSTATUS orxFASTCALL orxSoundPointer_AddSoundFromConfig(orxSOUNDPOINTER *_pstSoundPointer, const orxSTRING _zSoundConfigID) { orxU32 u32Index; orxSTATUS eResult; /* Checks */ orxASSERT(sstSoundPointer.u32Flags & orxSOUNDPOINTER_KU32_STATIC_FLAG_READY); orxSTRUCTURE_ASSERT(_pstSoundPointer); orxASSERT((_zSoundConfigID != orxNULL) && (_zSoundConfigID != orxSTRING_EMPTY)); /* Finds an empty slot */ for(u32Index = 0; (u32Index < orxSOUNDPOINTER_KU32_SOUND_NUMBER) && (_pstSoundPointer->astSoundList[u32Index].pstSound != orxNULL); u32Index++); /* Not found? */ if(u32Index == orxSOUNDPOINTER_KU32_SOUND_NUMBER) { orxFLOAT fShortestDuration; orxU32 u32ShortestIndex; /* Logs message */ orxDEBUG_PRINT(orxDEBUG_LEVEL_SOUND, "No free slot to play sound <%s>, replacing shortest one.", _zSoundConfigID); /* Gets first index */ u32ShortestIndex = (_pstSoundPointer->u32LastAddedIndex == 0) ? 1 : 0; /* Gets its duration */ fShortestDuration = orxSound_GetDuration(_pstSoundPointer->astSoundList[u32ShortestIndex].pstSound); /* For all other sounds */ for(u32Index = u32ShortestIndex + 1; (u32Index < orxSOUNDPOINTER_KU32_SOUND_NUMBER); u32Index++) { /* Not the latest added one? */ if(u32Index != _pstSoundPointer->u32LastAddedIndex) { orxFLOAT fDuration; /* Gets its duration */ fDuration = orxSound_GetDuration(_pstSoundPointer->astSoundList[u32Index].pstSound); /* Shorter? */ if(fDuration < fShortestDuration) { /* Selects it */ u32ShortestIndex = u32Index; } } } /* Removes it */ orxSoundPointer_RemoveSound(_pstSoundPointer, _pstSoundPointer->astSoundList[u32ShortestIndex].pstSound); /* Updates index */ u32Index = u32ShortestIndex; } /* Found? */ if(u32Index < orxSOUNDPOINTER_KU32_SOUND_NUMBER) { orxSOUND *pstSound; /* Creates sound */ pstSound = orxSound_CreateFromConfig(_zSoundConfigID); /* Valid? */ if(pstSound != orxNULL) { orxSOUND_EVENT_PAYLOAD stPayload; orxOBJECT *pstOwner; /* Increases its reference counter */ orxStructure_IncreaseCounter(pstSound); /* Adds it to holder */ _pstSoundPointer->astSoundList[u32Index].pstSound = pstSound; /* Updates its owner */ orxStructure_SetOwner(pstSound, _pstSoundPointer); /* Updates its flags */ orxFLAG_SET(_pstSoundPointer->astSoundList[u32Index].u32Flags, orxSOUNDPOINTER_HOLDER_KU32_FLAG_INTERNAL | orxSOUNDPOINTER_HOLDER_KU32_FLAG_AUTO_PLAY, orxSOUNDPOINTER_HOLDER_KU32_MASK_ALL); /* Stores it as last added sound */ _pstSoundPointer->u32LastAddedIndex = u32Index; /* Gets its owner object */ pstOwner = orxOBJECT(orxStructure_GetOwner(_pstSoundPointer)); /* Valid? */ if(pstOwner != orxNULL) { orxVECTOR vPosition; /* Updates its position */ orxSound_SetPosition(pstSound, orxObject_GetWorldPosition(pstOwner, &vPosition)); } /* Inits event payload */ orxMemory_Zero(&stPayload, sizeof(orxSOUND_EVENT_PAYLOAD)); stPayload.pstSound = pstSound; /* Sends event */ orxEVENT_SEND(orxEVENT_TYPE_SOUND, orxSOUND_EVENT_ADD, pstOwner, pstOwner, &stPayload); /* Updates result */ eResult = orxSTATUS_SUCCESS; } else { /* Logs message */ orxDEBUG_PRINT(orxDEBUG_LEVEL_SOUND, "Could not find object named '%s' in config.", _zSoundConfigID); /* Clears last added sound index */ _pstSoundPointer->u32LastAddedIndex = orxU32_UNDEFINED; /* Updates result */ eResult = orxSTATUS_FAILURE; } } else { /* Logs message */ orxDEBUG_PRINT(orxDEBUG_LEVEL_SOUND, "Failed to find an empty slot to put sound <%s> into.", _zSoundConfigID); /* Updates result */ eResult = orxSTATUS_FAILURE; } /* Done! */ return eResult; }
/** Updates the TimeLine (Callback for generic structure update calling) * @param[in] _pstStructure Generic Structure or the concerned Body * @param[in] _pstCaller Structure of the caller * @param[in] _pstClockInfo Clock info used for time updates * @return orxSTATUS_SUCCESS / orxSTATUS_FAILURE */ static orxSTATUS orxFASTCALL orxTimeLine_Update(orxSTRUCTURE *_pstStructure, const orxSTRUCTURE *_pstCaller, const orxCLOCK_INFO *_pstClockInfo) { orxTIMELINE *pstTimeLine; orxSTATUS eResult = orxSTATUS_SUCCESS; /* Profiles */ orxPROFILER_PUSH_MARKER("orxTimeLine_Update"); /* Checks */ orxASSERT(sstTimeLine.u32Flags & orxTIMELINE_KU32_STATIC_FLAG_READY); orxSTRUCTURE_ASSERT(_pstStructure); orxSTRUCTURE_ASSERT(_pstCaller); /* Gets TimeLine */ pstTimeLine = orxTIMELINE(_pstStructure); /* Is enabled? */ if(orxTimeLine_IsEnabled(pstTimeLine) != orxFALSE) { orxU32 i; /* Cleans its flags */ orxStructure_SetFlags(pstTimeLine, orxTIMELINE_KU32_FLAG_NONE, orxTIMELINE_KU32_FLAG_DIRTY); /* Has clock info? */ if(_pstClockInfo != orxNULL) { /* Computes its new time cursor */ pstTimeLine->fTime += _pstClockInfo->fDT; } /* For all tracks */ for(i = 0; i < orxTIMELINE_KU32_TRACK_NUMBER; i++) { orxTIMELINE_TRACK *pstTrack; /* Is timeline dirty? */ if(orxStructure_TestFlags(pstTimeLine, orxTIMELINE_KU32_FLAG_DIRTY)) { orxU32 j; /* For all previous tracks */ for(j = 0; j < i; j++) { /* Is defined? */ if(pstTimeLine->astTrackList[j].pstTrack != orxNULL) { /* Hasn't been updated? */ if(!orxFLAG_TEST(pstTimeLine->astTrackList[j].u32Flags, orxTIMELINE_HOLDER_KU32_FLAG_UPDATED)) { /* Selects it */ i = j; break; } } } } /* Gets track */ pstTrack = pstTimeLine->astTrackList[i].pstTrack; /* Valid and not already updated? */ if((pstTrack != orxNULL) && (!orxFLAG_TEST(pstTimeLine->astTrackList[i].u32Flags, orxTIMELINE_HOLDER_KU32_FLAG_UPDATED))) { orxFLOAT fTrackLocalTime; /* Gets track local time */ fTrackLocalTime = pstTimeLine->fTime - pstTimeLine->astTrackList[i].fStartTime; /* Has time come? */ if(fTrackLocalTime >= orxFLOAT_0) { orxTIMELINE_EVENT_PAYLOAD stPayload; orxU32 u32EventIndex; /* Is the first time? */ if(!orxFLAG_TEST(pstTimeLine->astTrackList[i].u32Flags, orxTIMELINE_HOLDER_KU32_FLAG_PLAYED)) { /* Inits event payload */ orxMemory_Zero(&stPayload, sizeof(orxTIMELINE_EVENT_PAYLOAD)); stPayload.pstTimeLine = pstTimeLine; stPayload.zTrackName = pstTrack->zReference; /* Sends event */ orxEVENT_SEND(orxEVENT_TYPE_TIMELINE, orxTIMELINE_EVENT_TRACK_START, _pstCaller, _pstCaller, &stPayload); } /* Updates its status */ orxFLAG_SET(pstTimeLine->astTrackList[i].u32Flags, orxTIMELINE_HOLDER_KU32_FLAG_PLAYED | orxTIMELINE_HOLDER_KU32_FLAG_UPDATED, orxTIMELINE_HOLDER_KU32_FLAG_NONE); /* Inits event payload */ orxMemory_Zero(&stPayload, sizeof(orxTIMELINE_EVENT_PAYLOAD)); stPayload.pstTimeLine = pstTimeLine; stPayload.zTrackName = pstTrack->zReference; /* For all recently past events */ for(u32EventIndex = pstTimeLine->astTrackList[i].u32NextEventIndex; (u32EventIndex < pstTrack->u32EventCounter) && (fTrackLocalTime >= pstTrack->astEventList[u32EventIndex].fTimeStamp); u32EventIndex++) { /* Updates payload */ stPayload.zEvent = pstTrack->astEventList[u32EventIndex].zEventText; stPayload.fTimeStamp = pstTrack->astEventList[u32EventIndex].fTimeStamp; /* Sends event */ orxEVENT_SEND(orxEVENT_TYPE_TIMELINE, orxTIMELINE_EVENT_TRIGGER, _pstCaller, _pstCaller, &stPayload); } /* Is over? */ if(u32EventIndex >= pstTrack->u32EventCounter) { orxTIMELINE_TRACK *pstTrack; /* Gets track */ pstTrack = pstTimeLine->astTrackList[i].pstTrack; /* Inits event payload */ orxMemory_Zero(&stPayload, sizeof(orxTIMELINE_EVENT_PAYLOAD)); stPayload.pstTimeLine = pstTimeLine; stPayload.zTrackName = pstTrack->zReference; /* Is a looping track? */ if(orxFLAG_TEST(pstTrack->u32Flags, orxTIMELINE_TRACK_KU32_FLAG_LOOP)) { /* Sends event */ orxEVENT_SEND(orxEVENT_TYPE_TIMELINE, orxTIMELINE_EVENT_LOOP, _pstCaller, _pstCaller, &stPayload); /* Resets track */ pstTimeLine->astTrackList[i].u32NextEventIndex = 0; pstTimeLine->astTrackList[i].fStartTime = pstTimeLine->fTime; } else { /* Sends event */ orxEVENT_SEND(orxEVENT_TYPE_TIMELINE, orxTIMELINE_EVENT_TRACK_STOP, _pstCaller, _pstCaller, &stPayload); /* Removes its reference */ pstTimeLine->astTrackList[i].pstTrack = orxNULL; /* Sends event */ orxEVENT_SEND(orxEVENT_TYPE_TIMELINE, orxTIMELINE_EVENT_TRACK_REMOVE, _pstCaller, _pstCaller, &stPayload); /* Deletes it */ orxTimeLine_DeleteTrack(pstTrack); } } else { /* Updates next event index */ pstTimeLine->astTrackList[i].u32NextEventIndex = u32EventIndex; } } } } /* For all tracks */ for(i = 0; i < orxTIMELINE_KU32_TRACK_NUMBER; i++) { /* Clears its update flag */ orxFLAG_SET(pstTimeLine->astTrackList[i].u32Flags, orxTIMELINE_HOLDER_KU32_FLAG_NONE, orxTIMELINE_HOLDER_KU32_FLAG_UPDATED); } } /* Profiles */ orxPROFILER_POP_MARKER(); /* Done! */ return eResult; }
/** Updates the SoundPointer (Callback for generic structure update calling) * @param[in] _pstStructure Generic Structure or the concerned Body * @param[in] _pstCaller Structure of the caller * @param[in] _pstClockInfo Clock info used for time updates * @return orxSTATUS_SUCCESS / orxSTATUS_FAILURE */ static orxSTATUS orxFASTCALL orxSoundPointer_Update(orxSTRUCTURE *_pstStructure, const orxSTRUCTURE *_pstCaller, const orxCLOCK_INFO *_pstClockInfo) { orxSOUNDPOINTER *pstSoundPointer; orxSTATUS eResult = orxSTATUS_SUCCESS; /* Profiles */ orxPROFILER_PUSH_MARKER("orxSoundPointer_Update"); /* Checks */ orxASSERT(sstSoundPointer.u32Flags & orxSOUNDPOINTER_KU32_STATIC_FLAG_READY); orxSTRUCTURE_ASSERT(_pstStructure); orxSTRUCTURE_ASSERT(_pstCaller); /* Gets sound pointer */ pstSoundPointer = orxSOUNDPOINTER(_pstStructure); /* Is enabled? */ if(orxSoundPointer_IsEnabled(pstSoundPointer) != orxFALSE) { orxU32 i; /* For all Sounds */ for(i = 0; i < orxSOUNDPOINTER_KU32_SOUND_NUMBER; i++) { orxSOUND *pstSound; /* Gets sound */ pstSound = pstSoundPointer->astSoundList[i].pstSound; /* Valid? */ if(pstSound != orxNULL) { /* Should auto play? */ if(orxFLAG_TEST(pstSoundPointer->astSoundList[i].u32Flags, orxSOUNDPOINTER_HOLDER_KU32_FLAG_AUTO_PLAY)) { /* Plays it */ orxSound_Play(pstSound); /* Updates its flags */ orxFLAG_SET(pstSoundPointer->astSoundList[i].u32Flags, orxSOUNDPOINTER_HOLDER_KU32_FLAG_NONE, orxSOUNDPOINTER_HOLDER_KU32_FLAG_AUTO_PLAY); } /* Delegates update to the sound */ orxStructure_Update(pstSound, _pstCaller, _pstClockInfo); /* Is sound stopped? */ if(orxSound_GetStatus(pstSound) == orxSOUND_STATUS_STOP) { /* Removes it */ orxSoundPointer_RemoveSound(pstSoundPointer, pstSound); } } } } /* Profiles */ orxPROFILER_POP_MARKER(); /* Done! */ return eResult; }
/** Event handler */ static orxSTATUS orxFASTCALL orxSoundPointer_EventHandler(const orxEVENT *_pstEvent) { orxSTATUS eResult = orxSTATUS_SUCCESS; /* Depending on event ID */ switch(_pstEvent->eID) { /* Pause / disable */ case orxOBJECT_EVENT_PAUSE: case orxOBJECT_EVENT_DISABLE: { orxSOUNDPOINTER *pstSoundPointer; /* Gets sound pointer */ pstSoundPointer = orxOBJECT_GET_STRUCTURE(orxOBJECT(_pstEvent->hSender), SOUNDPOINTER); /* Valid? */ if(pstSoundPointer != orxNULL) { orxU32 i; /* For all Sounds */ for(i = 0; i < orxSOUNDPOINTER_KU32_SOUND_NUMBER; i++) { /* Valid? */ if(pstSoundPointer->astSoundList[i].pstSound != orxNULL) { /* Is playing? */ if(orxSound_GetStatus(pstSoundPointer->astSoundList[i].pstSound) == orxSOUND_STATUS_PLAY) { /* Pauses it */ orxSound_Pause(pstSoundPointer->astSoundList[i].pstSound); /* Updates its status */ orxFLAG_SET(pstSoundPointer->astSoundList[i].u32Flags, orxSOUNDPOINTER_HOLDER_KU32_FLAG_AUTO_PAUSE, orxSOUNDPOINTER_HOLDER_KU32_FLAG_NONE); /* Delegates update to the sound */ orxStructure_Update(pstSoundPointer->astSoundList[i].pstSound, orxStructure_GetOwner(pstSoundPointer), orxNULL); } } } } break; } /* Unpause / enable */ case orxOBJECT_EVENT_UNPAUSE: case orxOBJECT_EVENT_ENABLE: { orxSOUNDPOINTER *pstSoundPointer; /* Gets sound pointer */ pstSoundPointer = orxOBJECT_GET_STRUCTURE(orxOBJECT(_pstEvent->hSender), SOUNDPOINTER); /* Valid? */ if(pstSoundPointer != orxNULL) { orxU32 i; /* For all Sounds */ for(i = 0; i < orxSOUNDPOINTER_KU32_SOUND_NUMBER; i++) { /* Valid? */ if(pstSoundPointer->astSoundList[i].pstSound != orxNULL) { /* Is auto-paused? */ if(orxFLAG_TEST(pstSoundPointer->astSoundList[i].u32Flags, orxSOUNDPOINTER_HOLDER_KU32_FLAG_AUTO_PAUSE)) { /* Resumes it */ orxSound_Play(pstSoundPointer->astSoundList[i].pstSound); /* Updates its status */ orxFLAG_SET(pstSoundPointer->astSoundList[i].u32Flags, orxSOUNDPOINTER_HOLDER_KU32_FLAG_NONE, orxSOUNDPOINTER_HOLDER_KU32_FLAG_AUTO_PAUSE); /* Delegates update to the sound */ orxStructure_Update(pstSoundPointer->astSoundList[i].pstSound, orxStructure_GetOwner(pstSoundPointer), orxNULL); } } } } break; } default: { break; } } /* Done! */ return eResult; }
/** Inits the event module * @return orxSTATUS_SUCCESS / orxSTATUS_FAILURE */ orxSTATUS orxFASTCALL orxEvent_Init() { orxSTATUS eResult = orxSTATUS_FAILURE; /* Not already Initialized? */ if(!orxFLAG_TEST(sstEvent.u32Flags, orxEVENT_KU32_STATIC_FLAG_READY)) { /* Cleans control structure */ orxMemory_Zero(&sstEvent, sizeof(orxEVENT_STATIC)); /* Creates handler storage table */ sstEvent.pstHandlerStorageTable = orxHashTable_Create(orxEVENT_KU32_HANDLER_TABLE_SIZE, orxHASHTABLE_KU32_FLAG_NONE, orxMEMORY_TYPE_MAIN); /* Success? */ if(sstEvent.pstHandlerStorageTable != orxNULL) { /* Creates handler storage bank */ sstEvent.pstHandlerStorageBank = orxBank_Create(orxEVENT_KU32_STORAGE_BANK_SIZE, sizeof(orxEVENT_HANDLER_STORAGE), orxBANK_KU32_FLAG_NONE, orxMEMORY_TYPE_MAIN); /* Success? */ if(sstEvent.pstHandlerStorageBank != orxNULL) { /* Inits Flags */ orxFLAG_SET(sstEvent.u32Flags, orxEVENT_KU32_STATIC_FLAG_READY, orxEVENT_KU32_STATIC_MASK_ALL); /* Success */ eResult = orxSTATUS_SUCCESS; } else { /* Deletes table */ orxHashTable_Delete(sstEvent.pstHandlerStorageTable); /* Logs message */ orxDEBUG_PRINT(orxDEBUG_LEVEL_SYSTEM, "Event module failed to create bank."); /* Updates result */ eResult = orxSTATUS_FAILURE; } } else { /* Logs message */ orxDEBUG_PRINT(orxDEBUG_LEVEL_SYSTEM, "Event module failed to create hash table."); /* Updates result */ eResult = orxSTATUS_FAILURE; } } else { /* Logs message */ orxDEBUG_PRINT(orxDEBUG_LEVEL_SYSTEM, "Event module already loaded."); /* Already initialized */ eResult = orxSTATUS_SUCCESS; } /* Done! */ return eResult; }