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/bin/data/Levels_DeckTheHalls.1.5.xml | 6 + vfg/bin/data/Lyrics_DeckTheHalls.1.5.xml | 47 +++ vfg/bin/data/MIDI_DeckTheHalls_MIDI.1.5.xml | 544 ++++++++++++++++++++++++++++ vfg/bin/data/MIDI_test.xml | 22 -- vfg/src/music.cpp | 148 ++++---- vfg/src/music.h | 133 ++++++- vfg/src/testApp.cpp | 23 +- vfg/src/testApp.h | 4 +- vfg/vfg.layout | 8 +- vpn/notes.txt | 5 + vpn/server.conf | 8 + vpn/static.key | 21 ++ 12 files changed, 839 insertions(+), 130 deletions(-) create mode 100755 vfg/bin/data/Levels_DeckTheHalls.1.5.xml create mode 100755 vfg/bin/data/Lyrics_DeckTheHalls.1.5.xml create mode 100755 vfg/bin/data/MIDI_DeckTheHalls_MIDI.1.5.xml delete mode 100644 vfg/bin/data/MIDI_test.xml create mode 100755 vpn/notes.txt create mode 100644 vpn/server.conf create mode 100644 vpn/static.key diff --git a/vfg/bin/data/Levels_DeckTheHalls.1.5.xml b/vfg/bin/data/Levels_DeckTheHalls.1.5.xml new file mode 100755 index 0000000..57ccca7 --- /dev/null +++ b/vfg/bin/data/Levels_DeckTheHalls.1.5.xml @@ -0,0 +1,6 @@ + + + + + + diff --git a/vfg/bin/data/Lyrics_DeckTheHalls.1.5.xml b/vfg/bin/data/Lyrics_DeckTheHalls.1.5.xml new file mode 100755 index 0000000..0bc6789 --- /dev/null +++ b/vfg/bin/data/Lyrics_DeckTheHalls.1.5.xml @@ -0,0 +1,47 @@ + + + Deck the halls + with boughs + of holly + Fa-la + la-la-la + la-la-la-la + 'tis the season + to be jolly + Fa-la + la-la-la + la-la-la-la + Don we now + our gay apparel + Fa-la-la + la-la-la + la-la-la + Troll the ancient + yule-tide + carol + Fa-la + la-la-la + la-la-la-la + + See the blazing + Yule before us + Fa-la + la-la-la + la-la-la-la + Strike the harp + and join + the chorus + Fa-la + la-la-la + la-la-la-la + Follow me + in merry measure + Fa-la-la + la-la-la + la-la-la + While I tell of + Yule-tide treasure + Fa-la + la-la-la + la-la-la-la + diff --git a/vfg/bin/data/MIDI_DeckTheHalls_MIDI.1.5.xml b/vfg/bin/data/MIDI_DeckTheHalls_MIDI.1.5.xml new file mode 100755 index 0000000..960c03f --- /dev/null +++ b/vfg/bin/data/MIDI_DeckTheHalls_MIDI.1.5.xml @@ -0,0 +1,544 @@ + + + + Chip Sounds + Chip Sounds + + + Marker ## + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Marker ## + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/vfg/bin/data/MIDI_test.xml b/vfg/bin/data/MIDI_test.xml deleted file mode 100644 index 769d445..0000000 --- a/vfg/bin/data/MIDI_test.xml +++ /dev/null @@ -1,22 +0,0 @@ - - - - Chip Sounds - Chip Sounds - - - Marker ## - - - - - - - - - - - - - - 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); } diff --git a/vfg/src/music.h b/vfg/src/music.h index 39ffd95..292e05f 100755 --- a/vfg/src/music.h +++ b/vfg/src/music.h @@ -5,15 +5,75 @@ //event times are absolute integer milliseconds //--------------------------------------------------------------------------------------------------------------------------------------------- +class levelscore { + public: + void load(string filename) { + ofxXmlSettings XML; + if( !XML.loadFile(filename) ){ + printf("unable to load %s check data/ folder\n",filename.c_str()); + }else{ + if(XML.pushTag("VFxmas")) { + for (int i=0;i::iterator iter; + int lives=0; + for (iter = levels.begin(); iter != levels.end(); ++iter) { + if (iter->first<=time) lives=iter->second; + else break; + } + return lives; + } + int getLevel(int time) { + map::iterator iter; + int level=-1; + for (iter = levels.begin(); iter != levels.end(); ++iter) { + if (iter->first<=time) level++; + else break; + } + return level; + } + int getLowerBound(int level) { + map::iterator iter=levels.begin(); + int bound=0; + for (int i=0;i<=level;i++) { + bound=iter->first; + iter++; + } + return bound; + } + private: + map levels; +}; +//--------------------------------------------------------------------------------------------------------------------------------------------- class note { public: - note(int n,int v,int d=0); + note(int n,int v,int d=0) { + num=n; + velocity=v; + duration=d; + activated=false; + } int num; int velocity; int duration; //may be needed another time? - int updown; //-1 0 1 used for 3-button interaction bool activated; - void playerActivated() { activated=true; } + void activate() { activated=true; } +}; +//--------------------------------------------------------------------------------------------------------------------------------------------- +class lyric { + public: + lyric(string s,int d) { + text=s; + duration=d; + } + string text; + int duration; }; //--------------------------------------------------------------------------------------------------------------------------------------------- class score { @@ -27,6 +87,23 @@ class score { class lyricscore: public score { //draws lyrics to screen for a certain time public: + void load(string filename) { + if( !XML.loadFile(filename) ){ + printf("unable to load %s check data/ folder\n",filename.c_str()); + }else{ + int multiplier=1000/XML.getAttribute("VFxmas", "timebase",0,0); + if(XML.pushTag("VFxmas")) { + for (int i=0;i lyrics; }; //--------------------------------------------------------------------------------------------------------------------------------------------- class musicscore: public score { @@ -35,31 +112,30 @@ class musicscore: public score { musicscore(); void parseMidi(string filename); void setTimeframe(int millis); - void draw(); - - void playerControl(int key); - //in wrong object? - int missedTime; + void draw(levelscore *levels); + void playerControl(int key,int threshold); + void makeFlakes(int threshStart,int threshEnd); + + int missedFlakes; + bool missedLast; + bool perfect; + private: - map notes; - map stars; + map notes; + map flakes; int timeframe; ofImage flake; - - //in wrong object? - int interactionThresh; - - - int playerKey; }; //--------------------------------------------------------------------------------------------------------------------------------------------- class song { public: - song(string backfile,string melfile,string musfile); + song(string backfile,string melfile,string musfile,string lyricfile,string levelfile); void play(); void stop(); void preRoll(long preroll); void setTimeframe(int millis); + void setFlakeThresh(int tS,int tE); + void setKeythresh(int millis); void draw(); bool isPlaying; void playerControl(int key); @@ -68,12 +144,31 @@ class song { ofSoundPlayer melody; lyricscore lyrics; musicscore notes; + levelscore levels; long startTime; bool isPreroll; - - int missedInterval; + int fThreshStart,fThreshEnd,keyThresh; }; //--------------------------------------------------------------------------------------------------------------------------------------------- +/* +Game +Animation & Sound Demo – NK to overlay latest version of Deck the Halls on 10 second animated sequence by COB Wednesday 7th November for visual and aural aesthetic sign-off. RM to send through latest version of Deck the Halls today (6th November). +Game Development – TR presented initial demo today. Usability looks good. NK to provide first suite of graphics by COB Wednesday 7th November. +Latency Test – TR and GK to perform end-to-end latency test next Monday 12th November once Vodafone have connected the 1800 number to the 01 number. Any issues noted in the testing to be flagged to BL. +Game Over – Players who miss a certain amount of notes in a row will be kicked out of the game early. The number of notes that can be missed in a row will decrease as the game goes on (subject to testing and tweaking): + +Stage 1 – N/A (it will not be possible to be kicked out in Stage 1) +Stage 2 – 5 notes missed will mean Game Over +Stage 3 – 4 notes missed will mean Game Over +Stage 4 – 3 notes missed will mean Game Over + +Scoring – Scoring will be based on the level of the game you achieve. There will be 4 scoring brackets (subject to testing and tweaking): + +Scoring Bracket 1 - Those who make it to Level 2 (see above - it's not possible to be kicked out in Level 1) +Scoring Bracket 2 – Those who make it to Level 3 +Scoring Bracket 3 – Those who make it to Level 4 +Scoring Bracket 4 – Those who don't miss any notes in Level 4 +*/ diff --git a/vfg/src/testApp.cpp b/vfg/src/testApp.cpp index c0c3671..dc450a2 100755 --- a/vfg/src/testApp.cpp +++ b/vfg/src/testApp.cpp @@ -2,10 +2,14 @@ //-------------------------------------------------------------- void testApp::setup(){ - testsong=new song("VODA_MUS_DeckTheHalls-Backing_v.1.3.mp3","VODA_MUS_DeckTheHalls-Melody_v.1.3.mp3","MIDI_DeckTheHalls_Test.1.3.xml"); - testsong->setTimeframe(10000); - testsong->preRoll(250); + //for (float i=0;i<1.2;i+=0.1) printf("%f in level %i bound %f\n",i,lives->getLevel(i),lives->getLowerBound(lives->getLevel(i))); + + testsong=new song("VODA_MUS_DeckTheHalls-Backing_v.1.5.mp3","VODA_MUS_DeckTheHalls-Melody_v.1.5.mp3","MIDI_DeckTheHalls_MIDI.1.5.xml","Lyrics_DeckTheHalls.1.5.xml","Levels_DeckTheHalls.1.5.xml"); + testsong->setTimeframe(2500); + testsong->setFlakeThresh(1000,100); + testsong->preRoll(250); + ofSetBackgroundAuto(false); ofBackground(0,0,0); } @@ -20,15 +24,14 @@ void testApp::update(){ //-------------------------------------------------------------- void testApp::draw(){ - ofEnableAlphaBlending(); + ofEnableAlphaBlending(); //ofBackground(0,0,0,0.1); - ofSetColor(0,0,0,100); + ofSetColor(0,0,0,50); ofRect(0,0,ofGetWidth(),ofGetHeight()); - if (testsong->isPlaying) testsong->draw(); - else { - ofSetColor(255,255,255); - ofDrawBitmapString("game over!", (ofGetWidth()/2)-25,(ofGetHeight()/2)-5); - } + ofSetColor(255,255,255); + testsong->draw(); + if (!testsong->isPlaying) ofDrawBitmapString("game over!", (ofGetWidth()/2)-25,(ofGetHeight()/2)-5); + } //-------------------------------------------------------------- diff --git a/vfg/src/testApp.h b/vfg/src/testApp.h index 5a8805a..0765b4f 100755 --- a/vfg/src/testApp.h +++ b/vfg/src/testApp.h @@ -44,6 +44,8 @@ class game { vector songs; }; + + class testApp : public ofBaseApp{ public: @@ -62,7 +64,7 @@ class testApp : public ofBaseApp{ void dragEvent(ofDragInfo dragInfo); void gotMessage(ofMessage msg); - song* testsong; + song *testsong; }; diff --git a/vfg/vfg.layout b/vfg/vfg.layout index 87ed139..7fe831e 100644 --- a/vfg/vfg.layout +++ b/vfg/vfg.layout @@ -7,11 +7,11 @@ - - + + - - + + diff --git a/vpn/notes.txt b/vpn/notes.txt new file mode 100755 index 0000000..04e07a3 --- /dev/null +++ b/vpn/notes.txt @@ -0,0 +1,5 @@ +sudo openvpn --config server.conf +01-5548000 +ssh 80.93.22.22 'sudo /usr/sbin/asterisk -rx "database put GAME passcode 89889"' +ssh 80.93.22.22 'sudo /usr/sbin/asterisk -rx "database put GAME ip 4.4.4.4"' +ssh 80.93.22.22 'sudo /usr/sbin/asterisk -rx "devstate change Custom:GAME NOT_INUSE"' \ No newline at end of file diff --git a/vpn/server.conf b/vpn/server.conf new file mode 100644 index 0000000..f84f4f4 --- /dev/null +++ b/vpn/server.conf @@ -0,0 +1,8 @@ +remote 80.93.22.22 +dev tun +ifconfig 10.10.10.2 10.10.10.1 +secret static.key +keepalive 10 60 +ping-timer-rem +persist-tun +persist-key diff --git a/vpn/static.key b/vpn/static.key new file mode 100644 index 0000000..4a41586 --- /dev/null +++ b/vpn/static.key @@ -0,0 +1,21 @@ +# +# 2048 bit OpenVPN static key +# +-----BEGIN OpenVPN Static key V1----- +74e9845064b9d1e5ad68028973a598b4 +ad7256441164270c532cae89917f6f8f +a2c21acd116b0d7e39389ebd14c10922 +61dc7ef520a644c30bdea7b6e22f15a8 +980e5f0cce7e7f028c737c67a3289bac +4434c431e27d88169c7c3674b779d902 +ed21bae0fbec6c66bb964be2a03faf44 +2dbc293b459fc688f5b1f0142af29513 +6c9d88c93056745268869681bc841712 +6187281b1256b9c58cf02160fa6accc3 +c1f3e4291d733d797ecf1b3fc055ed70 +aad59bb9ce34e41d18fd5ebfaf5939b8 +8efafb59efad92ce3d5d1413eb8fe526 +d80fc922c48fcd838b822ac11fb34a60 +3858095e677ffc22bd13c18508b67979 +3f27f6494f878aa39aa6ba702aac7e8b +-----END OpenVPN Static key V1----- -- cgit v1.2.3