Example #1
0
void TrailMod::act() {
    // module follows ship, constantly spawns trail atoms that block/hurt
    // trails disappear after a while
    // can be toggled on/off to save power

    //gm->add(/* new trail of the current type at this pos */)->initall(gm,x,y);
    Trail* t = new Trail(host);
    gm->add(t);
    t->initall(gm,host->x,host->y,team);
    t->lifedelay(200);
}
Example #2
0
    void mouseDrag (const MouseEvent& e) override
    {
        Trail* t = getTrail (e.source);

        if (t == nullptr)
        {
            t = new Trail (e.source);
            t->path.startNewSubPath (e.getPosition().toFloat());
            trails.add (t);
        }

        t->pushPoint (e.getPosition().toFloat(), e.mods);
        repaint();
    }
Example #3
0
    void mouseDrag (const MouseEvent& e) override
    {
        Trail* t = getTrail (e.source);

        if (t == nullptr)
        {
            t = new Trail (e.source);
            t->path.startNewSubPath (e.position);
            trails.add (t);
        }

        t->pushPoint (e.position, e.mods, e.pressure);
        repaint();
    }
Example #4
0
void DrawTrail(const Trail& tr, const Graph& g)
{
  if (tr.empty())
  {
    return;
  }

  int prev = tr[0];

  for (unsigned int i = 1; i < tr.size(); i++)
  {
    const GraphEdge& edge = g.GetEdge(tr[i], prev);
    prev = tr[i];
    DrawEdge(edge, g);
  }
}
Example #5
0
CString OptionRow::GetRowTitle() const
{
	CString sLineName = m_RowDef.name;
	CString sTitle = THEME_TITLES ? OPTION_TITLE(sLineName) : sLineName;

	// HACK: tack the BPM onto the name of the speed line
	if( sLineName.CompareNoCase("speed")==0 )
	{
		bool bShowBpmInSpeedTitle = SHOW_BPM_IN_SPEED_TITLE;

		if( GAMESTATE->m_pCurCourse )
		{
			Trail* pTrail = GAMESTATE->m_pCurTrail[GAMESTATE->m_MasterPlayerNumber];
			ASSERT( pTrail != NULL );
			const int iNumCourseEntries = pTrail->m_vEntries.size();
			if( iNumCourseEntries > MAX_COURSE_ENTRIES_BEFORE_VARIOUS )
				bShowBpmInSpeedTitle = false;
		}

		if( bShowBpmInSpeedTitle )
		{
			DisplayBpms bpms;
			if( GAMESTATE->m_pCurSong )
			{
				Song* pSong = GAMESTATE->m_pCurSong;
				pSong->GetDisplayBpms( bpms );
			}
			else if( GAMESTATE->m_pCurCourse )
			{
				Course *pCourse = GAMESTATE->m_pCurCourse;
				StepsType st = GAMESTATE->GetCurrentStyle()->m_StepsType;
				Trail* pTrail = pCourse->GetTrail( st );
				ASSERT( pTrail );
				pTrail->GetDisplayBpms( bpms );
			}

			if( bpms.IsSecret() )
				sTitle += ssprintf( " (??" "?)" ); /* split so gcc doesn't think this is a trigraph */
			else if( bpms.BpmIsConstant() )
				sTitle += ssprintf( " (%.0f)", bpms.GetMin() );
			else
				sTitle += ssprintf( " (%.0f-%.0f)", bpms.GetMin(), bpms.GetMax() );
		}
	}

	return sTitle;
}
Example #6
0
//--------------------------------------------------------------
void testApp::updateApp(){
	
	ofPoint * pos;
	Trail *trail;
	
	bool bInsideLetter;
	
	vector<ofPoint> growings;
	
	for(int i=0; i<trails.size(); i++){
		
		trail = &trails[i];
		pos = &trail->position;
		
		// If trail isn't in a letter yet
		if(trail->letterId == -1) {
			
			trail->update(screenBounds);
			
			if(!ofInsidePoly( trail->position, screenBounds.getVertices() )){
				trails.erase(trails.begin()+i);
				i--;
				continue;
			}
			
			// look if it has found a letter now
			for(int j=0; j<letters.size(); j++){
				if( ofInsidePoly( *pos, letters[j].getVertices() ) ) {
					trail->letterId = j;
				}
			}
		}
		else {
			
			trail->update(letters[trail->letterId]);
			
			if (trails[i].bActive) {
				growings.push_back(trails[i].position);
			}
		}
	}
	
	triangle.clear();
	if(growings.size()>=3)
		triangle.triangulate( growings, growings.size() );
}
Example #7
0
// Fills the complement of the radius of the trail with minus infties.
// The return value true means success. Failure means that during the fill,
// we intersected the outside of the quasidiagonal area.
// In this case, the operation is not finished.
bool borderDetailedAlignMatrix( AlignMatrix& alignMatrix, const Trail& trail, int radius )
{
  int huBookSize = alignMatrix.size();
  int enBookSize = alignMatrix.otherSize();

  int huPos, enPos;
  for ( huPos=0; huPos<huBookSize; ++huPos )
  {
    int rowStart = alignMatrix.rowStart(huPos);
    int rowEnd   = alignMatrix.rowEnd(huPos);
    for ( enPos=rowStart; enPos<rowEnd; ++enPos )
    {
      alignMatrix.cell(huPos,enPos) = outsideOfRadiusValue;
    }
  }

  // We seriously use the fact that many-to-zero segments are subdivided into one-to-zero segments.
  // Inside setBox, an exception is thrown if we try to write outside the quasidiagonal.
  // If we catch such an exception, it means that the quasidiagonal is not thick enough.
  // In this case, we abandon the whole align, just to be sure.
  try
  {
    for ( int i=0; i<trail.size(); ++i )
    {
      setBox( alignMatrix, trail[i].first, trail[i].second, radius, insideOfRadiusValue );
    }
  }
  catch ( const char* errorType )
  {
    massert( std::string(errorType) == "out of quasidiagonal" )
    return false;
  }

  bool verify = true;
  if (verify)
  {
    int numberOfEvaluatedItems(0);
    for ( huPos=0; huPos<huBookSize; ++huPos )
    {
      int rowStart = alignMatrix.rowStart(huPos);
      int rowEnd   = alignMatrix.rowEnd(huPos);
      for ( enPos=rowStart; enPos<rowEnd; ++enPos )
      {
        if (alignMatrix[huPos][enPos]==insideOfRadiusValue)
        {
          ++numberOfEvaluatedItems;
        }
      }
    }

    std::cerr << numberOfEvaluatedItems << " items inside the border." << std::endl;
  }

  return true;
}
Example #8
0
void BPMDisplay::SetBpmFromCourse( const Course* pCourse )
{
    ASSERT( pCourse != NULL );
    ASSERT( GAMESTATE->GetCurrentStyle(PLAYER_INVALID) != NULL );

    StepsType st = GAMESTATE->GetCurrentStyle(PLAYER_INVALID)->m_StepsType;
    Trail *pTrail = pCourse->GetTrail( st );
    // GetTranslitFullTitle because "Crashinfo.txt is garbled because of the ANSI output as usual." -f
    ASSERT_M( pTrail != NULL, ssprintf("Course '%s' has no trail for StepsType '%s'", pCourse->GetTranslitFullTitle().c_str(), StringConversion::ToString(st).c_str() ) );

    m_fCycleTime = (float)COURSE_CYCLE_SPEED;

    if( (int)pTrail->m_vEntries.size() > CommonMetrics::MAX_COURSE_ENTRIES_BEFORE_VARIOUS )
    {
        SetVarious();
        return;
    }

    DisplayBpms bpms;
    pTrail->GetDisplayBpms( bpms );
    SetBPMRange( bpms );
}
Example #9
0
int countIntersectionOfTrails( const Trail& sx, const Trail& sy )
{
  int inter(0);

  Trail::const_iterator sxt = sx.begin();
  Trail::const_iterator syt = sy.begin();
  Trail::const_iterator sxe = sx.end();
  Trail::const_iterator sye = sy.end();
  for ( ; sxt!=sxe && syt!=sye ; )
  {
    if ( *sxt < *syt )
      ++sxt;
    else if ( *sxt > *syt )
      ++syt;
    else
    {
      ++inter;
      ++sxt;
      ++syt;
    }
  }
  return inter;
}
Example #10
0
// A bit of an abuse of the fact that Trail and BisentenceList are typedef'd to the same structure.
double scoreTrailOrBisentenceList( const Trail& trailAuto, const Trail& trailHand )
{
  int score = countIntersectionOfTrails( trailAuto, trailHand );

  std::cerr << trailAuto.size()-score << " misaligned out of " << trailHand.size() << " correct items, "
    << trailAuto.size() << " bets." << std::endl;

  std::cerr << "Precision: " << 1.0*score/trailAuto.size() 
    << ", Recall: " << 1.0*score/trailHand.size() << std::endl;

  double ratio = 1.0*(trailAuto.size()-score)/trailAuto.size();
  return ratio;
}
Example #11
0
void trailToBisentenceList( const Trail& bestTrail,
                            BisentenceList& bisentenceList )
{
  bisentenceList.clear();

  int trailSize = bestTrail.size();

  for ( int pos=0; pos<trailSize-1; ++pos )
  {
    if ( oneToOne(bestTrail,pos) )
    {
      bisentenceList.push_back(bestTrail  [pos]);
    }
  }
}
Example #12
0
bool Course::GetTrailUnsorted( StepsType st, CourseDifficulty cd, Trail &trail ) const
{
	trail.Init();

	// XXX: Why are beginner and challenge excluded here? -Wolfman2000
	// No idea, probably an obsolete design decision from ITG, removing
	// exclusion here, but there's some other area that prevents it too. -Kyz
	/*
	switch( cd )
	{
		case Difficulty_Beginner:
			return false;
		case Difficulty_Challenge:
			return false;
		default: break;
	}
	*/

	// Construct a new Trail, add it to the cache, then return it.
	// Different seed for each course, but the same for the whole round:
	RandomGen rnd( GAMESTATE->m_iStageSeed + GetHashForString(m_sMainTitle) );

	vector<CourseEntry> tmp_entries;
	if( m_bShuffle )
	{
		/* Always randomize the same way per round.  Otherwise, the displayed course
		* will change every time it's viewed, and the displayed order will have no
		* bearing on what you'll actually play. */
		tmp_entries = m_vEntries;
		random_shuffle( tmp_entries.begin(), tmp_entries.end(), rnd );
	}

	const vector<CourseEntry> &entries = m_bShuffle ? tmp_entries:m_vEntries;

	// This can take some time, so don't fill it out unless we need it.
	vector<Song*> vSongsByMostPlayed;
	vector<Song*> AllSongsShuffled;

	trail.m_StepsType = st;
	trail.m_CourseType = GetCourseType();
	trail.m_CourseDifficulty = cd;
	trail.m_vEntries.reserve(entries.size());

	// Set to true if CourseDifficulty is able to change something.
	bool bCourseDifficultyIsSignificant = (cd == Difficulty_Medium);

	

	// Resolve each entry to a Song and Steps.
	if( trail.m_CourseType == COURSE_TYPE_ENDLESS )
	{
		GetTrailUnsortedEndless(entries, trail, st, cd, rnd, bCourseDifficultyIsSignificant);
	}
	else
	{
		vector<SongAndSteps> vSongAndSteps;
		for (auto e = entries.begin(); e != entries.end(); ++e)
		{
			SongAndSteps resolved;	// fill this in
			SongCriteria soc = e->songCriteria;

			Song *pSong = e->songID.ToSong();
			if( pSong )
			{
				soc.m_bUseSongAllowedList = true;
				soc.m_vpSongAllowedList.push_back( pSong );
			}
			soc.m_Tutorial = SongCriteria::Tutorial_No;
			soc.m_Locked = SongCriteria::Locked_Unlocked;
			if( !soc.m_bUseSongAllowedList )
				soc.m_iMaxStagesForSong = 1;

			StepsCriteria stc = e->stepsCriteria;
			stc.m_st = st;
			stc.m_Locked = StepsCriteria::Locked_Unlocked;

			const bool bSameSongCriteria = e != entries.begin() && ( e - 1 )->songCriteria == soc;
			const bool bSameStepsCriteria = e != entries.begin() && ( e - 1 )->stepsCriteria == stc;

			if( pSong )
			{
				StepsUtil::GetAllMatching( pSong, stc, vSongAndSteps );
			}
			else if( vSongAndSteps.empty() || !( bSameSongCriteria && bSameStepsCriteria ) )
			{
				vSongAndSteps.clear();
				StepsUtil::GetAllMatching( soc, stc, vSongAndSteps );
			}

			// It looks bad to have the same song 2x in a row in a randomly generated course.
			// Don't allow the same song to be played 2x in a row, unless there's only
			// one song in vpPossibleSongs.
			if( trail.m_vEntries.size() > 0 && vSongAndSteps.size() > 1 )
			{
				const TrailEntry &teLast = trail.m_vEntries.back();
				RemoveIf( vSongAndSteps, SongIsEqual( teLast.pSong ) );
			}

			// if there are no songs to choose from, abort this CourseEntry
			if( vSongAndSteps.empty() )
				continue;

			vector<Song*> vpSongs;
			typedef vector<Steps*> StepsVector;
			std::map<Song*, StepsVector> mapSongToSteps;
			for (auto &sas: vSongAndSteps)
			{
				StepsVector &v = mapSongToSteps[ sas.pSong ];

				v.push_back( sas.pSteps );
				if( v.size() == 1 )
					vpSongs.push_back( sas.pSong );
			}

			CourseSortSongs( e->songSort, vpSongs, rnd );

			ASSERT( e->iChooseIndex >= 0 );
			if( e->iChooseIndex < int( vSongAndSteps.size() ) )
			{
				resolved.pSong = vpSongs[ e->iChooseIndex ];
				const vector<Steps*> &mappedSongs = mapSongToSteps[ resolved.pSong ];
				resolved.pSteps = mappedSongs[ RandomInt( mappedSongs.size() ) ];
			}
			else
			{
				continue;
			}

			/* If we're not COURSE_DIFFICULTY_REGULAR, then we should be choosing steps that are
			* either easier or harder than the base difficulty.  If no such steps exist, then
			* just use the one we already have. */
			Difficulty dc = resolved.pSteps->GetDifficulty();
			int iLowMeter = e->stepsCriteria.m_iLowMeter;
			int iHighMeter = e->stepsCriteria.m_iHighMeter;
			if( cd != Difficulty_Medium  &&  !e->bNoDifficult )
			{
				Difficulty new_dc = ( Difficulty )( dc + cd - Difficulty_Medium );
				new_dc = Rage::clamp( new_dc, ( Difficulty )0, ( Difficulty )( Difficulty_Edit - 1 ) );
				/*
				// re-edit this code to work using the metric.
				Difficulty new_dc;
				if( INCLUDE_BEGINNER_STEPS )
				{
				// don't factor in the course difficulty if we're including
				// beginner steps -aj
				new_dc = Rage::clamp( dc, Difficulty_Beginner, (Difficulty)(Difficulty_Edit-1) );
				}
				else
				{
				new_dc = (Difficulty)(dc + cd - Difficulty_Medium);
				new_dc = Rage::clamp( new_dc, (Difficulty)0, (Difficulty)(Difficulty_Edit-1) );
				}
				*/

				bool bChangedDifficulty = false;
				if( new_dc != dc )
				{
					Steps* pNewSteps = SongUtil::GetStepsByDifficulty( resolved.pSong, st, new_dc );
					if( pNewSteps )
					{
						dc = new_dc;
						resolved.pSteps = pNewSteps;
						bChangedDifficulty = true;
						bCourseDifficultyIsSignificant = true;
					}
				}

				/* Hack: We used to adjust low_meter/high_meter above while searching for
				* songs.  However, that results in a different song being chosen for
				* difficult courses, which is bad when LockCourseDifficulties is disabled;
				* each player can end up with a different song.  Instead, choose based
				* on the original range, bump the steps based on course difficulty, and
				* then retroactively tweak the low_meter/high_meter so course displays
				* line up. */
				if( e->stepsCriteria.m_difficulty == Difficulty_Invalid && bChangedDifficulty )
				{
					/* Minimum and maximum to add to make the meter range contain the actual
					* meter: */
					int iMinDist = resolved.pSteps->GetMeter() - iHighMeter;
					int iMaxDist = resolved.pSteps->GetMeter() - iLowMeter;

					/* Clamp the possible adjustments to try to avoid going under 1 or over
					* MAX_BOTTOM_RANGE. */
					iMinDist = std::min( std::max( iMinDist, -iLowMeter + 1 ), iMaxDist );
					iMaxDist = std::max( std::min( iMaxDist, MAX_BOTTOM_RANGE - iHighMeter ), iMinDist );

					int iAdd;
					if( iMaxDist == iMinDist )
						iAdd = iMaxDist;
					else
						iAdd = rnd( iMaxDist - iMinDist ) + iMinDist;
					iLowMeter += iAdd;
					iHighMeter += iAdd;
				}
			}

			TrailEntry te;
			te.pSong = resolved.pSong;
			te.pSteps = resolved.pSteps;
			te.Modifiers = e->sModifiers;
			te.Attacks = e->attacks;
			te.bSecret = e->bSecret;
			te.iLowMeter = iLowMeter;
			te.iHighMeter = iHighMeter;

			/* If we chose based on meter (not difficulty), then store Difficulty_Invalid, so
			* other classes can tell that we used meter. */
			if( e->stepsCriteria.m_difficulty == Difficulty_Invalid )
			{
				te.dc = Difficulty_Invalid;
			}
			else
			{
				/* Otherwise, store the actual difficulty we got (post-course-difficulty).
				* This may or may not be the same as e.difficulty. */
				te.dc = dc;
			}
			trail.m_vEntries.push_back( te );

			// LOG->Trace( "Chose: %s, %d", te.pSong->GetSongDir().c_str(), te.pSteps->GetMeter() );

			if( IsAnEdit() && MAX_SONGS_IN_EDIT_COURSE > 0 &&
				int( trail.m_vEntries.size() ) >= MAX_SONGS_IN_EDIT_COURSE )
			{
				break;
			}
		}
	}

	/* Hack: If any entry was non-FIXED, or m_bShuffle is set, then radar values
	 * for this trail will be meaningless as they'll change every time. Pre-cache
	 * empty data. XXX: How can we do this cleanly, without propagating lots of
	 * otherwise unnecessary data (course entry types, m_bShuffle) to Trail, or
	 * storing a Course pointer in Trail (yuck)? */
	if( !AllSongsAreFixed() || m_bShuffle )
	{
		trail.m_bRadarValuesCached = true;
		trail.m_CachedRadarValues = RadarValues();
	}

	/* If we have a manually-entered meter for this difficulty, use it. */
	if( m_iCustomMeter[cd] != -1 )
		trail.m_iSpecifiedMeter = m_iCustomMeter[cd];

	/* If the course difficulty never actually changed anything, then this difficulty
	 * is equivalent to Difficulty_Medium; it doesn't exist. */
	return bCourseDifficultyIsSignificant && trail.m_vEntries.size() > 0;
}
Example #13
0
void Choreo3DApp::draw()
{
  
    //gl::clear( ColorA::gray( background ) );
    gl::clear(ColorAf(testBK));
    
    //THIS MAY NEED TO BE CLEANED UP
    vector<std::string> dataVector = {"CCL_JOINT_CCL3_00_skip10.json"};
    
    if( CURRENT_DATA_SET != LOADED_DATA_SET){
       // paused = true;
        
        
        //   jointList = {};
        jointList = ccl::loadMotionCaptureFromJson(getAssetPath(dataVector[CURRENT_DATA_SET]));
        
        FRAME_COUNT = 0;
        TOTAL_FRAMES = jointList[0].jointPositions.size(); //SHOULD PROBABLY PUT A TRY/CATCH HERE
        
        std::cout << "total frames: " << TOTAL_FRAMES << ", total joints:"<< jointList.size() << std::endl;
        
        gl::VboMeshRef body = gl::VboMesh::create( geom::Sphere().subdivisions( 16 ).radius(4) );
        
        //CREATE A CONTAINER TO STORE THE INITIAL POSITIONS FOR INITIALISING THE JOINTS
        std::vector<glm::vec3> positions;
        
        // CREATE THE SPHERES AT THE INITIAL JOINT LOCATIONS
        for ( int i = 0; i < jointList.size(); ++i ) {
            glm::vec3 jointAt = jointList[i].jointPositions[i];
            float instanceX = jointAt.x;
            float instanceY = jointAt.y;
            float instanceZ = jointAt.z;
            // float instanceZ = 0;
            
            positions.push_back( vec3( instanceX, instanceY, instanceZ));
        }
        //std::cout << "positions: " << positions[0] << std::endl;
        
        // create the VBO which will contain per-instance (rather than per-vertex) data
        mInstanceDataVbo = gl::Vbo::create( GL_ARRAY_BUFFER, positions.size() * sizeof(vec3), positions.data(), GL_DYNAMIC_DRAW );
        
        // we need a geom::BufferLayout to describe this data as mapping to the CUSTOM_0 semantic, and the 1 (rather than 0) as the last param indicates per-instance (rather than per-vertex)
        geom::BufferLayout instanceDataLayout;
        
        instanceDataLayout.append( geom::Attrib::CUSTOM_0, 3, 0, 0, 1 /* per instance */ );
        
        //NOW ADD IT TO THE VBO MESH THAT WE INITIAL CREATED FOR THE BODY / SKELETON
        body->appendVbo( instanceDataLayout, mInstanceDataVbo );
        
        //FINALLY, BUILD THE BATCH, AND MAP THE CUSTOM_0 ATTRIBUTE TO THE "vInstancePosition" GLSL VERTEX ATTRIBUTE
        mSphereBatch = gl::Batch::create( body, mGlsl, { { geom::Attrib::CUSTOM_0, "vInstancePosition" } } );
        
        LOADED_DATA_SET = CURRENT_DATA_SET;
        
    }
    
    
    
    gl::setMatrices( mCamera );
    
    if (showGrid)renderScene();
    
    Color( dancerColor[0], dancerColor[1], dancerColor[2] );
    //gl::ScopedModelMatrix modelScope;
    
    if(markersActive)mSphereBatch->drawInstanced( jointList.size() );
    
    if(skeletonActive)skeleton.renderSkeleton();
    
    if(ribbonsActive)drawRibbons();
    
    if(trailsActive)handTrail.render(dancerColor);
    
    
}
Example #14
0
void Choreo3DApp::update()
{
    setFrameRate(frameRate);
    
    //DISABLE CAMERA INTERACTION IF MOUSE IS OVER UI REGION
    if (getMousePos().x > 3 * getWindowWidth()/4. && camActive)
    {
        camActive = false;
        mCamUi.disconnect();
        mCamUi.disable();
        cout << "disabling camera UI" << endl;
    } else {
        if (!camActive)
        {
            mCamUi.connect(getWindow());
            mCamUi.enable();
        }
        camActive = true;
        cout << "enabling camera UI" << endl;
    }
    
    mGlsl->uniform("uColor", markerColour );
    
    if (!paused)
    {
        
        
        //UPDATE POSITIONS
        //MAP INSTANCE DATA TO VBO
        //WRITE NEW POSITIONS
        //UNMAP
        
        glm::vec3 *newPositions = (glm::vec3*)mInstanceDataVbo->mapReplace();
        
        for( int i = 0; i < jointList.size(); ++i )
        {
            
            float instanceX = jointList[i].jointPositions[FRAME_COUNT].x;
            float instanceY = jointList[i].jointPositions[FRAME_COUNT].y;
            float instanceZ = jointList[i].jointPositions[FRAME_COUNT].z;
            
            vec3 newPos(vec3(instanceX,instanceY, instanceZ)); //CREATE A NEW VEC3 FOR UPDATING THE VBO
            
            framePositions[i] = newPos;
            
        }
        
        //REPLACE VEC3s IN VBO BY INCREMENTING THE POINTER
        for (int i = 0; i < framePositions.size(); i++){
            *newPositions++ = framePositions[i];
        }
        
        handTrail.update(framePositions[26], dancerColor);
        
        //    std::cout << framePositions[17] << std::endl;
        
        
        skeleton.update(framePositions);

        
        mInstanceDataVbo->unmap();
        // std::cout << "position: " << positions[0] << std::endl;
        
        if (ribbonsActive)updateRibbons();
        
        //MANUALLY INCREMENT THE FRAME, IF THE FRAME_COUNT EXCEEDS TOTAL FRAMES, RESET THE COUNTER
        if (FRAME_COUNT < TOTAL_FRAMES)
        {
            FRAME_COUNT += 1;
        } else {
            FRAME_COUNT = 0;
        }
        
        //std::cout << getAverageFps() << std:: endl;
        // std::cout << "frame rate: " << getAverageFps() << ", frame count: " << FRAME_COUNT << std::endl;
        
        //define changed color
      //  Color temp = Color(dancerColor[0],dancerColor[1],dancerColor[2]);
        
        
        mCurrentFrame++; //MANUALLY ADVANCE THE CURRENT FRAME - WITH RESPECT TO THE DANCERS
    
    }
    
    updateGui();
}
Example #15
0
void trelliToLadder( const TrelliMatrix& trellis, Trail& bestTrail )
{
  bestTrail.clear();

  // The -1 is needed because the trellis matrix is one larger than the similarity matrix.
  // This points to its downmost rightmost element.
  const int huBookSize = trellis.size()-1;
  const int enBookSize = trellis.otherSize()-1;

  int huPos=huBookSize;
  int enPos=enBookSize;

  bool logging = false;

  if (logging) std::cerr << std::endl;

  bool over = false;
  bool hopelesslyBadTrail = false;
  bestTrail.push_back(std::make_pair(huPos,enPos));

  while (true)
  {
    unsigned char trelli = trellis[huPos][enPos];

    // std::cerr << huPos << "," << enPos << "," << (int)trelli << std::endl;

    if ((huPos==0) || (enPos==0))
      break;

    switch (trelli)
    {
    case Diag :
    {
      --huPos;
      --enPos;
      break;
    }
    case HuSkip :
    {
      --huPos;
      break;
    }
    case EnSkip :
    {
      --enPos;
      break;
    }
    case HuHuEnSkip :
    {
      huPos -= 2;
      --enPos;
      break;
    }
    case HuEnEnSkip :
    {
      --huPos;
      enPos -= 2;
      break;
    }
    case Dead :
    {
      over = true;
      break;
    }
    default:
    {
      hopelesslyBadTrail = true;
      over = true;
      break;
    }
    }

    if (over)
      break;

    bestTrail.push_back(std::make_pair(huPos,enPos));

    if (logging)
    {
      std::cerr << huPos << " \t" << enPos << std::endl;
    }

  }

  if (hopelesslyBadTrail)
  {
    bestTrail.clear();
    bestTrail.push_back(std::make_pair(huBookSize,enBookSize));
    bestTrail.push_back(std::make_pair(0,0));
    std::cerr << "Error: hopelessly bad trail." << std::endl;
  }

  std::reverse(bestTrail.begin(),  bestTrail.end()  );
}
Example #16
0
bool Course::GetTrailUnsorted( StepsType st, CourseDifficulty cd, Trail &trail ) const
{
	trail.Init();

	// XXX: Why are beginner and challenge excluded here? -Wolfman2000
	switch( cd )
	{
		case Difficulty_Beginner:
			return false;
		case Difficulty_Challenge:
			return false;
		default: break;
	}

	// Construct a new Trail, add it to the cache, then return it.
	// Different seed for each course, but the same for the whole round:
	RandomGen rnd( GAMESTATE->m_iStageSeed + GetHashForString(m_sMainTitle) );

	vector<CourseEntry> tmp_entries;
	if( m_bShuffle )
	{
		/* Always randomize the same way per round.  Otherwise, the displayed course
		* will change every time it's viewed, and the displayed order will have no
		* bearing on what you'll actually play. */
		tmp_entries = m_vEntries;
		random_shuffle( tmp_entries.begin(), tmp_entries.end(), rnd );
	}

	const vector<CourseEntry> &entries = m_bShuffle ? tmp_entries:m_vEntries;

	// This can take some time, so don't fill it out unless we need it.
	vector<Song*> vSongsByMostPlayed;
	vector<Song*> AllSongsShuffled;

	trail.m_StepsType = st;
	trail.m_CourseType = GetCourseType();
	trail.m_CourseDifficulty = cd;

	// Set to true if CourseDifficulty is able to change something.
	bool bCourseDifficultyIsSignificant = (cd == Difficulty_Medium);

	vector<Song*> vpAllPossibleSongs;
	vector<SongAndSteps> vSongAndSteps;

	// Resolve each entry to a Song and Steps.
	FOREACH_CONST( CourseEntry, entries, e )
	{
		SongAndSteps resolved;	// fill this in
		SongCriteria soc = e->songCriteria;

		Song *pSong = e->songID.ToSong();
		if( pSong )
		{
			soc.m_bUseSongAllowedList = true;
			soc.m_vpSongAllowedList.push_back( pSong );
		}
		soc.m_Tutorial = SongCriteria::Tutorial_No;
		soc.m_Locked = SongCriteria::Locked_Unlocked;
		if( !soc.m_bUseSongAllowedList )
			soc.m_iMaxStagesForSong = 1;

		StepsCriteria stc = e->stepsCriteria;
		stc.m_st = st;
		stc.m_Locked = StepsCriteria::Locked_Unlocked;

		const bool bSameSongCriteria  = e != entries.begin() && (e-1)->songCriteria == soc;
		const bool bSameStepsCriteria = e != entries.begin() && (e-1)->stepsCriteria == stc;

		if( pSong )
		{
			StepsUtil::GetAllMatching( pSong, stc, vSongAndSteps );
		}
		else if( vSongAndSteps.empty() || !(bSameSongCriteria && bSameStepsCriteria) )
		{
			vSongAndSteps.clear();
			StepsUtil::GetAllMatching( soc, stc, vSongAndSteps );
		}

		// It looks bad to have the same song 2x in a row in a randomly generated course.
		// Don't allow the same song to be played 2x in a row, unless there's only
		// one song in vpPossibleSongs.
		if( trail.m_vEntries.size() > 0  &&  vSongAndSteps.size() > 1 )
		{
			const TrailEntry &teLast = trail.m_vEntries.back();
			RemoveIf( vSongAndSteps, SongIsEqual(teLast.pSong) );
		}

		// if there are no songs to choose from, abort this CourseEntry
		if( vSongAndSteps.empty() )
			continue;

		vector<Song*> vpSongs;
		typedef vector<Steps*> StepsVector;
		map<Song*,StepsVector> mapSongToSteps;
		FOREACH_CONST( SongAndSteps, vSongAndSteps, sas )
		{
			StepsVector &v = mapSongToSteps[sas->pSong];

			v.push_back( sas->pSteps );
			if( v.size() == 1 )
				vpSongs.push_back( sas->pSong );
		}
Example #17
0
/** Example function that generates a trail from a pair of inputs.
 * In this example, we use the messages found by I. Dinur, O. Dunkelman
 * and A. Shamir to produce a collision on Keccak[r=1088, c=512] reduced
 * to 4 rounds.
 */
void generateTrailFromDinurDunkelmanShamirCollision()
{
    const UINT8 M1[] =
    "\x32\x1c\xf3\xc4\x6d\xae\x59\x4c\xf4\xf0\x19\x5d\x4b\xe4\xc4\x25"
    "\x32\x30\x85\xd8\xf2\x12\x5e\x8d\xe2\x6e\x6e\xbb\x1e\x3b\xc3\x27"
    "\x58\x10\x09\x6c\xd5\x02\x90\xeb\x6f\xa0\xa4\x3b\xf1\xc7\x0c\x4a"
    "\x51\x5e\xb5\xcc\x83\xd9\x0d\x8d\x43\x08\x0a\x2b\xb0\xd3\x21\x9b"
    "\x75\x90\x67\x53\xd2\xde\x6d\x52\x44\x48\x29\x48\x2c\xed\xf4\x6f"
    "\x15\x2c\xce\x1a\xc7\x1d\x1c\x47\x68\x85\x09\xd4\x39\xf6\xeb\xf1"
    "\x57\xb2\xf7\xea\x87\xae\xfd\x09\xe6\x78\x88\x68\x30\xeb\x75\x48"
    "\x80\x2d\xc3\xc9\xcb\x6f\x9e\x3c\xfa\xbc\x2a\x3c\x7b\x80\xa4\xe6"
    "\xb8\x81\xb2\x2a\xb3\x32\x23";
    const unsigned int M1len = 135;
    UINT8 M2[] =
    "\xf7\x0e\xd3\xa4\x69\x8f\xbb\x80\xdf\x48\xc0\x90\xb9\x13\x72\xeb"
    "\x24\x04\x65\xa6\x3e\xf6\x65\x3a\x81\x88\x26\x8c\x1f\xb8\x51\xb6"
    "\x3c\xfa\xda\xaa\xc3\xa5\x2c\xee\xc2\xea\x78\xdb\x79\xe7\xea\xc8"
    "\x35\x9c\x2f\x44\x87\xe2\x21\x32\x5a\x7a\x01\xb3\x12\x07\x79\x90"
    "\xdc\x8b\x1c\x1b\xa8\x10\x8b\xe0\xca\x25\x9d\x9a\xac\xaa\xe7\x1b"
    "\x9c\x3e\x2f\x4e\xad\x7d\x71\x73\x5a\x01\x66\x55\xb9\xcf\x98\xa1"
    "\xc2\xa8\x1c\x5a\x8a\x34\xe3\xa0\xb1\x0b\x6c\xae\xe4\xf9\x80\x39"
    "\x91\x8b\xfa\xa4\x89\xa9\x81\x6e\xaa\xbc\xa9\x89\xf1\xf1\x2b\xe1"
    "\x95\x95\xef\x30\x45\x8b\x2e";
    const unsigned int M2len = 135;
    {
        UINT8 output[32];
        ReducedRoundKeccak keccak(1088, 512, 4);
        keccak.absorb(M1, M1len*8);
        keccak.squeeze(output, 256);
        for(unsigned int i=0; i<32; i++)
            cout << hex << (int)output[i] << " ";
        cout << endl;
    }
    {
        UINT8 output[32];
        ReducedRoundKeccak keccak(1088, 512, 4);
        keccak.absorb(M2, M2len*8);
        keccak.squeeze(output, 256);
        for(unsigned int i=0; i<32; i++)
            cout << hex << (int)output[i] << " ";
        cout << endl;
    }
    {
        KeccakFDCEquations keccakF(1600, 4);
        KeccakFPropagation DC(keccakF, KeccakFPropagation::DC);
        vector<LaneValue> m1lanes, m2lanes;
        {
            UINT8 temp[200];
            memset(temp, 0, 200);
            memcpy(temp, M1, M1len);
            temp[M1len] = 0x81;
            keccakF.fromBytesToLanes(temp, m1lanes);
        }
        {
            UINT8 temp[200];
            memset(temp, 0, 200);
            memcpy(temp, M2, M2len);
            temp[M2len] = 0x81;
            keccakF.fromBytesToLanes(temp, m2lanes);
        }
        vector<SliceValue> m1slices, m2slices;
        fromLanesToSlices(m1lanes, m1slices, 64);
        fromLanesToSlices(m2lanes, m2slices, 64);
        Trail trail;
        keccakF.buildDCTrailFromPair(m1slices, m2slices, trail);
        {
            ofstream fout("DinurEtAl.trail");
            trail.save(fout);
        }
        Trail::produceHumanReadableFile(DC, "DinurEtAl.trail");
    }
}