/* ************************************************************************** */ /* _____ _ __ ___ __ */ /* Engine.cpp | ___(_)/ _| ___ ( _ ) / /_ */ /* Project: C-Engine | |_ | | |_ / _ \/ _ \| '_ \ */ /* | _| | | _| __/ (_) | (_) | */ /* Author: Fife |_| |_|_| \___|\___/ \___/ */ /* */ /* ************************************************************************** */ #include "..\C-Engine\include\Engine.hpp" Engine::Engine() { execute = true; fps = false; fpswish = 4; listeObject = NULL; nbobject = 0; screen.min.x = 0; screen.min.y = 0; screen.max.x = 128; screen.max.y = 64; tabLevel = NULL; nbLevel = 0; currentLevel = -1; time = 0; engineScript = NULL; } void Engine::StartGame() { InitGame(); while(execute) { ML_clear_vram(); input_update(); ExecuteScript(); AppliedForce(); UpdateRelativePosition(); Draw(); setFps(fpswish); ML_display_vram(); } DelAllObject(); } void Engine::InitGame() { execute = true; srand(RTC_getTicks()); for( int i = 0 ; i < nbobject ; i++ ) { if(listeObject[i]->GetScript() && listeObject[i]->GetEnable())listeObject[i]->GetScript()->Start(); } if(tabLevel) for( int i = 0 ; i < nbLevel ; i++ ) for( int j = 0 ; j < tabLevel[i]->GetNbObject() ; j++ ) if(tabLevel[i]->GetListeObject()[j]->GetScript() && tabLevel[i]->GetListeObject()[j]->GetEnable())tabLevel[i]->GetListeObject()[j]->GetScript()->Start(); if(engineScript)engineScript->Start(); } void Engine::StopGame() { execute = false; } void Engine::ShowFps() { fps = true; } void Engine::HideFps() { fps = false; } void Engine::SetFpsWish(int v) { fpswish = 180 / v; } void Engine::AddObject( Object * v , int level) { if(level == -1 && tabLevel) { tabLevel[currentLevel]->AddObject(v); return; } if( level < nbLevel && level >= 0 && tabLevel) { tabLevel[level]->AddObject(v); return; } Object ** Tab = listeObject; //On créai un pointeur sur la liste actuelle d'objet listeObject = (Object**) malloc( sizeof(Object *) * ( nbobject + 1 ) );//On alloue l'espace nécéssaire pour le nouveau tableau for( int i = 0 ; i < nbobject ; i++ )//On copie les pointeurs listeObject[i] = Tab[i]; listeObject[ nbobject ] = v; //Et on rajoute l'objet v->AffectEngine(this); nbobject ++; delete Tab; return; } void Engine::DelObject( Object * v , bool destroy ) { if(tabLevel) { if(!tabLevel[currentLevel]->DelObject(v , destroy )) { for(int i = 0 ; i < nbLevel ; i++ ) { if(tabLevel[i]->DelObject(v , destroy ))return; } } else { return; } } Object ** Tab = listeObject; int index = -1; if(!Tab)return; for( int i = 0 ; i < nbobject ; i++ ) if(Tab[i] == v ) index = i ; if(index == -1)return; listeObject = (Object**) malloc( sizeof(Object *) * ( nbobject - 1) ); for( int i = 0 ; i < index ; i++ ) listeObject[ i ] = Tab[ i ]; for(int i = index + 1 ; i < nbobject ; i++ ) listeObject[ i - 1] = Tab[ i ]; nbobject --; if(destroy)delete v; delete Tab; } void Engine::DelAllObject() { if(tabLevel) { for(int i = 0 ; i < nbLevel ; i++ ) { tabLevel[i]->DelAllObject(); } } for(int i = 0 ; i < nbobject ; i++) delete listeObject[i]; delete listeObject; listeObject = NULL; } Object ** Engine::GetListeObject() { return listeObject; } int Engine::GetNbObject() { return nbobject; } void Engine::ExecuteScript() { if(WaitOneSecond()) { ExecuteScriptSecond(); if(engineScript)engineScript->UpdateEverySecond(); } if(tabLevel && currentLevel != -1) { for( int i = 0 ; i < GetCurrentLevel()->GetNbObject() ; i++ ) { if(i >= GetCurrentLevel()->GetNbObject())return; if( GetCurrentLevel()->GetListeObject()[i]->GetEnable()) if(GetCurrentLevel()->GetListeObject()[i]->GetScript()) GetCurrentLevel()->GetListeObject()[i]->GetScript()->Update(); } } else { for( int i = 0 ; i < nbobject ; i++ ) { if(i >= nbobject)return; if( listeObject[i]->GetEnable()) if(listeObject[i]->GetScript()) listeObject[i]->GetScript()->Update(); } } } void Engine::AppliedForce() { if(tabLevel && currentLevel != -1) { for( int i = 0 ; i < GetCurrentLevel()->GetNbObject() ; i++ ) { if( GetCurrentLevel()->GetListeObject()[i]->GetEnable()) if(GetCurrentLevel()->GetListeObject()[i]->GetRigidBody()) GetCurrentLevel()->GetListeObject()[i]->GetRigidBody()->AppliedForce(); } } else { for( int i = 0 ; i < nbobject ; i++ ) { if( listeObject[i]->GetEnable()) if(listeObject[i]->GetRigidBody()) listeObject[i]->GetRigidBody()->AppliedForce(); } } } void Engine::Draw() { if(tabLevel && currentLevel != -1) { GetCurrentLevel()->DrawMap(); for( int i = 0 ; i < GetCurrentLevel()->GetNbObject() ; i++ ) { if( GetCurrentLevel()->GetListeObject()[i]->GetEnable()) if(GetCurrentLevel()->GetListeObject()[i]->GetRender()) GetCurrentLevel()->GetListeObject()[i]->GetRender()->DrawObject(); } } else { for( int i = 0 ; i < nbobject ; i++ ) { if( listeObject[i]->GetEnable()) if(listeObject[i]->GetRender()) listeObject[i]->GetRender()->DrawObject(); } } if(engineScript)engineScript->Update(); if(fps) PrintV(110,2,getFps()); } AABB * Engine::GetScreen() { return &screen; } void Engine::MoveScreen(int x , int y) { screen.min.x = x; screen.max.x = x + 64; screen.min.y = y; screen.max.y = y + 128; } void Engine::MiddleScreen(int x , int y , bool fixe) { screen.min.x = x - 64; screen.max.x = x + 64; screen.min.y = y - 32; screen.max.y = y + 32; if(fixe) { if( screen.min.x < 0 ) { screen.min.x = 0; screen.max.x = 128; } if(screen.min.y < 0) { screen.min.y = 0; screen.max.y = 64; } if(tabLevel && currentLevel != -1) { if(screen.max.x > GetCurrentLevel()->levelWidth * GetCurrentLevel()->tileWidth) { screen.max.x = GetCurrentLevel()->levelWidth * GetCurrentLevel()->tileWidth; screen.min.x = screen.max.x - 128; } if(screen.max.y > GetCurrentLevel()->levelHeight * GetCurrentLevel()->tileHeight) { screen.max.y = GetCurrentLevel()->levelHeight * GetCurrentLevel()->tileHeight; screen.min.y = screen.max.y - 64; } } } } void Engine::UpdateRelativePosition() { if(tabLevel && currentLevel != -1) { for( int i = 0 ; i < GetCurrentLevel()->GetNbObject() ; i++ ) { if( GetCurrentLevel()->GetListeObject()[i]->GetEnable()) GetCurrentLevel()->GetListeObject()[i]->GetTransform()->SetRelativeXY( GetCurrentLevel()->GetListeObject()[i]->GetTransform()->GetX() - screen.min.x , GetCurrentLevel()->GetListeObject()[i]->GetTransform()->GetY() - screen.min.y ); } } for( int i = 0 ; i < nbobject; i++ ) { if(listeObject[i]->GetEnable()) listeObject[i]->GetTransform()->SetRelativeXY( listeObject[i]->GetTransform()->GetX() - screen.min.x , listeObject[i]->GetTransform()->GetY() - screen.min.y ); } } void Engine::SetLevel( Level ** userTabLevel , int userNbLevel) { tabLevel = userTabLevel; nbLevel = userNbLevel; currentLevel = 0; for(int i = 0 ; i < nbLevel ; i++ ) tabLevel[i]->AffectEngine(this); } void Engine::SetLevel( Level * userLevel) { tabLevel = new Level*[1]; tabLevel[0] = userLevel; currentLevel = 0; nbLevel = 1; userLevel->AffectEngine(this); } void Engine::SetCurrentLevel( int id) { if( id < 0 || id >= nbLevel) currentLevel = - 1; else currentLevel = id; } void Engine::DrawLevel() { if(tabLevel && currentLevel != -1 )tabLevel[currentLevel]->DrawMap(); } int Engine::GetIdCurrentLevel() { return currentLevel; } Level * Engine::GetCurrentLevel() { if(currentLevel != -1) return tabLevel[currentLevel]; else return NULL; } Level * Engine::GetLevel(int id) { if(id > -1 && id < nbLevel) return tabLevel[id]; else return NULL; } void Engine::MoveObject(Object * v , int destination) { DelObject( v , false ); AddObject( v , destination ); } bool Engine::WaitOneSecond() { if(RTC_getTicks() - time > 128) // si il s'est écoulé une seconde complète { time = RTC_getTicks(); // et on se rappelle du nombre de ticks de la dernière seconde écoulée return true; } return false; } void Engine::ExecuteScriptSecond() { if(tabLevel && currentLevel != -1) { for( int i = 0 ; i < GetCurrentLevel()->GetNbObject() ; i++ ) { if(i >= GetCurrentLevel()->GetNbObject())return; if( GetCurrentLevel()->GetListeObject()[i]->GetEnable()) if(GetCurrentLevel()->GetListeObject()[i]->GetScript()) GetCurrentLevel()->GetListeObject()[i]->GetScript()->UpdateEverySecond(); } } else { for( int i = 0 ; i < nbobject ; i++ ) { if(i >= nbobject)return; if( listeObject[i]->GetEnable()) if(listeObject[i]->GetScript()) listeObject[i]->GetScript()->UpdateEverySecond(); } } } void Engine::AffectGui(Script * Gui) { engineScript = Gui; if(engineScript)engineScript->AffectEngine(this); }