From eda90b505d3a583e0c3788ca1ad924d75b02fe01 Mon Sep 17 00:00:00 2001 From: Tim Redfern Date: Fri, 9 Nov 2012 18:55:44 +0000 Subject: levels working, lyrics loading --- vfg/src/music.cpp | 148 +++++++++++++++++++++++++++--------------------------- 1 file changed, 74 insertions(+), 74 deletions(-) (limited to 'vfg/src/music.cpp') diff --git a/vfg/src/music.cpp b/vfg/src/music.cpp index 096e630..29b1ef6 100755 --- a/vfg/src/music.cpp +++ b/vfg/src/music.cpp @@ -2,18 +2,11 @@ //event times & durations are absolute integer milliseconds //--------------------------------------------------------------------------------------------------------------------------------------------- -note::note(int n,int v,int d){ - num=n; - velocity=v; - duration=d; - activated=false; -} -//--------------------------------------------------------------------------------------------------------------------------------------------- -//--------------------------------------------------------------------------------------------------------------------------------------------- musicscore::musicscore() { timeframe=2000; flake.loadImage("flake.png"); flake.setAnchorPercent(0.5,0.5); + missedLast=false; } void musicscore::parseMidi(string filename){ // millis = 60000 / (BPM * PPQ) @@ -86,10 +79,9 @@ void musicscore::parseMidi(string filename){ while (++iter2 != events.end()) { if ((iter1->second->num==iter2->second->num)&&(iter2->second->duration==128)) { iter1->second->duration=iter2->first-iter1->first; - iter1->second->updown=iter1->second->numsecond->num==n?0:1; n=iter1->second->num; notes[iter1->first]=iter1->second; - printf("%i: noteon %i %i %i\n",iter1->first,iter1->second->num,iter1->second->duration,iter1->second->updown); + //printf("%i: noteon %i %i\n",iter1->first,iter1->second->num,iter1->second->duration); break; } } @@ -98,97 +90,96 @@ void musicscore::parseMidi(string filename){ iter1 = notes.end(); iter1--; printf("processed %s: length %f, %i notes in %f seconds\n",filename.c_str(),((float)(iter1->first+iter1->second->duration)*.001f),notes.size(),ofGetElapsedTimef()-wt); - -//decimate notes to generate flakes that can be interacted with - int noteThresh=1000; - note *lastNote=notes.begin()->second; - int lastTime=0; - stars[notes.begin()->first]=notes.begin()->second; - for (iter1 = notes.begin(); iter1 != notes.end(); iter1++) { - if ((iter1->second->num/5!=lastNote->num/5)||(iter1->first-lastTime>noteThresh)) { - stars[iter1->first]=iter1->second; +} +void musicscore::makeFlakes(int threshStart,int threshEnd){ + //decimate notes to generate flakes that can be interacted with + map::iterator iter; + note *lastNote=notes.begin()->second; + int lastTime=0; + iter = notes.end(); + iter--; + float songDuration=iter->first; + flakes[notes.begin()->first]=notes.begin()->second; + for (iter = notes.begin(); iter != notes.end(); iter++) { + float songPos=((float)iter->first)/songDuration; + if ((iter->second->num/5!=lastNote->num/5)||(iter->first-lastTime>((songPos*threshEnd)+((1.0f-songPos)*threshStart)))) { + flakes[iter->first]=iter->second; } - lastNote=iter1->second; - lastTime=iter1->first; - } - - interactionThresh=200; //how long player has to respond - missedTime=-1; - - + lastNote=iter->second; + lastTime=iter->first; + } } void musicscore::setTimeframe(int millis) {timeframe=millis;} -void musicscore::draw() { +void musicscore::draw(levelscore *levels) { ofEnableAlphaBlending(); int scoreStart=ofGetElapsedTimeMillis()-startTime; int scoreEnd=scoreStart+timeframe; - //temporary drawing method 46h - 52h + //note drawing 46h - 52h int numnotes=16; int firstnote=70; float widthStep=((float)ofGetWidth())/numnotes; float heightStep=((float)ofGetHeight())/timeframe; map::iterator iter; - for (iter = notes.lower_bound(scoreStart); iter != notes.upper_bound(scoreEnd); ++iter) { + //draw notes for reference + for (iter = notes.lower_bound(scoreStart); iter != notes.upper_bound(scoreEnd); ++iter) { int thisnote=iter->second->num-firstnote; int thisstart=iter->first-scoreStart; int thislength=iter->second->duration; ofSetColor(ofColor::fromHsb(((float)thisnote*255)/numnotes,200,100)); ofRect(thisnote*widthStep,ofGetHeight()-(thisstart*heightStep),widthStep,-(thislength*heightStep)); - - //different methods for generating flakes - //ideally theres a variable clumping factor, this means pre-processing the flakes though - - //ofSetColor(ofColor::fromHsb(((float)thisnote*255)/numnotes,200,255)); - - //flake.draw((thisnote+0.5f)*widthStep,ofGetHeight()-(thisstart*heightStep)); - //flake.draw((iter->second->updown*ofGetWidth()*0.33)+(ofGetWidth()*0.5),ofGetHeight()-(thisstart*heightStep)); - //flake.draw((((thisnote/5)*5)+3.5f)*widthStep,ofGetHeight()-(thisstart*heightStep)); } - for (iter = stars.lower_bound(scoreStart-200); iter != stars.upper_bound(scoreEnd); ++iter) { //added extra 200ms for flake to leave screen + //draw flakes + for (iter = flakes.lower_bound(scoreStart-200); iter != flakes.upper_bound(scoreEnd); ++iter) { //extra 200ms for flake to leave screen int thisnote=iter->second->num-firstnote; int thisstart=iter->first-scoreStart; int thislength=iter->second->duration; - - // check player interaction - if (thisstartsecond->playerActivated(); - } - } if (iter->second->activated) ofSetColor(255,255,255); else ofSetColor(ofColor::fromHsb(((float)thisnote*255)/numnotes,200,255)); flake.draw((((thisnote/5)*5)+3.5f)*widthStep,ofGetHeight()-(thisstart*heightStep),flake.getWidth()/2,flake.getHeight()/2); } - //check for unactivated stars. must be a better way - missedTime=-1; - for (iter = stars.upper_bound(scoreStart); iter != stars.lower_bound(0); --iter) { - if (!iter->second->activated) missedTime=scoreStart-iter->first; - else break; + //check for unactivated flakes within this segment: is there a more efficient way? + //is it the number of flakes they can lose per segment? + missedFlakes=0; + missedLast=false; + for (iter = flakes.lower_bound(levels->getLowerBound(levels->getLevel(scoreStart))); iter != flakes.upper_bound(scoreStart); ++iter){ + if (!iter->second->activated) { + missedFlakes++; + } + missedLast=!iter->second->activated; } ofDisableAlphaBlending(); } -void musicscore::playerControl(int key){ - //0-3 - 0 is off - playerKey=key; +void musicscore::playerControl(int key,int threshold){ + map::iterator iter; + int scoreTime=ofGetElapsedTimeMillis()-startTime; + for (iter = flakes.lower_bound(scoreTime-threshold); iter != flakes.upper_bound(scoreTime+threshold); ++iter) { + iter->second->activate(); + } } //--------------------------------------------------------------------------------------------------------------------------------------------- -song::song(string backfile,string melfile,string notefile) { +song::song(string backfile,string melfile,string musfile,string lyricfile,string levelfile) { backing.loadSound(backfile); melody.loadSound(melfile); - notes.parseMidi(notefile); + notes.parseMidi(musfile); + lyrics.load(lyricfile); + levels.load(levelfile); isPlaying=false; - missedInterval=5000; + keyThresh=200; } void song::setTimeframe(int millis) {notes.setTimeframe(millis);} +void song::setKeythresh(int millis) {keyThresh=millis;} +void song::setFlakeThresh(int tS,int tE) { + fThreshStart=tS; + fThreshEnd=tE; +} void song::play() { backing.play(); melody.play(); startTime=ofGetElapsedTimeMillis(); notes.startTime=startTime; isPlaying=true; + notes.makeFlakes(fThreshStart,fThreshEnd); } void song::stop() { backing.stop(); @@ -200,24 +191,33 @@ void song::preRoll(long preroll) { notes.startTime=startTime; isPreroll=true; isPlaying=true; + notes.makeFlakes(fThreshStart,fThreshEnd); } void song::draw(){ - //how to deal with end/ track length/ part of game? - if (isPreroll) { - if (startTimelevels.getLives(songTime)) { + //work out score + stop(); + } + } + } + else melody.setVolume(1.0f); + notes.draw(&levels); } - if (notes.missedTime>0) { - if (notes.missedTime>missedInterval) stop(); - else melody.setVolume(0.0f); //1.0f-((float)notes.missedTime/(float)missedInterval)); - } - else melody.setVolume(1.0f); - notes.draw(); + + ofDrawBitmapString(ofToString((float)songTime/1000.0f,3)+" "+ofToString(levels.getLevel(songTime))+" "+ofToString(notes.missedFlakes)+" of "+ofToString(levels.getLives(songTime)),10,ofGetHeight()-15); } void song::playerControl(int key){ - //0-3 - 0 is off - notes.playerControl(key); + notes.playerControl(key,keyThresh); } -- cgit v1.2.3