// HACK HACK HACK - We must guarantee the thread safety of both this Step function and // // Perform all of the selectors on the pipeline. // // elapsed - time elapsed since the last step. void hdAnimationController::StepWithInterval(hdTimeInterval elapsed) { if (m_pipelineCount > 0) { int p = 0; #ifdef ANIMATION_DEBUG hdPrintf("Pipeline Step: %d animations requiring steps\n", m_pipelineCount); #endif p = m_pipelineCount; m_pipelineCount = 0; memcpy(m_HACKHACKHACK_tmpPipeline, m_pipeline, sizeof(hdAnimation*) * p); memset(m_pipeline, 0, sizeof(m_pipeline)); for(int i = 0; i < p; ++i) { hdAnimation* receiver = m_HACKHACKHACK_tmpPipeline[i]; if (receiver != NULL && receiver->m_id >= -1 && receiver->m_id <= kPipelineSize && (receiver->GetStatus() == e_animationRunning || receiver->GetStatus() == e_animationPaused)) { receiver->Step(elapsed); } else { #ifdef ANIMATION_DEBUG hdPrintf("### NULL Pointer in pipeline at %d\n", i); #endif } } } }
bool hdGameWorld::AddGameObject(hdGameObject* gameObject) { hdAssert(m_lock == false); if (m_lock == true) { return false; } // What if we already have the game object? if (this->ContainsGameObject(gameObject)) return false; #if TARGET_OS_MAC hdPrintf("Adding Game Object: %d Type: %d\n", gameObject, gameObject->GetUserType()); #else hdPrintf("Adding Game Object: %d Type: %d\n", gameObject, gameObject->GetUserType()); #endif gameObject->m_prev = NULL; gameObject->m_next = m_gameObjectList; if (m_gameObjectList) { m_gameObjectList->m_prev = gameObject; } m_gameObjectList = gameObject; ++m_gameObjectCount; return true; }
void GameController::AnimateLostBlockNotification(Block* block) { hdVec2 screenPos; hdVec3 aa; Polygon* notification = new Polygon(NULL, "Interface/Textures/imgBlockLost.png"); notification->SetRelative(block); notification->SetAlpha(0.0f); notification->SetUpdateCallback(this, GameController::HandleNotificationUpdateCallback); ConvertInterfaceToScreen(screenPos, block->GetWorldCenter().x, block->GetWorldCenter().y); aa.Set(screenPos.x - 35.0f, screenPos.y + 30.0f, 0.0f); notification->SetAs2DBox(aa, aa+hdVec3(70, 35, 0)); if (-1 == m_notificationPolygons->Add(notification)) { hdPrintf("Could not add notification to polygon list: not enough room in list.\n"); delete notification; return; } hdPrintf("[F] AnimateLostBlockNotification: %d\n", notification); AnimateFadeInOut(notification, 0.5f, 0.75f, 0.5f); hdAnimation* funcAnim = hdAnimationController::CreateAnimation(this); hdFunctionAction<Polygon>* funcAction = new hdFunctionAction<Polygon>(); funcAction->SetDuration(1.75f); funcAction->SetFunctionObject(notification); funcAction->SetFunction(&Polygon::DoUpdateCallback); funcAnim->AddGameObject(notification); funcAnim->AddAction(funcAction); funcAnim->SetFinishedCallback(this, GameController::LostBlockNotificationCallback); funcAnim->StartAnimation(); }
void Scripts_LoadStringsFile(const char *stringsFilePath) { std::string line; size_t pos; filehandle_t *hnd; stringTable.clear(); // Matchings std::smatch matchings; // string line pattern: $Key "$Value" std::regex stringLinePattern("^\\s*([^[:space:]]+)\\s+[\"](.+)[\"]$"); if (NULL == (hnd = FileSystem_OpenFile(stringsFilePath, 0))) { hdPrintf("Could not load strings file: %s\n", stringsFilePath); return; } std::istringstream iss((char *)hnd->filedata); if (!iss.good()) { hdPrintf("Could not load strings file: %s\n", stringsFilePath); return; } // Parse line by line while(!iss.eof()) { getline(iss, line); if (std::regex_match(line, matchings, stringLinePattern)) { hdAssert(line == matchings[0]); hdAssert(3 == matchings.size()); // New line hack std::string s(matchings[2]); while((pos = s.find("\\n")) != std::string::npos) { s.replace(pos, 2, 1, '\n'); } stringTable[matchings[1]] = s; } } FileSystem_CloseFile(hnd); stringsFileWasLoaded = true; }
hdTexture* hdTextureManager::FindTexture(const char* name, texturetype_t type) { hdTexture *tex; unsigned char *data; unsigned short width, height; unsigned short bytes; if (name == NULL) return NULL; if (strlen(name) == 0) return NULL; for (int i = 0; i < m_textures->GetItemCount(); i++) { if (strncmp(m_textures->GetItems()[i]->name, name, kMaxTexturePathSize) == 0) { return (hdTexture*)m_textures->GetItems()[i]; } } hdPrintf("[hdTextureManager] Looking for texture file: %s\n", name); if (std::string(name).find(std::string(".tga")) != std::string::npos) { LoadTGA( name, &data, &width, &height, &bytes ); if ( data ) { tex = this->LoadTexture( name, data, width, height, type, bytes ); free( data ); return tex; } } if (std::string(name).find(std::string(".png")) != std::string::npos) { LoadPNG( name, &data, &width, &height, &bytes ); if ( data ) { tex = this->LoadTexture( name, data, width, height, type, bytes ); #if TARGET_OS_IPHONE == 1 || TARGET_IPHONE_SIMULATOR == 1 tex->isPremultipliedAlpha = true; #endif free( data ); return tex; } } hdPrintf("[hdTextureManager] ERROR: could not find texture file: %s\n", name); return m_nullTexture; }
void Scripts_LoadScript(const char *scriptfilepath, int worldId) { hdAssert(currentCache != NULL); if (strcmp(scriptfilepath, currentWorldFilePath) == 0) { hdPrintf("[SCRIPTING] Scripts file already loaded for world: %s\n", scriptfilepath); return; } s_worldId = worldId; hdPrintf("[SCRIPTING] Loading script file: %s\n", scriptfilepath); snprintf(currentWorldFilePath, 256, "%s", scriptfilepath); currentCache->RemoveAll(); ParseWorldMessageScript(scriptfilepath); }
AppController::~AppController() { if (introController != NULL) { hdPrintf("\t*** Delete intro controller\n"); delete introController; introController = NULL; } if (menuController != NULL) { hdPrintf("\t*** Delete menu controller\n"); delete menuController; menuController = NULL; } if (gameController != NULL) { hdPrintf("\t*** Delete game controller\n"); delete gameController; gameController = NULL; } if (levelPickerController != NULL) { hdPrintf("\t*** Delete level picker controller\n"); delete levelPickerController; levelPickerController = NULL; } Scripts_TearDown(); hdSoundManager::TearDown(); hdFontManager::TearDown(); hdTextureManager::TearDown(); hdAnimationController::TearDown(); WorldManager::TearDown(); FileSystem_Teardown(); }
bool hdAnimationController::DeleteAnimationStep(const hdAnimation* animation, const int stepId) { if (stepId < 0 || stepId >= kPipelineSize) return false; if (m_pipeline[stepId] == NULL) return false; if (animation->GetStatus() == e_animationFinished || animation->GetStatus() == e_animationStopped) return false; if (m_pipeline[stepId] != animation) return false; #ifdef ANIMATION_DEBUG hdPrintf("\t\t[-] Delete anim step at %d with id of %d\n", animation, stepId); #endif m_pipeline[stepId] = NULL; return true; }
void hdAnimationController::AddAnimationStep(const hdAnimation* animation, int* stepId) { if (animation == NULL) return; if (animation->GetStatus() == e_animationFinished || animation->GetStatus() == e_animationStopped) return; *stepId = m_pipelineCount; #ifdef ANIMATION_DEBUG hdPrintf("\t\t[+] Added anim step at %d with id of %d\n", animation, *stepId); #endif m_pipeline[m_pipelineCount] = (hdAnimation *)animation; ++m_pipelineCount; }
void GameController::LostBlockNotificationCallback(void *handler, hdAnimation *anim) { // Need to avoid dangling pointer problems here otherwise program will crash horribly. if (handler == NULL || anim == NULL) return; hdPrintf("[F] LostBlockNotificationCallback\n"); GameController *self = (GameController *)handler; if (anim->GetGameObjectCount() == 0) return; Polygon* poly = (Polygon*)(anim->GetGameObject(0)); if (poly == NULL) return; self->m_notificationPolygons->Remove(poly); }
extern int hdglGenTextureFrameBuffer(const hdTexture *texture) { GLuint fbo, status; glGenFramebuffersOES(1, &fbo); glBindFramebufferOES(GL_FRAMEBUFFER_OES, fbo); glFramebufferTexture2DOES(GL_FRAMEBUFFER_OES, GL_COLOR_ATTACHMENT0_OES, GL_TEXTURE_2D, texture->texnum, 0); status = glCheckFramebufferStatusOES(GL_FRAMEBUFFER_OES); if (status != GL_FRAMEBUFFER_COMPLETE_OES) { hdPrintf("Could not create frame buffer."); return -1; } else { return fbo; } }
void hdAlphaAction::Apply(hdTimeInterval elapsed, hdGameObject* gameObject) { float current; if (m_endAlpha > m_startAlpha) { current = (m_endAlpha - m_startAlpha) * ((m_progress) / m_duration); } else { current = 1.0f + (m_endAlpha - m_startAlpha) * ((m_progress) / m_duration); } current = hdClamp(current, 0.0f, 1.0f); gameObject->SetAlpha(current); #ifdef ANIMATION_DEBUG hdPrintf("Alpha Action:: Name: %d, Progress: %f, Elapsed: %f, New Alpha: %f\n", gameObject->GetName(), m_progress, elapsed, (float)current); #endif }
bool hdGameWorld::RemoveGameObject(hdGameObject* gameObject) { hdAssert(m_lock == false); if (m_lock == true) { return false; } // What if the pointer is retained somewhere else? // Well, we f*****g have to deal with it don't we! // Makes removing, on average, an O(nlogn) algo rather // than O(n). F**k. if (!this->ContainsGameObject(gameObject)) return false; hdAssert(m_gameObjectCount > 0); hdPrintf("Removing Game Object: %d\n", gameObject); if (gameObject->m_prev) { gameObject->m_prev->m_next = gameObject->m_next; } if (gameObject->m_next) { gameObject->m_next->m_prev = gameObject->m_prev; } if (gameObject == m_gameObjectList) { m_gameObjectList = gameObject->m_next; } gameObject->SetWorld(NULL); --m_gameObjectCount; return true; }
void hdScaleAction::Apply(hdTimeInterval elapsed, hdGameObject* gameObject) { hdAssert(m_duration >= 0.0); hdAssert(elapsed > 0.0); hdVec3 current = gameObject->GetTransform().scale; hdVec3 identity = hdVec3(1.0, 1.0, 1.0); hdVec3 step = m_scale; step -= identity; // Work out original scale: vecOrig = vecCur/(1+(scale * progress)) fixed32 xOrig = current.x * (1.0 / (1.0 + (step.x * ((m_progress - elapsed) / m_duration)))); fixed32 yOrig = current.y * (1.0 / (1.0 + (step.y * ((m_progress - elapsed) / m_duration)))); fixed32 zOrig = current.z * (1.0 / (1.0 + (step.z * ((m_progress - elapsed) / m_duration)))); hdVec3 scale0 = hdVec3(xOrig, yOrig, zOrig); // Multiply the step factor by the current progress. step *= (m_progress / m_duration); scale0.x = scale0.x + (scale0.x * step.x); scale0.y = scale0.y + (scale0.y * step.y); scale0.z = scale0.z + (scale0.z * step.z); hdVec3 center = gameObject->GetWorldCenter(); hdTranslateVertices(gameObject->GetVertices(), gameObject->GetVertexCount(), -center); hdScaleVertices(gameObject->GetVertices(), gameObject->GetVertexCount(), scale0); hdTranslateVertices(gameObject->GetVertices(), gameObject->GetVertexCount(), center); gameObject->GetTransform().scale = scale0; gameObject->ResetAABB(); #ifdef ANIMATION_DEBUG hdPrintf("Name: %d, Elapsed: %f, Scaled to: %f, %f, %f\n", gameObject->GetName(), elapsed, (float)scale0.x, (float)scale0.y, (float)scale0.z); #endif }
void* MyGetOpenALAudioData(CFURLRef inFileURL, ALsizei *outDataSize, ALenum *outDataFormat, ALsizei *outSampleRate, ALdouble *duration) { OSStatus err = noErr; SInt64 theFileLengthInFrames = 0; AudioStreamBasicDescription theFileFormat; UInt32 thePropertySize = sizeof(theFileFormat); ExtAudioFileRef extRef = NULL; void* theData = NULL; AudioStreamBasicDescription theOutputFormat; // Open a file with ExtAudioFileOpen() err = ExtAudioFileOpenURL(inFileURL, &extRef); if(err) { hdPrintf("MyGetOpenALAudioData: ExtAudioFileOpenURL FAILED, Error = %ld\n", err); goto Exit; } // Get the audio data format err = ExtAudioFileGetProperty(extRef, kExtAudioFileProperty_FileDataFormat, &thePropertySize, &theFileFormat); if(err) { hdPrintf("MyGetOpenALAudioData: ExtAudioFileGetProperty(kExtAudioFileProperty_FileDataFormat) FAILED, Error = %ld\n", err); goto Exit; } if (theFileFormat.mChannelsPerFrame > 2) { hdPrintf("MyGetOpenALAudioData - Unsupported Format, channel count is greater than stereo\n"); goto Exit; } // Set the client format to 16 bit signed integer (native-endian) data // Maintain the channel count and sample rate of the original source format theOutputFormat.mSampleRate = theFileFormat.mSampleRate; theOutputFormat.mChannelsPerFrame = theFileFormat.mChannelsPerFrame; theOutputFormat.mFormatID = kAudioFormatLinearPCM; theOutputFormat.mBytesPerPacket = 2 * theOutputFormat.mChannelsPerFrame; theOutputFormat.mFramesPerPacket = 1; theOutputFormat.mBytesPerFrame = 2 * theOutputFormat.mChannelsPerFrame; theOutputFormat.mBitsPerChannel = 16; theOutputFormat.mFormatFlags = kAudioFormatFlagsNativeEndian | kAudioFormatFlagIsPacked | kAudioFormatFlagIsSignedInteger; // Set the desired client (output) data format err = ExtAudioFileSetProperty(extRef, kExtAudioFileProperty_ClientDataFormat, sizeof(theOutputFormat), &theOutputFormat); if(err) { hdPrintf("MyGetOpenALAudioData: ExtAudioFileSetProperty(kExtAudioFileProperty_ClientDataFormat) FAILED, Error = %ld\n", err); goto Exit; } // Get the total frame count thePropertySize = sizeof(theFileLengthInFrames); err = ExtAudioFileGetProperty(extRef, kExtAudioFileProperty_FileLengthFrames, &thePropertySize, &theFileLengthInFrames); if(err) { hdPrintf("MyGetOpenALAudioData: ExtAudioFileGetProperty(kExtAudioFileProperty_FileLengthFrames) FAILED, Error = %ld\n", err); goto Exit; } // Read all the data into memory UInt32 dataSize = theFileLengthInFrames * theOutputFormat.mBytesPerFrame;; theData = malloc(dataSize); if (theData) { AudioBufferList theDataBuffer; theDataBuffer.mNumberBuffers = 1; theDataBuffer.mBuffers[0].mDataByteSize = dataSize; theDataBuffer.mBuffers[0].mNumberChannels = theOutputFormat.mChannelsPerFrame; theDataBuffer.mBuffers[0].mData = theData; // Read the data into an AudioBufferList err = ExtAudioFileRead(extRef, (UInt32*)&theFileLengthInFrames, &theDataBuffer); if(err == noErr) { // success *outDataSize = (ALsizei)dataSize; //*outDataFormat = (theOutputFormat.mChannelsPerFrame > 1) ? AL_FORMAT_STEREO16 : AL_FORMAT_MONO16; if(theOutputFormat.mBitsPerChannel == 8) *outDataFormat = (theOutputFormat.mChannelsPerFrame == 1) ? AL_FORMAT_MONO8 : AL_FORMAT_STEREO8; else if(theOutputFormat.mBitsPerChannel == 16) *outDataFormat = (theOutputFormat.mChannelsPerFrame == 1) ? AL_FORMAT_MONO16 : AL_FORMAT_STEREO16; *outSampleRate = (ALsizei)theOutputFormat.mSampleRate; } else { // failure free (theData); theData = NULL; // make sure to return NULL hdPrintf("MyGetOpenALAudioData: ExtAudioFileRead FAILED, Error = %ld\n", err); goto Exit; } } // Alex: get the file duration... // first, get the audioID for the file... AudioFileID audioID; UInt32 audioIDSize = sizeof(audioID); err = ExtAudioFileGetProperty(extRef, kExtAudioFileProperty_AudioFile, &audioIDSize, &audioID); if(err) { hdPrintf("MyGetOpenALAudioData: ExtAudioFileGetProperty(kExtAudioFileProperty_AudioFile) FAILED, Error = %ld\n", err); goto Exit; } //now the duration... double soundDuration; UInt32 durationSize = sizeof(soundDuration); err = AudioFileGetProperty(audioID, kAudioFilePropertyEstimatedDuration, &durationSize, &soundDuration); if(err) { hdPrintf("MyGetOpenALAudioData: AudioFileGetProperty(kAudioFilePropertyEstimatedDuration) FAILED, Error = %ld\n", err); goto Exit; } *duration = soundDuration; hdPrintf("Audio duration:%f secs.\n", soundDuration); Exit: // Dispose the ExtAudioFileRef, it is no longer needed if (extRef) ExtAudioFileDispose(extRef); return theData; }
// Buggy poor implentation of half of a packrat parser void ParseWorldMessageScript(const char* scriptfilepath) { std::string line; bool contextOpened; int currContextID; size_t pos; hdMessage msg; filehandle_t *hnd; contextOpened = false; if (NULL == (hnd = FileSystem_OpenFile(scriptfilepath, 0))) { hdPrintf("Could not load strings file: %s\n", scriptfilepath); return; } std::istringstream iss((char *)hnd->filedata); if (!iss.good()) { hdPrintf("Could not load scripts file: %s\n", scriptfilepath); return; } // ("LEVEL")(Spaces)(Digits)(Optional Scaces) std::regex contextLinePattern("^(LEVEL)\\s+(\\d+)\\s*$"); // ("TEXT")(Spaces)(Digits)(Spaces)("Anything") std::regex textLinePattern("^(TEXT)\\s+(\\d+)\\s+(.+)$"); // ("IMAGE")(Spaces)(Digits)(Spaces)("Anything") std::regex imageLinePattern("^(IMAGE)\\s+(\\d+)\\s+(.+)$"); // ("CUSTOMTEXT")(Spaces)(Digits)(Spaces)(@ImageTextureName)(Scaces)(@Message) std::regex customTextLinePattern("^(CUSTOMTEXT)\\s+(\\d+)\\s+([^[:space:]]+)\\s+[\"](.+)[\"]$"); // ("CUSTOMTEXT")(Spaces)(Digits)(Spaces)(@ImageTextureName)(Scaces)(@Message) std::regex avatarTextLinePattern("^(AVATARMESSAGE)\\s+(\\d+)\\s+([^[:space:]]+)\\s+[\"](.+)[\"]$"); // Matchings std::smatch matchings; // Parse line by line while(!iss.eof()) { getline(iss, line); if (std::regex_match(line, matchings, contextLinePattern)) { contextOpened = true; hdAssert(line == matchings[0]); hdAssert(matchings.size() == 3); std::string s(matchings[2]); currContextID = (int)strtol(s.c_str(), NULL, 0); } else if (std::regex_match(line, matchings, textLinePattern)) { if (!contextOpened) { hdPrintf("Scripts file malformed, bailing out: %s\n", scriptfilepath); break; } hdAssert(line == matchings[0]); hdAssert(4 == matchings.size()); msg.contextId = currContextID; msg.targetId = (int)strtol(std::string(matchings[2]).c_str(), NULL, 0); // New line hack std::string s(matchings[3]); while((pos = s.find("\\n")) != std::string::npos) { s.replace(pos, 2, 1, '\n'); } snprintf(msg.message, 256, "%s", s.c_str()); msg.messageType = e_hdMessageTypeText; if (HD_COLLECTIONS_ERROR_FULL == currentCache->Add(msg)) { hdPrintf("Script cache full, bailing out: %s\n", scriptfilepath); break; } } else if (std::regex_match(line, matchings, imageLinePattern)) { if (!contextOpened) { hdPrintf("Scripts file malformed, bailing out: %s\n", scriptfilepath); break; } hdAssert(line == matchings[0]); hdAssert(4 == matchings.size()); msg.contextId = currContextID; msg.targetId = (int)strtol(std::string(matchings[2]).c_str(), NULL, 0); snprintf(msg.texture, 256, "%s", std::string(matchings[3]).c_str()); msg.messageType = e_hdMessageTypeImage; if (HD_COLLECTIONS_ERROR_FULL == currentCache->Add(msg)) { hdPrintf("Script cache full, bailing out: %s\n", scriptfilepath); break; } } else if (std::regex_match(line, matchings, customTextLinePattern)) { if (!contextOpened) { hdPrintf("Scripts file malformed, bailing out: %s\n", scriptfilepath); break; } hdAssert(line == matchings[0]); hdAssert(5 == matchings.size()); msg.contextId = currContextID; msg.targetId = (int)strtol(std::string(matchings[2]).c_str(), NULL, 0); snprintf(msg.texture, 256, "%s", std::string(matchings[3]).c_str()); // New line hack std::string s(matchings[4]); while((pos = s.find("\\n")) != std::string::npos) { s.replace(pos, 2, 1, '\n'); } snprintf(msg.message, 256, "%s", s.c_str()); msg.messageType = e_hdMessageTypeCustomImageText; if (HD_COLLECTIONS_ERROR_FULL == currentCache->Add(msg)) { hdPrintf("Script cache full, bailing out: %s\n", scriptfilepath); break; } } else if (std::regex_match(line, matchings, avatarTextLinePattern)) { if (!contextOpened) { hdPrintf("Scripts file malformed, bailing out: %s\n", scriptfilepath); break; } hdAssert(line == matchings[0]); hdAssert(5 == matchings.size()); msg.contextId = currContextID; msg.targetId = (int)strtol(std::string(matchings[2]).c_str(), NULL, 0); snprintf(msg.texture, 256, "%s", std::string(matchings[3]).c_str()); // New line hack std::string s(matchings[4]); while((pos = s.find("\\n")) != std::string::npos) { s.replace(pos, 2, 1, '\n'); } snprintf(msg.message, 256, "%s", s.c_str()); msg.messageType = e_hdMessageTypeAvatar; if (HD_COLLECTIONS_ERROR_FULL == currentCache->Add(msg)) { hdPrintf("Script cache full, bailing out: %s\n", scriptfilepath); break; } } } FileSystem_CloseFile(hnd); }
Layer::~Layer() { hdPrintf("Deleting Layer\n"); m_polygons->RemoveAll(); delete m_polygons; }
void GameController::AnimateIcon(const char *iconTexture, const hdVec3& gamePosition, int position, bool drifts, float xWidth, float duration) { #define DRAW_ICONS_IN_GAMEWORLD 1 #if DRAW_ICONS_IN_GAMEWORLD == 1 hdVec2 origin, interfaceValues; hdUIImage *icon; float xOffset; float padding; hdAnimation* transAnim; hdAnimation* fadeAnim; hdVectorAction* moveTo; ConvertScreenToInterface(interfaceValues, xWidth, 0.5f * xWidth); ConvertScreenToInterface(origin, 0, 0); interfaceValues.x = interfaceValues.x - origin.x; interfaceValues.y = interfaceValues.y - origin.y; padding = 0.5f * interfaceValues.x; xOffset = -padding; if (position == ICON_POSITION_LEFT) { xOffset = interfaceValues.x + padding; } if (position == ICON_POSITION_CENTER) { xOffset = 0.5f * interfaceValues.x; } if (NULL == (icon = new hdUIImage(iconTexture, NULL, gamePosition.x-xOffset, gamePosition.y, interfaceValues.x, interfaceValues.x/2.0f))) { hdPrintf("[GameController::AnimateIcon] Couldn't find texture for icon %s", iconTexture); return; } icon->SetAlpha(0.0f); m_gameWorldAnimPolygons->Add(icon); if (drifts) { transAnim = hdAnimationController::CreateAnimation(this); moveTo = new hdVectorAction(); moveTo->SetDuration(duration); moveTo->SetDestination(hdVec3(icon->GetWorldCenter().x, gamePosition.y + interfaceValues.y, 0.0f)); transAnim->AddGameObject(icon); transAnim->AddAction(moveTo); //transAnim->SetFinishedCallback(this, GameController::AnimateIconCallback); transAnim->StartAnimation(); } fadeAnim = AnimateFadeInOut(icon, 0.1f, duration - 0.3f, 0.30f); fadeAnim->SetFinishedCallback(this, GameController::AnimateIconCallback); #else hdVec2 screenPos; hdUIImage *icon; float xOffset; hdAnimation* transAnim; hdAnimation* fadeAnim; hdVectorAction* moveTo; ConvertInterfaceToScreen(screenPos, gamePosition.x, gamePosition.y); xOffset = oppositeSide ? xWidth : 0.0f; if (NULL == (icon = new hdUIImage(iconTexture, NULL, screenPos.x-xOffset, screenPos.y, xWidth, xWidth/2.0f))) { hdPrintf("[GameController::AnimateIcon] Couldn't find texture for icon %s", iconTexture); return; } icon->SetAlpha(0.0f); m_animPolygons->Add(icon); if (drifts) { transAnim = hdAnimationController::CreateAnimation(this); moveTo = new hdVectorAction(); moveTo->SetDuration(duration); moveTo->SetDestination(hdVec3(icon->GetWorldCenter().x, screenPos.y + 100.0f, 0.0f)); transAnim->AddGameObject(icon); transAnim->AddAction(moveTo); transAnim->StartAnimation(); } fadeAnim = AnimateFadeInOut(icon, 0.1f, duration - 0.3f, 0.30f); fadeAnim->SetFinishedCallback(this, GameController::AnimateIconCallback); #endif }