From: Thomas Pietrzak Date: Wed, 30 Mar 2011 14:24:34 +0000 (+0000) Subject: Import Haptic Metronome X-Git-Url: https://git.thomaspietrzak.com/?a=commitdiff_plain;h=de08110ce2e38f03d52d621ce304e1b1f8bbb47f;p=hapticmetronome.git Import Haptic Metronome git-svn-id: svn+ssh://thomaspietrzak.com/var/svn/rep@2 47cf9a05-e0a8-4ed5-9e9b-101a649bc004 --- de08110ce2e38f03d52d621ce304e1b1f8bbb47f diff --git a/Makefile b/Makefile new file mode 100644 index 0000000..aebf76f --- /dev/null +++ b/Makefile @@ -0,0 +1,54 @@ +COMP = g++ +RM = rm -f +# VERSION = 3 +OBJS = obj/main.o obj/MIDIReader.o obj/Config.o obj/Track.o obj/Texture.o obj/Vector2D.o obj/Vector3D.o obj/String.o obj/Pair.o obj/Triplet.o obj/Tools.o obj/Mixer.o obj/List.o obj/PrefixTree.o obj/Wiimote.o +#-lefence +#-lSDL -lSDL_image -lGL -lGLU -lusb +# -lefence +# export EF_ALLOW_MALLOC_0=1 +FLAGS = -Wall -pg -DDEBUG +LIBS = -lSDL -lSDL_image -lSDL_mixer -lGL -lGLU -lGLEW -lwiiuse +CFLAGS = $(FLAGS) -Iinclude/ +TARGET = bin/hapticmetronome +TAR = hapticmetronome +REPARCHIVE = hapticmetronome + +all :$(TARGET) + +$(TARGET) : $(OBJS) + $(COMP) $(CFLAGS) -o $@ $^ $(LIBS) + +clean : + $(RM) $(OBJS) + +mrproper : + $(RM) $(OBJS) $(TARGET) $(TARGETDEMO) + +tar: + mkdir $(REPARCHIVE) + mkdir $(REPARCHIVE)/src + mkdir $(REPARCHIVE)/include + mkdir $(REPARCHIVE)/data + mkdir $(REPARCHIVE)/bin + cp Makefile* $(REPARCHIVE)/ + cp data/*.ttf $(REPARCHIVE)/data + cp data/shapes* $(REPARCHIVE)/data + cp data/params $(REPARCHIVE)/data + cp $(TARGET) $(REPARCHIVE)/bin + cp $(TARGET).exe $(REPARCHIVE)/bin + cp src/*.c $(REPARCHIVE)/src + cp include/*.h $(REPARCHIVE)/include + tar -cvzf $(TAR).tar.gz $(REPARCHIVE) + rm -rf $(REPARCHIVE) + +#obj/shapes.o : src/shapes.c +# $(COMP) $(CFLAGS) -o $@ -c $< + +obj/%.o : src/%.c include/%.h + $(COMP) $(CFLAGS) -o $@ -c $< + +obj/%.o : src/%.cpp include/%.hpp + $(COMP) $(CFLAGS) -o $@ -c $< + +obj/%.o : src/%.cpp + $(COMP) $(CFLAGS) -o $@ -c $< diff --git a/include/Config.hpp b/include/Config.hpp new file mode 100644 index 0000000..9c6cd6c --- /dev/null +++ b/include/Config.hpp @@ -0,0 +1,68 @@ +#ifndef __CONFIG__ +#define __CONFIG__ + +enum keys { KEY0 = 0, KEY1 = 1, KEY2 = 2, KEY3 = 3, KEY4 = 4 }; + +#define COLOR_GREEN 0.0f,1.0f,0.0f +#define COLOR_RED 1.0f,0.0f,0.0f +#define COLOR_YELLOW 1.0f,1.0f,0.0f +#define COLOR_BLUE 0.0f,0.0f,1.0f +#define COLOR_ORANGE 1.0f,0.5f,0.0f +// #define SECONDSIZE 3.0 +#define NOTESIZE 1.5 +#define LONGSIZE 0.5 + +#define NECKWIDTH 12 +#define NOTEDIST 5 + +void drawCube(double pos, double size, double colorx, double colory, double colorz); +void drawLong(double pos, double size, double length, double colorx, double colory, double colorz); + +#include +#include +using namespace std; + +#include "String.hpp" +#include "Tools.hpp" + +class Config +{ + public: + Config(double position=0, double end=0, uint32 time=0, uint32 ticks=0,bool a=false, bool b=false, bool c=false, bool d=false, bool e=false) + :_position(position), _end(end), _time(time), _ticks(ticks), _a(a), _b(b), _c(c), _d(d), _e(e){} + + Config(const Config &cf):_position(cf._position), _end(cf._end), _time(cf._time), _ticks(cf._ticks), _a(cf._a), _b(cf._b), _c(cf._c), _d(cf._d), _e(cf._e){} + ~Config(){} + + void addKey(keys k); + void remKey(keys k); + void setKeys(bool a, bool b, bool c, bool d, bool e); + + void setPosition(double p) { _position = p; } + double getPosition() const { return _position; } + + void setEnd(double d) { _end = d; } + double getEnd() const { return _end; } + + void setTime(uint32 t) { _time = t; } + uint32 getTime() const { return _time; } + + void setTicks(uint32 t) { _ticks = t; } + uint32 getTicks() const { return _ticks; } + + void display() const; + void log(const String &type, FILE *file) const; + + Config &operator =(const Config&cfg); + + friend ostream& operator <<(ostream &os,const Config &c); + + bool isNone() const { return !(_a || _b || _c || _d || _e ); } + + private: + double _position, _end; + uint32 _time, _ticks; + bool _a, _b, _c, _d, _e; +}; + +#endif diff --git a/include/List.hpp b/include/List.hpp new file mode 100644 index 0000000..ce9557a --- /dev/null +++ b/include/List.hpp @@ -0,0 +1,148 @@ +/* + * This source file is part of Dungeon Digger + * Website: http://sourceforge.net/projects/dungeondigger/ + * + * Copyright (C) 2006 Dungeon Digger Team + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ +#ifndef __LIST__ +#define __LIST__ + +#include +using namespace std; + +template class List; + +template List &operator+(const T &elt, List &l); +template ostream &operator << (ostream &os, const List &l); + + +template +class List +{ + public: + struct Node + { + T key; + Node *next, *previous; + Node(const T &elt, Node *n, Node *p) + :key(elt), next(n), previous(p) + {} + }; + class ListIterator + { + public: + ListIterator(List &l): _list(&l), _current(&(l.head)) {}; + ListIterator(List &l, bool): _list(&l), _current(&(l.tail)) {}; + void operator++ (int) { if (_current && *_current) _current = &((*_current)->next); } + void operator-- (int) { if (_current && *_current) _current = &((*_current)->previous); } + bool end() const { return *_current == NULL; } + bool beforeEnd() const { return (*_current == NULL || (*_current)->next == NULL); } + bool afterEnd() const { return (*_current == NULL || (*_current)->previous == NULL); } + T &elt() { return (*_current)->key; } + //TODO: test + void add(const T &element) + { + if (_current) + { + if (*_current) + { + *_current = new Node(element, *_current, (*_current)->previous); + (*_current)->next->previous = *_current; + } + else + *_current = new Node(element, NULL, _list->getTail()); + _list->setTail(*_current); + } + else + throw "wrong iterator"; + } + //TODO: test + void remove() + { + if (_current) + { + if (*_current) + { + Node *tbd = *_current; + if ((*_current)->previous) + (*_current)->previous->next = (*_current)->next; + if ((*_current)->next) + (*_current)->next->previous = (*_current)->previous; + delete tbd; + } + else + throw "end of list"; + } + else + throw "wrong iterator"; + } + //void displayDebug() { if (current) cout << " key=" << current->key << " next=" << current->next << " previous=" << current->previous << endl; else cout << " NULL" << endl;} + private: + ListIterator(): _list(NULL), _current(NULL) {} + List *_list; + Node **_current; + }; + + List(); + List(const List &l); + ~List(); + + void empty(); + + T &operator [] (const int &i) const; + + unsigned int size() const; + bool isEmpty() const; + + Node *getHead() const; + void setHead(Node *); + Node *getTail() const; + void setTail(Node *); + + //put the element specified on the top of the list + void onTop(const T&elt); + //put the element specified at the bottom of the list + void onBottom(const T&elt); + + //remove the element specified + List &operator- (const T &elt); + //remove the element of position pos in the list + List &operator- (const int &pos); + + //add an element at the head + friend List &operator+ <>(const T &elt, List &l); + //add an element at the tail + List &operator+ (const T &elt); + List &operator+= (const T &elt); + //concatenate two lists + List &operator+ (const List &l); + List &operator+= (const List &l); + + List &operator= (const List &l); + + friend ostream &operator<< <>(ostream &os, const List &l); + + //friend istream &operator >> (istream & is, const List &l); + protected: + + void deleteElt(Node *elt); + + Node *head, *tail; +}; + +#include "../src/List.cpp" +#endif diff --git a/include/MIDIReader.hpp b/include/MIDIReader.hpp new file mode 100644 index 0000000..a09c8a7 --- /dev/null +++ b/include/MIDIReader.hpp @@ -0,0 +1,35 @@ +#ifndef __MIDIREADER__ +#define __MIDIREADER__ + +#include + +#include "Track.hpp" +#include "String.hpp" +#include "Tools.hpp" + + +class MIDIReader +{ + public: + MIDIReader(const String &f); + ~MIDIReader(); + + void readHeader(); + void skipTrack(); + void readTrack(Track &); + void readTracks(Track &t); + private: + MIDIReader(); + MIDIReader(const MIDIReader &); + + FILE *_file; + uint16 _nbtracks; + uint16 _timedivision; +// unsigned long int _position; + uint8 readVariableLength(uint32 &); + void readBytes(void *, uint32); + void printBytes(uint8 *data, uint32 length); + uint32 _position; +}; + +#endif diff --git a/include/Mixer.hpp b/include/Mixer.hpp new file mode 100644 index 0000000..7725886 --- /dev/null +++ b/include/Mixer.hpp @@ -0,0 +1,94 @@ +/* + * This source file is part of Dungeon Digger + * Website: http://sourceforge.net/projects/dungeondigger/ + * + * Copyright (C) 2006 Dungeon Digger Team + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +#ifndef __MIXER__ +#define __MIXER__ + +#define MAXSOUNDS 5 + +#include "String.hpp" +#include "PrefixTree.hpp" +#ifdef __APPLE__ +#include +#else +#include +#endif + +class Sound +{ + public: + Sound(); + Sound(const String &); + ~Sound(); + + bool addSound(const String &filename); + bool addChunk(Mix_Chunk *c); + Mix_Chunk *mix(); + + Mix_Chunk *getChunk(); + + private: + Sound(const Sound &); + int nbrchunks; + Mix_Chunk **_chunks; +}; + +class Mixer +{ + public: + Mixer(); + ~Mixer(); + static void playMusic(const String &); + static void stopMusic(); + void playSound(const String &); + void stopSound(const int &); + bool addSound(const String &s, const String &filename); + static void channelStopped(int); + int getMusicVolume() const { return _musicVolume; } + void setMusicVolume(const int &); + int getSoundVolume() const { return _soundVolume; } + void setSoundVolume(const int &); + + static void initMixer(); + + static Mixer *getInstance() + { + if (!_minstance) + { + _minstance = new Mixer(); + initMixer(); + } + + return _minstance; + } + + private: + Mixer(const Mixer &); + PrefixTree _sounds; + static Mix_Music *_music; + static int *_soundChannels; + + int _musicVolume, _soundVolume; + + static Mixer *_minstance; +}; + +#endif diff --git a/include/Pair.hpp b/include/Pair.hpp new file mode 100644 index 0000000..d5e5962 --- /dev/null +++ b/include/Pair.hpp @@ -0,0 +1,82 @@ +/* + * This source file is part of Dungeon Digger + * Website: http://sourceforge.net/projects/dungeondigger/ + * + * Copyright (C) 2006 Dungeon Digger Team + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ +#ifndef __PAIR__ +#define __PAIR__ + +#include +using namespace std; + +template class Pair; + +template Pair operator + (const Pair &p1, const Pair &p2); +template Pair operator + (const T &a, const Pair &p); +template Pair operator + (const Pair &p1, const U &a); +template Pair operator - (const Pair &p1, const Pair &p2); +template Pair operator - (const T &a, const Pair &p); +template Pair operator - (const Pair &p1, const U &a); +template Pair operator * (const Pair &p1, const Pair &p2); +template Pair operator * (const T &a, const Pair &p); +template Pair operator * (const Pair &p1, const U &a); +template Pair operator / (const Pair &p1, const Pair &p2); +template Pair operator / (const T &a, const Pair &p); +template Pair operator / (const Pair &p1, const U &a); +template ostream &operator << (ostream &os, const Pair &s); + +template +class Pair +{ + public: + inline Pair(const T &x=0, const U &y=0); + inline Pair(const Pair &p); + inline ~Pair(); + + const T &getX() const; + const U &getY() const; + void setX(const T &x); + void setY(const U &y); + + inline const Pair & operator = (const Pair &s); + bool operator == (const Pair &s) const; + + friend Pair operator + <>(const Pair &p1, const Pair &p2); + friend Pair operator + <>(const T &a, const Pair &p); + friend Pair operator + <>(const Pair &p1, const U &a); + friend Pair operator - <>(const Pair &p1, const Pair &p2); + friend Pair operator - <>(const T &a, const Pair &p); + friend Pair operator - <>(const Pair &p1, const U &a); + Pair operator - (void); + friend Pair operator * <>(const Pair &p1, const Pair &p2); + friend Pair operator * <>(const T &a, const Pair &p); + friend Pair operator * <>(const Pair &p1, const U &a); + friend Pair operator / <>(const Pair &p1, const Pair &p2); + friend Pair operator / <>(const T &a, const Pair &p); + friend Pair operator / <>(const Pair &p1, const U &a); + + friend ostream &operator << <>(ostream &os, const Pair &s); + + protected: + T px; + U py; +}; + +#include "../src/Pair.cpp" + +#endif diff --git a/include/PrefixTree.hpp b/include/PrefixTree.hpp new file mode 100644 index 0000000..5094bc1 --- /dev/null +++ b/include/PrefixTree.hpp @@ -0,0 +1,159 @@ +/* + * This source file is part of Dungeon Digger + * Website: http://sourceforge.net/projects/dungeondigger/ + * + * Copyright (C) 2006 Dungeon Digger Team + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ +#ifndef __PREFIXTREE__ +#define __PREFIXTREE__ + +#include +using namespace std; + +#include "String.hpp" +#include "List.hpp" +#include "Pair.hpp" + +template +class PrefixTree; + +template +ostream &operator << (ostream &os, const PrefixTree &t); + +template +class PrefixTree +{ + public: + struct TNode + { + bool haskey; + T key; + String prefix; + TNode *son, *brotherleft, *brotherright, *father; + TNode(); + TNode(const T &elt, const String &pref, TNode *son, TNode *brotherleft, TNode *brotherright, TNode *father); + TNode(const String &pref, TNode *son, TNode *brotherleft, TNode *brotherright, TNode *father); + + ~TNode(); + + void insertInsideNode(const String &pref, const T &elt, const unsigned int &posword, const unsigned int &posnode); + + String searchInsideNode(const String &pref, const unsigned int &posword, const unsigned int &posnode) const; + + bool nodeExists(const String &n, const unsigned int &posword, const unsigned int &posnode) const; + + const T &getNode(const String &n, const unsigned int &posword, const unsigned int &posnode) const; + + TNode *nextNode(); + + String wholePrefix() const; + + ostream &display(ostream &os); + }; + class PrefixTreeIterator + { + public: + PrefixTreeIterator(PrefixTree &t):pt(&t), current(t.root){} + void operator++(int) + { + do + { + current = current->nextNode(); + }while (current && ! current->haskey); + } + bool end() const { return current == NULL; } + Pair elt() + { + if (current->haskey) + return Pair(current->wholePrefix(), current->key); + else + throw "No key"; + //should not happen + return Pair(); + } + private: + PrefixTree *pt; + TNode *current; + }; + + PrefixTree(); + PrefixTree(const PrefixTree &pt); + virtual ~PrefixTree(); + + void addNode(const String &pref, const T&elt); + void remNode(const T &elt); + bool searchNode(const String &n); + + TNode * getRoot(); + + //currently we dont allow to modify elements like this + //inline T &operator[](const String &key); + inline const T &operator[](const String &key) const; + + List sonsList(const String &pref) const; + String completePrefix(const String &pref) const; + + friend ostream &operator<< <>(ostream &os, const PrefixTree &n); + + protected: + TNode *root; +}; + +class ExceptionNodeDontExist +{ + public: + ExceptionNodeDontExist(const String &s="") + :name(s) + {} + + ExceptionNodeDontExist(const ExceptionNodeDontExist &e) + :name(e.name) + {} + + ~ExceptionNodeDontExist() + {} + + String getName() const + { + return name; + } + + private: + String name; +}; + +// template +// ostream &operator << (ostream &os, const typename PrefixTree::TNode &n) +// { +// if (n.key) +// os << "[" << *(n.key) << "]"; +// else +// os << "X"; +// os << " " << n.prefix << " "; +// if (n.son) +// os << " (" << *(n.son) << ")"; +// if (n.brother) +// os << " {" << *(n.brother) << "}"; +// return os; +// } + + +// template +// ostream &operator<< <>(ostream &os, const typename PrefixTree::TNode &n); + +#include "../src/PrefixTree.cpp" +#endif diff --git a/include/String.hpp b/include/String.hpp new file mode 100644 index 0000000..024eb3a --- /dev/null +++ b/include/String.hpp @@ -0,0 +1,61 @@ +/* + * This source file is part of Dungeon Digger + * Website: http://sourceforge.net/projects/dungeondigger/ + * + * Copyright (C) 2006 Dungeon Digger Team + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ +#ifndef __MYSTRING__ +#define __MYSTRING__ + +#include +#include +using namespace std; + +class String +{ + public: + String(const String &s); + String(const int &a); + String(const double &a); + String(const char *s=""); + String(const char &c); + ~String(); + + unsigned int length() const; + void concat(const String &s); + //find + + const char *c_str() const; + + const String & operator = (const String &s); + bool operator == (const String &s) const; + bool operator != (const String &s) const; + + //returns the character i + char &operator [] (const int &i) const; + //returns the substring at pos i, and of length j + String operator () (const unsigned int &i, const unsigned int &j) const; + + friend String operator + (const String &s1, const String &s2); + friend ostream &operator << (ostream &os, const String &s); + //friend istream &operator >> (istream & is, const String &s); + + private: + char *string; +}; + +#endif diff --git a/include/Texture.hpp b/include/Texture.hpp new file mode 100644 index 0000000..ee7058a --- /dev/null +++ b/include/Texture.hpp @@ -0,0 +1,49 @@ +/* + * This source file is part of Dungeon Digger + * Website: http://sourceforge.net/projects/dungeondigger/ + * + * Copyright (C) 2006 Dungeon Digger Team + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ +#ifndef __TEXTURE__ +#define __TEXTURE__ + +#include +#include +// #include + +#include "String.hpp" +#include "Vector2D.hpp" + +class Texture +{ + public: + Texture(const String &filename, const bool &repeat=false); + ~Texture(); + + void useTexture() const; + bool isLoaded() const; + Vector2D getSize() const; + + private: + SDL_Surface *surface; + unsigned int gltex; + GLuint texture; + Vector2D size; + bool repeat; +}; + +#endif diff --git a/include/Tools.hpp b/include/Tools.hpp new file mode 100644 index 0000000..b5e55bb --- /dev/null +++ b/include/Tools.hpp @@ -0,0 +1,57 @@ +/* + * This source file is part of Dungeon Digger + * Website: http://sourceforge.net/projects/dungeondigger/ + * + * Copyright (C) 2006 Dungeon Digger Team + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ +#ifndef __MYTOOLS__ +#define __MYTOOLS__ + +typedef unsigned char uint8; +typedef unsigned short uint16; +typedef unsigned int uint32; + +#include "String.hpp" +#include "Vector2D.hpp" +#include + +#define MAX(X,Y) (X)>(Y)?(X):(Y) +#define MIN(X,Y) (X)<(Y)?(X):(Y) + +bool fileExists(const String &f); +bool dirExists(const String &d); +Vector2D rotatePoint(const Vector2D pos, const Vector2D center, const double &angle); + +templateT maxi(const T&a, const T&b) +{ + if (a>b) + return a; + else + return b; +} + +templateT mini(const T&a, const T&b) +{ + if (a +#include +/*#include +using namespace std; +*/ +#include "Config.hpp" +#include "Tools.hpp" + +class Track +{ + public: + Track(); + Track(const Track &); + ~Track(); + + void addKey(uint32 time, uint8 note); + void remKey(uint32 time, uint8 note); + + void addTempo(uint32 pos, uint32 t) { _tempo[pos] = t; } + +// int getTempo() const { return _currenttempo; } + +// void setTempo(uint32 t) { _currenttempo = t; } + +// uint32 beatsToTicks(uint32 time) { return (time * _currenttempo * 480) / 60000.0; } + uint32 beatsToTicks(uint32 time, uint32 tempo) { return (time * tempo * 480) / 60000.0; } + uint32 ticksToBeats(uint32 time) { return 60000000 / time; } + + void displayTracks(); + void drawFrets(double postime) const; + void drawNotes(double postime, uint8 diff) const; + + uint32 getNbNotes(uint32 k) const { return _nbnotes[k]; } + uint32 getTotalLength(uint32 k) const { return _totallength[k]; } + uint32 getTotalNotes(uint32 k) const { return _totalnotes[k]; } + + void setEndOfTrack(uint32 length) { if (length > _trackSize) _trackSize = length; } + uint32 getEndOfTrack() const { return _trackSize; } + + Config getNote(uint32 pos, uint8 difficulty); + uint32 getTempo(uint32 pos); + + void computeBips(); + + void debugTempo(); + + private: + //notes : position ; configs + map _notes[NBDIFFICULTIES]; + map _tempo; + +// private: + list _bips; + + Config _currentconfig[NBDIFFICULTIES]; + + uint32 _nbnotes[NBDIFFICULTIES]; + uint32 _totallength[NBDIFFICULTIES]; + uint32 _totalnotes[128]; + uint32 _trackSize; + bool _active; +}; + +#endif diff --git a/include/Triplet.hpp b/include/Triplet.hpp new file mode 100644 index 0000000..fbb0678 --- /dev/null +++ b/include/Triplet.hpp @@ -0,0 +1,85 @@ +/* + * This source file is part of Dungeon Digger + * Website: http://sourceforge.net/projects/dungeondigger/ + * + * Copyright (C) 2006 Dungeon Digger Team + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ +#ifndef __TRIPLET__ +#define __TRIPLET__ + +#include +using namespace std; + +template class Triplet; + +template Triplet operator + (const Triplet &p1, const Triplet &p2); +template Triplet operator + (const T &a, const Triplet &p); +template Triplet operator + (const Triplet &p1, const U &a); +template Triplet operator - (const Triplet &p1, const Triplet &p2); +template Triplet operator - (const T &a, const Triplet &p); +template Triplet operator - (const Triplet &p1, const U &a); +template Triplet operator * (const Triplet &p1, const Triplet &p2); +template Triplet operator * (const T &a, const Triplet &p); +template Triplet operator * (const Triplet &p1, const U &a); +template Triplet operator / (const Triplet &p1, const Triplet &p2); +template Triplet operator / (const T &a, const Triplet &p); +template Triplet operator / (const Triplet &p1, const U &a); +template ostream &operator << (ostream &os, const Triplet &s); + +template +class Triplet +{ + public: + inline Triplet(const T &x=0, const U &y=0, const V &z=0); + inline Triplet(const Triplet &p); + inline ~Triplet(); + + const T &getX() const; + const U &getY() const; + const V &getZ() const; + void setX(const T &x); + void setY(const U &y); + void setZ(const V &z); + + inline const Triplet & operator = (const Triplet &s); + bool operator == (const Triplet &s) const; + + friend Triplet operator + <>(const Triplet &p1, const Triplet &p2); + friend Triplet operator + <>(const T &a, const Triplet &p); + friend Triplet operator + <>(const Triplet &p1, const U &a); + friend Triplet operator - <>(const Triplet &p1, const Triplet &p2); + friend Triplet operator - <>(const T &a, const Triplet &p); + friend Triplet operator - <>(const Triplet &p1, const U &a); + Triplet operator - (void); + friend Triplet operator * <>(const Triplet &p1, const Triplet &p2); + friend Triplet operator * <>(const T &a, const Triplet &p); + friend Triplet operator * <>(const Triplet &p1, const U &a); + friend Triplet operator / <>(const Triplet &p1, const Triplet &p2); + friend Triplet operator / <>(const T &a, const Triplet &p); + friend Triplet operator / <>(const Triplet &p1, const U &a); + + friend ostream &operator << <>(ostream &os, const Triplet &s); + + protected: + T px; + U py; + V pz; +}; + +#include "../src/Triplet.cpp" + +#endif diff --git a/include/Vector2D.hpp b/include/Vector2D.hpp new file mode 100644 index 0000000..8ac544c --- /dev/null +++ b/include/Vector2D.hpp @@ -0,0 +1,92 @@ +/* + * This source file is part of Dungeon Digger + * Website: http://sourceforge.net/projects/dungeondigger/ + * + * Copyright (C) 2006 Dungeon Digger Team + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ +#ifndef __VECTOR2D__ +#define __VECTOR2D__ + +#include "Pair.hpp" +/* +#include +using namespace std;*/ + +template class Vector2D; + +template Vector2D operator + (const Vector2D &p1, const Vector2D &p2); +template Vector2D operator + (const T &a, const Vector2D &p); +template Vector2D operator + (const Vector2D &p1, const T &a); +template Vector2D operator - (const Vector2D &p1, const Vector2D &p2); +template Vector2D operator - (const T &a, const Vector2D &p); +template Vector2D operator - (const Vector2D &p1, const T &a); +template Vector2D operator * (const Vector2D &p1, const Vector2D &p2); +template Vector2D operator * (const T &a, const Vector2D &p); +template Vector2D operator * (const Vector2D &p1, const T &a); +template Vector2D operator / (const Vector2D &p1, const Vector2D &p2); +template Vector2D operator / (const T &a, const Vector2D &p); +template Vector2D operator / (const Vector2D &p1, const T &a); +// template ostream &operator << (ostream &os, const Vector2D &s); + +enum { C_X=0, C_Y=1, C_Z=2 }; + +template +class Vector2D: public Pair +{ + public: + inline Vector2D(const T &x=0, const T &y=0); + inline Vector2D(const Vector2D &p); + inline ~Vector2D(); + +/* + T getX() const; + T getY() const; + void setX(const T &x); + void setY(const T &y);*/ + + inline T &operator [] (const int &i); + inline const T &operator [] (const int &i) const; + + +// const Vector2D & operator = (const Vector2D &s); +// bool operator == (const Vector2D &s) const; + + friend Vector2D operator + <>(const Vector2D &p1, const Vector2D &p2); + friend Vector2D operator + <>(const T &a, const Vector2D &p); + friend Vector2D operator + <>(const Vector2D &p1, const T &a); + friend Vector2D operator - <>(const Vector2D &p1, const Vector2D &p2); + friend Vector2D operator - <>(const T &a, const Vector2D &p); + friend Vector2D operator - <>(const Vector2D &p1, const T &a); + Vector2D operator - (void); + friend Vector2D operator * <>(const Vector2D &p1, const Vector2D &p2); + friend Vector2D operator * <>(const T &a, const Vector2D &p); + friend Vector2D operator * <>(const Vector2D &p1, const T &a); + friend Vector2D operator / <>(const Vector2D &p1, const Vector2D &p2); + friend Vector2D operator / <>(const T &a, const Vector2D &p); + friend Vector2D operator / <>(const Vector2D &p1, const T &a); +// +// friend ostream &operator << <>(ostream &os, const Vector2D &s); + + private: +// T px, py; +}; + +#include "../src/Vector2D.cpp" + +#include "Vector3D.hpp" + +#endif diff --git a/include/Vector3D.hpp b/include/Vector3D.hpp new file mode 100644 index 0000000..b6db366 --- /dev/null +++ b/include/Vector3D.hpp @@ -0,0 +1,75 @@ +/* + * This source file is part of Dungeon Digger + * Website: http://sourceforge.net/projects/dungeondigger/ + * + * Copyright (C) 2006 Dungeon Digger Team + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ +#ifndef __VECTOR3D__ +#define __VECTOR3D__ + +#include "Triplet.hpp" +/* +#include +using namespace std;*/ + +template class Vector3D; + +template Vector3D operator + (const Vector3D &p1, const Vector3D &p2); +template Vector3D operator + (const T &a, const Vector3D &p); +template Vector3D operator + (const Vector3D &p1, const T &a); +template Vector3D operator - (const Vector3D &p1, const Vector3D &p2); +template Vector3D operator - (const T &a, const Vector3D &p); +template Vector3D operator - (const Vector3D &p1, const T &a); +template Vector3D operator * (const Vector3D &p1, const Vector3D &p2); +template Vector3D operator * (const T &a, const Vector3D &p); +template Vector3D operator * (const Vector3D &p1, const T &a); +template Vector3D operator / (const Vector3D &p1, const Vector3D &p2); +template Vector3D operator / (const T &a, const Vector3D &p); +template Vector3D operator / (const Vector3D &p1, const T &a); +// template ostream &operator << (ostream &os, const Vector3D &s); + +template +class Vector3D: public Triplet +{ + public: + // passé en inline pour voir impact sur performance... + inline Vector3D(const T &x=0, const T &y=0, const T &z=0); + inline Vector3D(const Vector3D &p); + inline ~Vector3D(); + + inline T &operator [] (const int &i); + inline const T &operator [] (const int &i) const; + + friend Vector3D operator + <>(const Vector3D &p1, const Vector3D &p2); + friend Vector3D operator + <>(const T &a, const Vector3D &p); + friend Vector3D operator + <>(const Vector3D &p1, const T &a); + friend Vector3D operator - <>(const Vector3D &p1, const Vector3D &p2); + friend Vector3D operator - <>(const T &a, const Vector3D &p); + friend Vector3D operator - <>(const Vector3D &p1, const T &a); + Vector3D operator - (void); + friend Vector3D operator * <>(const Vector3D &p1, const Vector3D &p2); + friend Vector3D operator * <>(const T &a, const Vector3D &p); + friend Vector3D operator * <>(const Vector3D &p1, const T &a); + friend Vector3D operator / <>(const Vector3D &p1, const Vector3D &p2); + friend Vector3D operator / <>(const T &a, const Vector3D &p); + friend Vector3D operator / <>(const Vector3D &p1, const T &a); + + private: +}; + +#include "../src/Vector3D.cpp" +#endif diff --git a/include/Wiimote.hpp b/include/Wiimote.hpp new file mode 100644 index 0000000..0fdc1cb --- /dev/null +++ b/include/Wiimote.hpp @@ -0,0 +1,34 @@ +#ifndef __WIIMOTE__ +#define __WIIMOTE__ + +#ifndef WIN32 + #include +#endif + +#include + + +#define MAX_WIIMOTES 4 + +class Wiimote{ + public: + Wiimote(int nb=1); + + void handleEvents(); + + void vibration(int wiimote, int time); + + virtual void handleStrumOn() = 0; + virtual void handleStrumOff() = 0; + virtual void handleButtonOn(int k) = 0; + virtual void handleButtonOff(int k) = 0; + virtual void handleButtons(bool a, bool b, bool c, bool d, bool e) = 0; + + private: + void handleKey(guitar_hero_3_t* gh3, int key, int button); + wiimote **_wiimotes; + int _nb; + bool _strumstate, _keystate[5]; +}; + +#endif diff --git a/src/Config.cpp b/src/Config.cpp new file mode 100644 index 0000000..95e035e --- /dev/null +++ b/src/Config.cpp @@ -0,0 +1,134 @@ +#include "Config.hpp" +#include + +void Config::addKey(keys k) +{ + switch(k) + { + case KEY0: + _a = true; + break; + case KEY1: + _b = true; + break; + case KEY2: + _c = true; + break; + case KEY3: + _d = true; + break; + case KEY4: + _e = true; + break; + } +} + +void Config::remKey(keys k) +{ + switch(k) + { + case KEY0: + _a = false; + break; + case KEY1: + _b = false; + break; + case KEY2: + _c = false; + break; + case KEY3: + _d = false; + break; + case KEY4: + _e = false; + break; + } +} + +void Config::setKeys(bool a, bool b, bool c, bool d, bool e) +{ + _a = a; + _b = b; + _c = c; + _d = d; + _e = e; +} + +void Config::display() const +{ + if (_ticks > 240) + { + if (_a) + drawLong(-2*NOTEDIST, LONGSIZE, _end - _position, COLOR_GREEN); + if (_b) + drawLong(-NOTEDIST, LONGSIZE, _end - _position, COLOR_RED); + if (_c) + drawLong(0, LONGSIZE, _end - _position, COLOR_YELLOW); + if (_d) + drawLong(NOTEDIST, LONGSIZE, _end - _position, COLOR_BLUE); + if (_e) + drawLong(2*NOTEDIST, LONGSIZE, _end - _position, COLOR_ORANGE); + } + + if (_a) + drawCube(-2*NOTEDIST, NOTESIZE, COLOR_GREEN); + if (_b) + drawCube(-NOTEDIST, NOTESIZE, COLOR_RED); + if (_c) + drawCube(0, NOTESIZE, COLOR_YELLOW); + if (_d) + drawCube(NOTEDIST, NOTESIZE, COLOR_BLUE); + if (_e) + drawCube(2*NOTEDIST, NOTESIZE, COLOR_ORANGE); +} + +void Config::log(const String &type, FILE *file) const +{ + if (!file) + return; + fprintf(file, "%s;%d;%d;%d;%d;%d;%f;%f;%d;%d\n", type.c_str(), _a, _b, _c, _d, _e, _position, _end, _time, _ticks); +} + +Config &Config::operator =(const Config&cfg) +{ + if (&cfg != this) + { + _a = cfg._a; + _b = cfg._b; + _c = cfg._c; + _d = cfg._d; + _e = cfg._e; + _position = cfg._position; + _end = cfg._end; + _time = cfg._time; + _ticks = cfg._ticks; + } + return *this; +} + +ostream& operator <<(ostream &os,const Config &c) +{ +// os << c._time << " "; + if (c._a) + os << "\033[1;32mO\033[0m"; + else + os << "\033[1;32m.\033[0m"; + if (c._b) + os << "\033[0;31mO\033[0m"; + else + os << "\033[0;31m.\033[0m"; + if (c._c) + os << "\033[1;33mO\033[0m"; + else + os << "\033[1;33m.\033[0m"; + if (c._d) + os << "\033[1;34mO\033[0m"; + else + os << "\033[1;34m.\033[0m"; + if (c._e) + os << "\033[0;33mO\033[0m"; + else + os << "\033[0;33m.\033[0m"; + os << " " << c._position << " " << c._end; + return os; +} diff --git a/src/List.cpp b/src/List.cpp new file mode 100644 index 0000000..4dbc8dc --- /dev/null +++ b/src/List.cpp @@ -0,0 +1,292 @@ +/* + * This source file is part of Dungeon Digger + * Website: http://sourceforge.net/projects/dungeondigger/ + * + * Copyright (C) 2006 Dungeon Digger Team + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ +#ifdef __LIST__ + +template +List::List() +:head(NULL), tail(NULL) +{ +} + +template +List::List(const List &l) +{ + Node *temp = l.head; + head = NULL; + tail = NULL; + while(temp) + { + Node *newnode = new Node(temp->key, NULL, tail); + if (!head) + head = newnode; + if (tail) + tail->next = newnode; + tail = newnode; + temp = temp->next; + } +} + +template +List::~List() +{ + empty(); +} + +template +void List::empty() +{ + Node *temp = head; + while(temp) + { + Node *temp2 = temp; + temp = temp->next; + delete temp2; + } + head = NULL; + tail = NULL; +} + +template +T &List::operator [] (const int &i) const +{ + int j; + Node *temp = head; + for (j = 0 ; j < i && temp ; j++) + temp = temp->next; + if (j == i) + return temp->key; + else + throw "Index out of range"; +} + +template +unsigned int List::size() const +{ + Node *temp = head; + int s=0; + while(temp) + { + s++; + temp = temp->next; + } + return s; +} + +template +bool List::isEmpty() const +{ + return head == NULL; +} + +template +typename List::Node *List::getHead() const +{ + return head; +} + +template +void List::setHead(typename List::Node *n) +{ + head = n; +} + +template +typename List::Node *List::getTail()const +{ + return tail; +} + +template +void List::setTail(typename List::Node *n) +{ + tail = n; +} + +template +void List::onTop(const T&elt) +{ + Node *temp = tail; + while(temp && temp != head) + { + if (temp->key == elt) + { + if (temp->next) + temp->next->previous = temp->previous; + if (temp->previous) + temp->previous->next = temp->next; + if (temp == tail) + tail = temp->previous; + head->previous = temp; + temp->next = head; + temp->previous = NULL; + head = temp; + break; + } + temp = temp->previous; + } +} + +template +void List::onBottom(const T&elt) +{ + *this = *this - elt + elt; +} + +template +void List::deleteElt(typename List::Node *elt) +{ + if (elt->previous) + elt->previous->next = elt->next; + else + head = elt->next; + if (elt->next) + elt->next->previous = elt->previous; + else + tail = elt->previous; + delete elt; +} + +template +List &List::operator- (const T &elt) +{ + Node *temp = head; + while(temp) + { + if (temp->key == elt) + { + deleteElt(temp); + return *this; + } + temp = temp->next; + } + return *this; +} + +template +List &List::operator- (const int &pos) +{ + int i; + Node *temp = head; + for (i = 0 ; i < pos && temp ; i++) + temp = temp->next; + if (i == pos) + { + deleteElt(temp); + return *this; + } + else + throw "Index out of range"; +} + +template +List &operator+ (const T &elt, List &l) +{ + typename List::Node *newnode = new typename List::Node(elt, l.getHead(), NULL); + if (l.isEmpty()) + l.setTail(newnode); + else + l.getHead()->previous = newnode; + l.setHead(newnode); + return l; +} + +template +List &List::operator+ (const T &elt) +{ + Node *newnode = new Node(elt, NULL, tail); + if (isEmpty()) + head = newnode; + else + tail->next = newnode; + tail = newnode; + return *this; +} + +template +List &List::operator+= (const T &elt) +{ + return *this + elt; +} + +//TODO: use iterators +template +List &List::operator+ (const List &l) +{ + Node *temp = l.head; + while(temp) + { + *this = *this + temp->key; + temp = temp->next; + } + return *this; +} + +//TODO: use iterators +template +List &List::operator+= (const List &l) +{ + Node *temp = l.head; + while(temp) + { + *this = *this + temp->key; + temp = temp->next; + } + return *this; +} + +template +List &List::operator= (const List &l) +{ + if (this != &l) + { + empty(); + Node *temp = l.head; + head = NULL; + tail = NULL; + while(temp) + { + Node *newnode = new Node(temp->key, tail, NULL); + if (!head) + head = newnode; + if (tail) + tail->next = newnode; + tail = newnode; + temp = temp->next; + } + } + return *this; +} + +template +ostream &operator<< (ostream &os, const List &l) +{ + typename List::Node *temp = l.getHead(); + while(temp) + { + os << temp->key; + if (temp->next) + os << ", "; + temp = temp->next; + } + return os; +} + +#endif diff --git a/src/MIDIReader.cpp b/src/MIDIReader.cpp new file mode 100644 index 0000000..7ccb818 --- /dev/null +++ b/src/MIDIReader.cpp @@ -0,0 +1,387 @@ +// For format explanation, see http://www.sonicspot.com/guide/midifiles.html + +#include +#include +#include +using namespace std; +#include + +#include "Tools.hpp" + +MIDIReader::MIDIReader() +:_file(NULL), _nbtracks(0), _timedivision(0), _position(0) +{ +} + +MIDIReader::MIDIReader(const String &filename) +:_nbtracks(0), _timedivision(0), _position(0) +{ + String buffer; + if (fileExists(filename)) + buffer = filename; + else if (fileExists("data/songs/" + filename)) + buffer = "data/songs/" + filename; + else if (fileExists("../data/songs/" + filename)) + buffer = "../data/songs/" + filename; + else if (fileExists("data/songs/" + filename)) + buffer = "data/songs/" + filename; + + if (buffer == "" || (_file = fopen(buffer.c_str(), "rb")) == NULL) + { + cerr << "Could not open file " << filename << " buffer=" << buffer << endl; + perror("error:"); + throw 0; + } +} + +MIDIReader::MIDIReader(const MIDIReader &m) +: _file(m._file), _nbtracks(m._nbtracks), _timedivision(m._timedivision), _position(m._position) +{ +} + +MIDIReader::~MIDIReader() +{ + if (_file) + fclose(_file); +} + +void MIDIReader::readHeader() +{ + if (!_file) + return; + + uint8 temp[4]; + + //read the chunk ID + fread((void *)(temp), 1, 4, _file); + if (strncmp((char *)temp, "MThd", 4) != 0) + { + cerr << "Wrong chunk '" << (char)temp[0] << (char)temp[1] << (char)(char)temp[2] << (char)temp[3] << "'" << endl; + return; + } + + //read the chunk size + uint32 chunksize; + readBytes(&chunksize, 4); + cout << "Header size: " << chunksize << endl; + + //read the format + uint16 format; + readBytes(&format, 2); + cout << "Format type: " << format << endl; + + //read the format + readBytes(&_nbtracks, 2); + cout << "Nb of tracks: " << _nbtracks << endl; + + //read the format + readBytes(&_timedivision, 2); + cout << "Time division: " << _timedivision << endl; + + //In theory there is no more than 6 bytes in the header... + if (chunksize > 6) + cout << (chunksize - 6) << "more bytes in the header" << endl; +} + +void MIDIReader::skipTrack() +{ + uint8 temp[4]; + //read the chunk ID + fread((void *)(temp), 4, 1, _file); +// cerr << temp << endl; + if (strncmp((char *)temp, "MTrk", 4) != 0) + { + cerr << "Wrong track chunk '" << (char)temp[0] << (char)temp[1] << (char)temp[2] << (char)temp[3] << "'" << endl; + return; + } + + //read the chunk size + uint32 chunksize; + readBytes(&chunksize, 4); + cout << "Chunk size: " << chunksize << endl; + fseek(_file, chunksize, SEEK_CUR); + cout << "Track Skipped" << endl; +} + +void MIDIReader::readTrack(Track &tr) +{ + uint8 temp[4]; + //read the chunk ID + fread((void *)(temp), 4, 1, _file); +// cerr << temp << endl; + if (strncmp((char *)temp, "MTrk", 4) != 0) + { + cerr << "Wrong track chunk '" << (char)temp[0] << (char)temp[1] << (char)temp[2] << (char)temp[3] << "'" << endl; + return; + } + + //read the chunk size + uint32 chunksize; + readBytes(&chunksize, 4); + cout << "Chunk size: " << chunksize << endl; + +// unsigned long + _position = 0; + +// char temp2[4]; +// readBytes(&te) +// fread(&temp2, 4, 1, _file); +// readBytes((char *)(&temp2),4); +// printf("TEMP : %0x %0x %0x %0x\n", temp2[0], temp2[1], temp2[2], temp2[3]); + bool end = false; + uint8 oldeventandchannel = 0; + uint32 timestamp = 0; + +// Track example; + + //Read the events + while (_position < chunksize) + { + uint32 delta; + //The delta is a variable-length stuff + /*uint8 nblus = */readVariableLength(delta); + + timestamp += delta; + + uint8 eventandchannel, tempevt; + // 4 bits for event type, and 4 others for the channel + readBytes(&tempevt, 1); + fseek(_file, -1, SEEK_CUR); + _position--; + + if (tempevt & 0x80) + { + readBytes(&eventandchannel, 1); + if ((tempevt & 0xf0) != 0xf0) + oldeventandchannel = eventandchannel; + } + else +// { + eventandchannel = oldeventandchannel; +// } + + //Meta events + if ((eventandchannel & 0xff) == 0xff) + { + if (end) + cerr << "EXTRA EVT "; + uint8 type; + readBytes(&type, 1); + + uint32 length; + /*uint8 nblus = */readVariableLength(length); + + uint8 *data = new uint8[length]; + readBytes(data, length); + uint32 tempo = 0; + + switch(type) + { + case 0x00: + cout << "Sequence number: " << data[0] << " ; " << data[1] << endl; + break; + case 0x01: + cout << "Text: "; + printBytes(data, length); + break; + case 0x02: + cout << "Copyright: "; + printBytes(data, length); + break; + case 0x03: + cout << "Track name: "; + printBytes(data, length); + break; + case 0x04: + cout << "Instrument name: "; + printBytes(data, length); + break; + case 0x05: + cout << "Lyrics: "; + printBytes(data, length); + break; + case 0x06: + cout << "Maker: "; + printBytes(data, length); + break; + case 0x07: + cout << "Cue point: "; + printBytes(data, length); + break; + case 0x20: + cout << "MIDI Channel prefix: " << data << endl; + break; + case 0x2F: + cout << "End of track at " << timestamp << endl; + tr.setEndOfTrack(timestamp); + end = true; + break; + case 0x51: + tempo = ((int(data[2]) << 16) + (int(data[1]) << 8) + int(data[0])); + cout << "Tempo at " << timestamp << " : x=" << tempo << "=" << 60000000 / tempo << "bpm" << endl; + tr.addTempo(timestamp, tempo); + break; + case 0x58: + cout << "Time signature: " << int(data[3]) << "|" << int(data[2]) << " " << int(data[1]) << " ticks " << int(data[0]) << "x" << endl; + break; + case 0x59: + cout << "Key signature: " << int(data[1]) << " " << int(data[0]) << endl; + break; + case 0x7F: + cout << "Sequencer stuff!" << endl; + break; + default: + printf("Unknown chunk: %0x, size=%d\n", type, length); + break; + } + delete []data; + } + //System Data + else if ((eventandchannel & 0xf0) == 0xf0)// || (eventandchannel & 0xff) == 0xf7) + { + //May be something else + uint32 length; + readVariableLength(length); + uint8 *data = new uint8[length]; + readBytes(data, length); + printf("System data\n"); + delete []data; + } + //Other events + else + { +// printf("Evt : %x %x %x\n", eventandchannel & 0xf0, eventandchannel & 0x0f, eventandchannel); + uint8 par1, par2; +// position += 2; +// char *notenames[] = {"C", "C#", "D", "D#", "E", "F", "F#", "G", "G#", "A", "A#", "B"}; + switch(eventandchannel & 0xf0) + { + ///Note ON + case 0x80: + readBytes(&par1, 1); + readBytes(&par2, 1); +// printf("- Delta : %4d ; Note %s%d (%02x) off, velocity=%d, channel=%d\n", delta, notenames[par1 % 12], par1 / 12, par1+0, par2+0, eventandchannel & 0x0f); + tr.remKey(timestamp, par1); +// tr.addKey(delta, par1); +// cout << "Note " << notenames[int(par1) % 12] << (int(par1) / 12) << " (" << << ") off, velocity=" << int(par2) << " channel " << (eventandchannel & 0x0f) << endl; + break; + ///Note OFF + case 0x90: + readBytes(&par1, 1); + readBytes(&par2, 1); +// printf("+ Delta : %4d ; Note %s%d (%02x) on, velocity=%d, channel=%d\n", delta, notenames[par1 % 12], par1 / 12, par1+0, par2+0, eventandchannel & 0x0f); + if (par2 > 0) + tr.addKey(timestamp, par1); + else + tr.remKey(timestamp, par1); +// printf("Delta : %4ld ; ", delta); +// cout << "Note " << notenames[int(par1) % 12] << (int(par1) / 12 )<< " on, velocity=" << int(par2) << " channel " << (eventandchannel & 0x0f) << endl; + break; + case 0xA0: + readBytes(&par1, 1); + readBytes(&par2, 1); + printf("Delta : %4d ; Note Aftertouch\n", delta); + break; + case 0xB0: + readBytes(&par1, 1); + readBytes(&par2, 1); + printf("Delta : %4d ; Controller\n", delta); + break; + case 0xC0: + readBytes(&par1, 1); + printf("Delta : %4d ; Program Change\n", delta); + break; + case 0xD0: + readBytes(&par1, 1); + printf("Delta : %4d ; Channel Aftertouch\n", delta); + break; + case 0xE0: + readBytes(&par1, 1); + readBytes(&par2, 1); + printf("Delta : %4d ; Pitch Bend\n", delta); + break; + default: + readBytes(&par1, 1); + printf("Delta : %4d ; Other event : %x, channel %x\n", delta, (eventandchannel & 0xf0) >> 4, eventandchannel & 0x0f); +// cout << endl; + break; + } + } +// printf("Delta : %d, Event %4x on channel %d, par1 = %d, par2 = %d\n", delta, eventandchannel >> 4, eventandchannel & 0x0f, par1, par2); + } +// tr.displayTracks(); +} + +void MIDIReader::readTracks(Track &t)//, int &nb) +{ +/* Track tracks[_nbtracks]; + for (int i=0 ; i < _nbtracks ; i++) + { + cout << "Reading Track " << i << endl; + readTrack(tracks[i]); + }*/ + +// Track t; + //read tempos + readTrack(t); + //read notes + readTrack(t); + //skip other tracks + for (int i = 2 ; i < _nbtracks ; i++) + { + cout << "Skipping Track " << i << endl; + skipTrack(); + } + + + cout << "Stats Track " << endl; + for (int j = 0 ; j < NBDIFFICULTIES ; j++) + { + cout << " Difficulty " << j << " "; + cout << t.getNbNotes(j) << " notes "; + cout << " l=" << t.getTotalLength(j) << endl; + } + +// t.debugTempo(); + + int total = 0; + cout << "Notes : "; + for (int j = 0 ; j < 128 ; j++) + { + cout << j << ":" << t.getTotalNotes(j) << " "; + total += t.getTotalNotes(j); + } + cout << endl << "Total : " << total << endl; +} + +uint8 MIDIReader::readVariableLength(uint32 &nb) +{ + uint8 nblus = 0; + nb = 0; + uint8 temp; + do + { + fread((void *)(&temp), 1, 1, _file); + nb = (nb << 7) | (temp & 0x7f); + nblus++; + } + while (temp & 0x80 && nblus < 4); + _position += nblus; + return nblus; +} + +void MIDIReader::readBytes(void *data, uint32 nb) +{ + uint8 temp[nb]; + fread((void *)(&temp), nb, 1, _file); + for (uint32 i=0 ; iallocated = _chunks[0]->allocated; + m->alen = _chunks[0]->alen; + m->abuf = new Uint8[m->alen]; + m->volume = _chunks[0]->volume; + for (Uint32 i = 0 ; i < m->alen ; i++) + { + printf("%d/%d\r",i, m->alen); + m->abuf[i] = 0; + for (int j = 0 ; j < nbrchunks ; j++) + m->abuf[i] += _chunks[j]->abuf[i] / nbrchunks; + } + return m; +} + +Mix_Music *Mixer::_music = NULL; +Mixer *Mixer::_minstance = NULL; +int *Mixer::_soundChannels = NULL; + +Mixer::Mixer() +:/*_music(NULL), *//*_soundChannels(new int[MAXSOUNDS]),*/ _musicVolume(-1), _soundVolume(-1) +{ + if (!_soundChannels) + _soundChannels = new int[MAXSOUNDS]; + for (int i = 0 ; i < MAXSOUNDS ; i++) + _soundChannels[i] = -1; + Mix_ChannelFinished(channelStopped); +} + +Mixer::Mixer(const Mixer &m) +:_sounds(m._sounds)/*, _music(m._music)*//*, _soundChannels(new int[MAXSOUNDS])*/ +{ + if (!_soundChannels) + _soundChannels = new int[MAXSOUNDS]; + for (int i = 0 ; i < MAXSOUNDS ; i++) + _soundChannels[i] = m._soundChannels[i]; +} + +Mixer::~Mixer() +{ + for (int i = 0 ; i < MAXSOUNDS ; i++) + if (_soundChannels[i] >=0) + stopSound(i); + delete _soundChannels; + //TODO: destroy the Sounds... + //for the moment we never unload Sounds... + if (_music) + stopMusic(); +} + + +void Mixer::initMixer() +{ +/* list::iterator it; + for(it=cc.l.begin();it!=cc.l.end();++it) { + if(it->match("SOUND")) { + string n,f; + it->tail() >> n >> f; + _minstance->addSound(n.c_str(),f.c_str()); + } + }*/ +} + +void Mixer::playMusic(const String &filename) +{ + //_debug_(stderr, "playMusic(%s)\n",filename.c_str()); + if (_music) + { + Mix_HaltMusic(); + Mix_FreeMusic(_music); + } + String buffer; + if (fileExists(filename)) + buffer = filename; + else if (fileExists("data/sounds/" + filename)) + buffer = "data/sounds/" + filename; + else if (fileExists("../data/sounds/" + filename)) + buffer = "../data/sounds/" + filename; + else if (fileExists("data/songs/" + filename)) + buffer = "data/songs/" + filename; + else if (fileExists("../data/songs/" + filename)) + buffer = "../data/songs/" + filename; + + if (buffer != "") + { + _music = Mix_LoadMUS(buffer.c_str()); + if(_music==NULL) + fprintf(stderr, "cannot load music %s\n",buffer.c_str()); + else + { + Mix_PlayMusic(_music, -1); + Mix_HookMusicFinished(stopMusic); + } + } + else + fprintf(stderr, "music file %s not found\n",filename.c_str()); + + //else + // cout << "music file " << filename << " not found" << endl; +} + +void Mixer::stopMusic() +{ + Mix_HaltMusic(); + Mix_FreeMusic(_music); + _music = NULL; +} + +bool Mixer::addSound(const String &s, const String &filename) +{ + Sound *snd; + try + { + snd = _sounds[s]; + } + catch(ExceptionNodeDontExist &e) + { + _sounds.addNode(s, new Sound); + snd = _sounds[s]; + } + + return snd->addSound(filename); +} + +void Mixer::playSound(const String &s) +{ + //_debug_(stderr, "playSound(%s)\n",s.c_str()); + Sound *snd; + try + { + snd = _sounds[s]; + } + catch(ExceptionNodeDontExist &e) + { + _sounds.addNode(s, new Sound(s)); + snd = _sounds[s]; + } + + Mix_Chunk *c=snd->getChunk(); + if(c) + { + for (int i = 0 ; i < MAXSOUNDS ; i++) + { + if (_soundChannels[i] < 0 || !Mix_Playing(_soundChannels[i])) + { + _soundChannels[i] = Mix_PlayChannel(-1, c, 0); + // else { + // fprintf(stderr, "snd->getChunk()==NULL\n"); + //} + break; + } + } + } +} + +void Mixer::stopSound(const int &i) +{ + Mix_HaltChannel(_soundChannels[i]); +} + +void Mixer::channelStopped(int channel) +{ + for (int i = 0 ; i < MAXSOUNDS ; i++) + { + if (_soundChannels[i] == channel) + { + _soundChannels[i] = -1; + break; + } + } +} + +void Mixer::setMusicVolume(const int &v) +{ + _musicVolume = v; + Mix_VolumeMusic(_musicVolume); +} + +void Mixer::setSoundVolume(const int &v) +{ + _soundVolume = v; + for (int i = 0 ; i < MAXSOUNDS ; i++) + //if (Mix_Playing(_soundChannels[i])) + Mix_Volume(_soundChannels[i], v); +// Mix_VolumeChunk(_sounds[i]->getChunk(), _soundVolume); +} + diff --git a/src/Pair.cpp b/src/Pair.cpp new file mode 100644 index 0000000..69b99b1 --- /dev/null +++ b/src/Pair.cpp @@ -0,0 +1,198 @@ +/* + * This source file is part of Dungeon Digger + * Website: http://sourceforge.net/projects/dungeondigger/ + * + * Copyright (C) 2006 Dungeon Digger Team + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ +#ifdef __PAIR__ + +#include +using namespace std; + +template +Pair::Pair(const T &x, const U &y) +:px(x), py(y) +{ +} + +template +Pair::Pair(const Pair &p) +:px(p.px), py(p.py) +{ +} + +template +Pair::~Pair() +{ +} + +template +const T &Pair::getX() const +{ + return px; +} + +template +const U &Pair::getY() const +{ + return py; +} + +template +void Pair::setX(const T &x) +{ + px = x; +} + +template +void Pair::setY(const U &y) +{ + py = y; +} + +///Use an exception ? +// template +// T &Pair::operator [] (const int &i) +// { +// if (i == 0) +// return px; +// else +// return py; +// } +// +// template +// T Pair::operator [] (const int &i) const +// { +// if (i == 0) +// return px; +// else +// return py; +// } + + +template +const Pair & Pair::operator = (const Pair &p) +{ + px = p.px; + py = p.py; + return *this; +} + +template +bool Pair::operator == (const Pair &p) const +{ + return (px == p.px) && (py == p.py); +} + +template +Pair operator + (const Pair &p1, const Pair &p2) +{ + Pair result; + result.px = p1.px + p2.px; + result.py = p1.py + p2.py; + return result; +} + +template +Pair operator + (const T &a, const Pair &p) +{ + return p + Pair(a, a); +} + +template +Pair operator + (const Pair &p, const U &a) +{ + return p + Pair(a, a); +} + +template +Pair operator - (const Pair &p1, const Pair &p2) +{ + Pair result; + result.px = p1.px - p2.px; + result.py = p1.py - p2.py; + return result; +} + +template +Pair operator - (const T &a, const Pair &p) +{ + return Pair(a, a) - p ; +} + +template +Pair operator - (const Pair &p, const U &a) +{ + return p - Pair(a, a); +} + +template +Pair Pair::operator - (void) +{ + return Pair(-px, -py); +} + +template +Pair operator * (const Pair &p1, const Pair &p2) +{ + Pair result; + result.px = p1.px * p2.px; + result.py = p1.py * p2.py; + return result; +} + +template +Pair operator * (const T &a, const Pair &p) +{ + return p * Pair(a, a); +} + +template +Pair operator * (const Pair &p, const U &a) +{ + return p * Pair(a, a); +} + +template +Pair operator / (const Pair &p1, const Pair &p2) +{ + Pair result; + result.px = p1.px / p2.px; + result.py = p1.py / p2.py; + return result; +} + +template +Pair operator / (const T &a, const Pair &p) +{ + return Pair(a, a) / p; +} + +template +Pair operator / (const Pair &p, const U &a) +{ + return p / Pair(a, a); +} + +template +ostream &operator << (ostream &os, const Pair &p) +{ + os << "(" << p.px << "," << p.py << ")"; + return os; +} + +#endif diff --git a/src/PrefixTree.cpp b/src/PrefixTree.cpp new file mode 100644 index 0000000..d8f3311 --- /dev/null +++ b/src/PrefixTree.cpp @@ -0,0 +1,306 @@ +/* + * This source file is part of Dungeon Digger + * Website: http://sourceforge.net/projects/dungeondigger/ + * + * Copyright (C) 2006 Dungeon Digger Team + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ +#ifdef __PREFIXTREE__ + +template +PrefixTree::PrefixTree() +:root(new TNode()) +{ +} + +template +PrefixTree::PrefixTree(const PrefixTree &pt) +:root(pt.root) +{ +} + +template +PrefixTree::~PrefixTree() +{ + delete root; +} + +template +void PrefixTree::addNode(const String &pref, const T&elt) +{ + root->insertInsideNode(pref, elt, 0, 0); +} + +template +void PrefixTree::remNode(const T &elt) +{ + //TODO +} + +template +List PrefixTree::sonsList(const String &pref) const +{ + //TODO + return List(); +} + +template +String PrefixTree::completePrefix(const String &pref) const +{ + return root->searchInsideNode(pref, 0, 0); +} + +template +PrefixTree::TNode::TNode() +:haskey(false), key(), prefix(""), son(NULL), brotherleft(NULL), brotherright(NULL), father(NULL) +{ +} + +template +PrefixTree::TNode::TNode(const T &elt, const String &pref, TNode *s, TNode *bl, TNode *br, TNode *f) +:haskey(true), key(elt), prefix(pref), son(s), brotherleft(bl), brotherright(br), father(f) +{ +} + +template +PrefixTree::TNode::TNode(const String &pref, TNode *s, TNode *bl, TNode *br, TNode *f) +:haskey(false), key(), prefix(pref), son(s), brotherleft(bl), brotherright(br), father(f) +{ +} + +template +PrefixTree::TNode::~TNode() +{ + delete son; + delete brotherright; +} + +template +void PrefixTree::TNode::insertInsideNode(const String &pref, const T &elt, const unsigned int &posword, const unsigned int &posnode) +{ + if (posnode >= prefix.length()) + { + if (posword >= pref.length()) + key = elt; + else if (son == NULL) + son = new TNode(elt, pref(posword, pref.length() - posword), NULL, NULL, NULL, this); + else + son->insertInsideNode(pref, elt, posword, 0); + } + else + { + if (posword >= pref.length()) + { + TNode *temp = new TNode(key, prefix(posnode, prefix.length() - posnode), son, NULL, NULL, this); + key = elt; + prefix = prefix(0, posnode); + son = temp; + } + else + { + if (pref[posword] == prefix[posnode]) + insertInsideNode(pref, elt, posword + 1, posnode + 1); + else + { + if (posnode == 0) + { + if (brotherright) + brotherright->insertInsideNode(pref, elt, posword, 0); + else + brotherright = new TNode(elt, pref(posword, pref.length() - posword), NULL, this, NULL, father); + } + else + { + TNode *temp = new TNode(prefix(0, posnode), this, brotherleft, brotherright, father); + if (father->son == this) + father->son = temp; + if (brotherleft) + brotherleft->brotherright = temp; + if (brotherright) + brotherright->brotherleft = temp; + TNode *temp2 = new TNode(elt, pref(posword, pref.length() - posword), NULL, this, NULL, temp); + father = temp; + brotherleft = NULL; + brotherright = temp2; + prefix = prefix(posnode, prefix.length() - posnode); + } + } + } + } +} + +template +String PrefixTree::TNode::searchInsideNode(const String &pref, const unsigned int &posword, const unsigned int &posnode) const +{ + if (posnode >= prefix.length()) + { + if (posword >= pref.length() || son == NULL) + return pref(0, posword); + return son->searchInsideNode(pref, posword, 0); + } + if (posword >= pref.length()) + return pref + prefix(posnode, prefix.length() - posnode); + if (pref[posword] == prefix[posnode]) + return searchInsideNode(pref, posword + 1, posnode + 1); + if (posnode == 0 && brotherright) + return brotherright->searchInsideNode(pref, posword, 0); + return pref(0, posword); +} + +template +bool PrefixTree::searchNode(const String &n) +{ + return root->nodeExists(n, 0, 0); +} + +template +bool PrefixTree::TNode::nodeExists(const String &n, const unsigned int &posword, const unsigned int &posnode) const +{ + if (posnode >= prefix.length()) + { + if (posword >= n.length()) + return haskey; + if (son == NULL) + return false; + return son->nodeExists(n, posword, 0); + } + if (posword >= n.length()) + return false; + if (n[posword] != prefix[posnode]) + { + if (posnode == 0 && brotherright) + return brotherright->nodeExists(n, posword, 0); + else + return false; + } + return nodeExists(n, posword + 1, posnode + 1); +} + +template +const T &PrefixTree::TNode::getNode(const String &n, const unsigned int &posword, const unsigned int &posnode) const +{ + if (posnode >= prefix.length()) + { + if (posword >= n.length()) + return key; + if (son == NULL) + throw ExceptionNodeDontExist(n); + return son->getNode(n, posword, 0); + } + if (posword >= n.length()) + throw ExceptionNodeDontExist(n); + if (n[posword] != prefix[posnode]) + { + if (posnode == 0 && brotherright) + return brotherright->getNode(n, posword, 0); + else + throw ExceptionNodeDontExist(n); + } + return getNode(n, posword + 1, posnode + 1); +} + +template +typename PrefixTree::TNode * PrefixTree::getRoot() +{ + return root; +} +/* +template +inline T &PrefixTree::operator[](const String &key) +{ + return root->getNode(n, 0, 0); +}*/ + +template +inline const T &PrefixTree::operator[](const String &key) const +{ + return root->getNode(key, 0, 0); +} + +template +ostream &PrefixTree::TNode::display(ostream &os) +{ +// cout << "display key" << endl; + if (haskey) + os << "[" << key << "]"; + else + os << "X"; +// cout << "display prefix" << endl; + os << " " << prefix << " "; +// cout << "display son" << endl; + if (son) + { + os << " ("; + son->display(os); + os << ")"; + } +// cout << "display brother" << endl; + if (brotherright) + { + os << " {"; + brotherright->display(os); + os << "}"; + } + return os; +} + +/*template +ostream &operator<< (ostream &os, const typename PrefixTree::TNode &n) +{ + if (n.key) + os << "[" << *(n.key) << "]"; + else + os << "X"; + os << " " << n.prefix << " "; + if (n.son) + os << " (" << *(n.son) << ")"; + if (n.brother) + os << " {" << *(n.brother) << "}"; + return os; +}*/ + +template +ostream &operator<< (ostream &os, const PrefixTree &n) +{ + if (n.root) + n.root->display(os); + return os; +} + +template +typename PrefixTree::TNode *PrefixTree::TNode::nextNode() +{ + if (son) + return son; + TNode *temp = this; + while (temp && !temp->brotherright) + temp = temp->father; + if (temp) + return temp->brotherright; + else + return NULL; +} + +template +String PrefixTree::TNode::wholePrefix() const +{ + if (father) + return father->wholePrefix() + prefix; + else + return prefix; +} + +#endif diff --git a/src/String.cpp b/src/String.cpp new file mode 100644 index 0000000..1d105ae --- /dev/null +++ b/src/String.cpp @@ -0,0 +1,167 @@ +/* + * This source file is part of Dungeon Digger + * Website: http://sourceforge.net/projects/dungeondigger/ + * + * Copyright (C) 2006 Dungeon Digger Team + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ +#include "String.hpp" + +#include +#include +#include +#include +#include +#include +using namespace std; + +String::String(const String &s) +:string(strdup(s.string)) +{ +} + +String::String(const int &a) +{ + if (a == 0) + string = (char *)malloc(2 * sizeof(char)); + else if (a < 0) + string = (char *)malloc(int(log10(-a) + 3) * sizeof(char)); + else + string = (char *)malloc(int(log10(a) + 2) * sizeof(char)); + sprintf(string, "%d", a); +} + +String::String(const double &a) +{ + //compute the number of chars + //too many if |n| < 0 + //fix this in the future + int i; + long long pi=1; + for (i=0 ; a * pi - ceil(a * pi) > DBL_EPSILON ; i++,pi*=10); + + int size; + if (i == 0) + { + if (a == 0) + size=2; + else if (a < 0) + size=int(log10(-a) + 3); + else + size=int(log10(a) + 2); + } else { + if (a < 0) + size=int(log10(-a * pow(10.0, i)) + 4); + else + size=int(log10(a * pow(10.0, i)) + 3); + } + + string = (char *)malloc(size * sizeof(char)); + snprintf(string,size, "%.20f", a); +} + + +String::String(const char *s) +:string(strdup(s)) +{ +} + +String::String(const char &c) +{ + string = (char *)malloc(2 * sizeof(char)); + string[0] = c; + string[1] = '\0'; +} + +String::~String() +{ + free(string); +} + +unsigned int String::length() const +{ + return strlen(string); +} + +void String::concat(const String &s) +{ + string = (char *)realloc(string, (length() + s.length() + 1) * sizeof(char)); + strcat(string, s.string); +} + +const char *String::c_str() const +{ + return string; +} + +const String & String::operator = (const String &s) +{ + if (&s != this) + { + free(string); + string = strdup(s.string); + } + return *this; +} + +bool String::operator == (const String &s) const +{ + if (s.length() != length()) + return false; + for (unsigned int i = 0 ; i < length() ; i++) + if (string[i] != s.string[i]) + return false; + return true; +} + +bool String::operator != (const String &s) const +{ + return !(*this == s); +} + +char &String::operator [] (const int &i) const +{ + return string[i]; +} + +String String::operator () (const unsigned int &i, const unsigned int &j) const +{ + String result; + free (result.string); + result.string = (char *)malloc((j + 1) * sizeof(char)); + for (unsigned int k = 0 ; k < j ; k++) + result.string[k] = string[k + i]; + result.string[j] = '\0'; + return result; +} + +String operator + (const String &s1, const String &s2) +{ + String temp(s1); + temp.concat(s2); + return temp; +} + +ostream &operator << (ostream & os, const String &s) +{ + os << s.string; + return os; +} + +// istream &operator >> (istream & is, const String &s); +// { +// +// } diff --git a/src/Texture.cpp b/src/Texture.cpp new file mode 100644 index 0000000..e3f9913 --- /dev/null +++ b/src/Texture.cpp @@ -0,0 +1,131 @@ +/* + * This source file is part of Dungeon Digger + * Website: http://sourceforge.net/projects/dungeondigger/ + * + * Copyright (C) 2006 Dungeon Digger Team + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ +#include "Texture.hpp" + +// #include +// #include +#ifdef __APPLE__ +#include +#else +#include +#endif +// #include +#include + +#include "Tools.hpp" + +#define BUFFERSIZE 256 + +Texture::Texture(const String &filename, const bool &rep) +:surface(NULL), repeat(rep) +{ + glGenTextures (1, &texture); + glBindTexture (GL_TEXTURE_2D, texture); + + glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT); + glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT); + glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); + glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); + glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE); + + String buffer; + if (fileExists(filename)) + buffer = filename; + else if (fileExists("data/textures/" + filename)) + buffer = "data/textures/" + filename; + else if (fileExists("../data/textures/" + filename)) + buffer = "../data/textures/" + filename; + else if (fileExists("data/textures2D/" + filename)) + buffer = "data/textures2D/" + filename; + else if (fileExists("../data/textures2D/" + filename)) + buffer = "../data/textures2D/" + filename; + else if (fileExists("data/textures3D/" + filename)) + buffer = "data/textures3D/" + filename; + else if (fileExists("../data/textures3D/" + filename)) + buffer = "../data/textures3D/" + filename; + else if (fileExists("data/fonts/" + filename)) + buffer = "data/fonts/" + filename; + else if (fileExists("../data/fonts/" + filename)) + buffer = "../data/fonts/" + filename; + + if (buffer != "") + surface = IMG_Load(buffer.c_str()); + else + cerr << "Could not open texture " << filename << endl; + + if (surface) + { + size[C_X] = surface->w; + size[C_Y] = surface->h; + SDL_Surface *temp = NULL; + SDL_PixelFormat format = {NULL, 32, 4, 0, 0, 0, 0, 0, 8, 16, 24, 0x000000FF, 0x0000FF00, 0x00FF0000, 0xFF000000, 0, 255}; + switch(surface->format->BitsPerPixel) + { + case 24: + //convert to 32bits + temp = SDL_ConvertSurface(surface, &format, SDL_SWSURFACE); + SDL_FreeSurface(surface); + surface = temp; + gluBuild2DMipmaps(GL_TEXTURE_2D, GL_RGB, surface->w, surface->h, GL_RGB, GL_UNSIGNED_BYTE, surface->pixels); + break; + case 32: + //convert if it's ABGR + if (surface->format->Rshift > surface->format->Bshift) + { + temp = SDL_ConvertSurface(surface, &format, SDL_SWSURFACE); + SDL_FreeSurface(surface); + surface = temp; + } + break; + } + gluBuild2DMipmaps(GL_TEXTURE_2D, 4, surface->w, surface->h, GL_RGBA, GL_UNSIGNED_BYTE, surface->pixels); + } +} + + +Texture::~Texture() +{ + if (surface) + { + SDL_FreeSurface(surface); + glDeleteTextures(1, &texture); + } + else + cerr << "no texture..." << endl; +} + +void Texture::useTexture() const +{ + if (surface) + glBindTexture(GL_TEXTURE_2D, texture); + else + cerr << "problem with texture" << endl; +} + +bool Texture::isLoaded() const +{ + return (surface != NULL); +} + +Vector2D Texture::getSize() const +{ + return size; +} diff --git a/src/Tools.cpp b/src/Tools.cpp new file mode 100644 index 0000000..79ce059 --- /dev/null +++ b/src/Tools.cpp @@ -0,0 +1,68 @@ +/* + * This source file is part of Dungeon Digger + * Website: http://sourceforge.net/projects/dungeondigger/ + * + * Copyright (C) 2006 Dungeon Digger Team + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ +#include "Tools.hpp" + +#include +#include +#include +#include +using namespace std; + +bool fileExists(const String &f) +{ + FILE *file; + if ((file = fopen(f.c_str(),"r")) != NULL) + { + fclose(file); + return true; + } + return false; +} + +bool dirExists(const String &d) +{ + DIR *dir; + if ((dir = opendir(d.c_str())) != NULL) + { + closedir(dir); + return true; + } + return false; +} + +Vector2D rotatePoint(const Vector2D pos, const Vector2D center, const double &angle) +{ + return Vector2D( + int((pos[C_X] - center[C_X]) * cos(angle) - (pos[C_Y] - center[C_Y]) * sin(angle) + center[C_X]), + int((pos[C_Y] - center[C_Y]) * cos(angle) + (pos[C_X] - center[C_X]) * sin(angle) + center[C_Y]) + ); +} + +//recursive, but supposed to be called once... +//see if we have to do something here... +double mod2pi(const double &a) +{ + if (a > 2 * M_PI) + return mod2pi(a - 2 * M_PI); + else if (a < 0) + return mod2pi(a + 2 * M_PI); + return a; +} diff --git a/src/Track.cpp b/src/Track.cpp new file mode 100644 index 0000000..e9173c5 --- /dev/null +++ b/src/Track.cpp @@ -0,0 +1,452 @@ +#include "Track.hpp" + +#include "Mixer.hpp" + +#include + +double SECONDSIZE = 0.050; + +extern FILE *logfile; + +void drawCube(double pos, double size, double colorx, double colory, double colorz) +{ + glBegin(GL_QUADS); + glColor3f(colorx, colory, colorz); // Set The Color To Green +/* + glNormal3f(0, -1, 0); + glVertex3f( size+pos,0, size); // Top Right Of The Quad (Bottom) + glVertex3f(-size+pos,0, size); // Top Left Of The Quad (Bottom) + glVertex3f(-size+pos,0,-size); // Bottom Left Of The Quad (Bottom) + glVertex3f( size+pos,0,-size); // Bottom Right Of The Quad (Bottom) +*/ + glNormal3f(0, 0.5, 0.5); + glVertex3f( size/2+pos, size/3, size/2); // Top Right Of The Quad (Front) + glVertex3f(-size/2+pos, size/3, size/2); // Top Left Of The Quad (Front) + glVertex3f(-size+pos,0, size); // Bottom Left Of The Quad (Front) + glVertex3f( size+pos,0, size); // Bottom Right Of The Quad (Front) + + glNormal3f(0, 0.5, -0.5); + glVertex3f( size+pos,0,-size); // Bottom Left Of The Quad (Back) + glVertex3f(-size+pos,0,-size); // Bottom Right Of The Quad (Back) + glVertex3f(-size/2+pos, size/3,-size/2); // Top Right Of The Quad (Back) + glVertex3f( size/2+pos, size/3,-size/2); // Top Left Of The Quad (Back) + + glNormal3f(-0.5, 0.5, 0); + glVertex3f(-size/2+pos, size/3, size/2); // Top Right Of The Quad (Left) + glVertex3f(-size/2+pos, size/3,-size/2); // Top Left Of The Quad (Left) + glVertex3f(-size+pos,0,-size); // Bottom Left Of The Quad (Left) + glVertex3f(-size+pos,0, size); // Bottom Right Of The Quad (Left) + + glNormal3f(0.5, 0.5, 0); + glVertex3f( size/2+pos, size/3,-size/2l); // Top Right Of The Quad (Right) + glVertex3f( size/2+pos, size/3, size/2); // Top Left Of The Quad (Right) + glVertex3f( size+pos,0, size); // Bottom Left Of The Quad (Right) + glVertex3f( size+pos,0,-size); // Bottom Right Of The Quad (Right) + + glColor3f(1.0, 1.0, 1.0); // Set The Color To White + glNormal3f(0, 1, 0); + glVertex3f( size/2+pos, size/3,-size/2); // Top Right Of The Quad (Top) + glVertex3f( size/2+pos, size/3, size/2); // Bottom Right Of The Quad (Top) + glVertex3f(-size/2+pos, size/3, size/2); // Bottom Left Of The Quad (Top) + glVertex3f(-size/2+pos, size/3,-size/2); // Top Left Of The Quad (Top) +/* +*/ + glEnd(); // Done Drawing The Quad +} + +void drawLong(double pos, double size, double length, double colorx, double colory, double colorz) +{ + double l = length*SECONDSIZE; + glBegin(GL_QUADS); + glColor3f(colorx, colory, colorz); // Set The Color +/* + glNormal3f(0, -1, 0); + glVertex3f( size+pos,0, size); // Top Right Of The Quad (Bottom) + glVertex3f(-size+pos,0, size); // Top Left Of The Quad (Bottom) + glVertex3f(-size+pos,0,-size-l); // Bottom Left Of The Quad (Bottom) + glVertex3f( size+pos,0,-size-l); // Bottom Right Of The Quad (Bottom) +*/ + glNormal3f(0, 0.5, 0.5); + glVertex3f( size/2+pos, size/3, size/2); // Top Right Of The Quad (Front) + glVertex3f(-size/2+pos, size/3, size/2); // Top Left Of The Quad (Front) + glVertex3f(-size+pos,0, size); // Bottom Left Of The Quad (Front) + glVertex3f( size+pos,0, size); // Bottom Right Of The Quad (Front) + + glNormal3f(0, 0.5, -0.5); + glVertex3f( size+pos,0,-size); // Bottom Left Of The Quad (Back) + glVertex3f(-size+pos,0,-size); // Bottom Right Of The Quad (Back) + glVertex3f(-size/2+pos, size/3,-size/2-l); // Top Right Of The Quad (Back) + glVertex3f( size/2+pos, size/3,-size/2-l); // Top Left Of The Quad (Back) + + glNormal3f(-0.5, 0.5, 0); + glVertex3f(-size/2+pos, size/3, size/2); // Top Right Of The Quad (Left) + glVertex3f(-size/2+pos, size/3,-size/2-l); // Top Left Of The Quad (Left) + glVertex3f(-size+pos,0,-size-l); // Bottom Left Of The Quad (Left) + glVertex3f(-size+pos,0, size); // Bottom Right Of The Quad (Left) + + glNormal3f(0.5, 0.5, 0); + glVertex3f( size/2+pos, size/3,-size/2-l); // Top Right Of The Quad (Right) + glVertex3f( size/2+pos, size/3, size/2); // Top Left Of The Quad (Right) + glVertex3f( size+pos,0, size); // Bottom Left Of The Quad (Right) + glVertex3f( size+pos,0,-size-l); // Bottom Right Of The Quad (Right) + + glNormal3f(0, 1, 0); + glVertex3f( size/2+pos, size/3,-size/2-l); // Top Right Of The Quad (Top) + glVertex3f(-size/2+pos, size/3,-size/2-l); // Top Left Of The Quad (Top) + glVertex3f(-size/2+pos, size/3, size/2); // Bottom Left Of The Quad (Top) + glVertex3f( size/2+pos, size/3, size/2); // Bottom Right Of The Quad (Top) + glEnd(); // Done Drawing The Quad +} + +Track::Track() +:/*_currenttempo(120)*,_currentpos(0),*/ _trackSize(0), _active(true) +{ + for (uint8 i = 0 ; i < NBDIFFICULTIES ; i++) + { + _currentconfig[i] = 0; + _nbnotes[i] = 0; + _totallength[i] = 0; + } + for (uint8 i = 0 ; i < 128 ; i++) + _totalnotes[i] = 0; +} + +Track::Track(const Track &tr) +{ + cerr << "WARNING: COPYING THE TRACK!" << endl; + for (uint8 i = 0 ; i < NBDIFFICULTIES ; i++) + { + _notes[i] = tr._notes[i]; + _currentconfig[i] = tr._currentconfig[i]; + _nbnotes[i] = 0; + _totallength[i] = 0; + } +} + +Track::~Track() +{ +} +/* + http://www.scorehero.com/forum/viewtopic.php?t=1179 + Lead guitar track (GH1) + ======================= + + Track 1 contains only events that affect gameplay. The exception to this rule is that Track 1 also contains events guiding the animation of the singer's mouth. Note-on and Note-off events are the only MIDI event types that are valid in this track other than the first event which is always a Track Name event with a track name of "T1 GEMS". Each gameplay event is allocated a MIDI note number where the note letter specifies the type of event and the note octave specifies the difficulty level to which the note applies. Each note event applies to a single difficulty level except for the vocal track events which apply to all difficulty levels. The note number mapping is as follows: + + 60: guitar note GREEN, easy (C) + 61: guitar note RED, easy (C#) + 62: guitar note YELLOW, easy (D) + 63: guitar note BLUE, easy (D#) + 64: guitar note ORANGE, easy (E) + 67: star power group, easy (G) + 69: player 1 section, easy (A) + 70: player 2 section, easy (A#) + 72: guitar note GREEN, medium (C) + 73: guitar note RED, medium (C#) + 74: guitar note YELLOW, medium (D) + 75: guitar note BLUE, medium (D#) + 76: guitar note ORANGE, medium (E) + 79: star power group, medium (G) + 81: player 1 section, medium (A) + 82: player 2 section, medium (A#) + 84: guitar note GREEN, hard (C) + 85: guitar note RED, hard (C#) + 86: guitar note YELLOW, hard (D) + 87: guitar note BLUE, hard (D#) + 88: guitar note ORANGE, hard (E) + 91: star power group, hard (G) + 93: player 1 section, hard (A) + 94: player 2 section, hard (A#) + 96: guitar note GREEN, expert (C) + 97: guitar note RED, expert (C#) + 98: guitar note YELLOW, expert (D) + 99: guitar note BLUE, expert (D#) + 100: guitar note ORANGE, expert (E) + 103: star power group, expert (G) + 105: player 1 section, expert (A) + 106: player 2 section, expert (A#) + 108: vocal track (C) +*/ + +void Track::addKey(uint32 time, uint8 note) +{ +// _totalnotes[note]++; + +// cout << "addkey begin" << endl; + uint8 difficulty = note / 12 - 5; + uint8 key = note % 12; +// cout << "+ diff=" << difficulty+0 << " key=" << key+0 << " note=" << note+0 << endl; //could be note 108 for singer + if (difficulty >= NBDIFFICULTIES || difficulty < 0) + { + //cout << "Wrong difficulty!" << difficulty << endl; + return; + } + //Notes could be other stuff + if (key >= 5) + { +// cout << "+ Key : " << key+0 << " difficulty : " << difficulty+0 << endl; + return; + } +/* + //if delta is 0, this is a new note + if (delta > 0) + { + _notes[difficulty][_currentconfig[difficulty].getTime()] = _currentconfig[difficulty]; + //set the new position + _currentconfig[difficulty].setTime(_currentconfig[difficulty].getTime() + _currentconfig[difficulty].getDuration()); + //set the new duration + _currentconfig[difficulty].setDuration(delta); + } + _currentconfig[difficulty].addKey(keys(key));*/ + + _currentconfig[difficulty].addKey(keys(key)); + _currentconfig[difficulty].setTime(time); + +// if (delta > +// _currentconfig[difficulty].addKey(keys(key)); + +/* if (_notes[difficulty].empty()) + { + _currentconfig[difficulty].remKey(keys(key)); + _currentconfig[difficulty] = delta; + _currentconfig[difficulty].addKey(keys(key)); + _notes[difficulty].push_back(_currentconfig[difficulty]); + _nbnotes[difficulty]++; + _totallength[difficulty] += delta; + return; + } + + if (delta > 0) + { + _currentconfig[difficulty].remKey(keys(key)); + _notes[difficulty].push_back(_currentconfig[difficulty]); + _currentconfig[difficulty].setTime(delta); + _nbnotes[difficulty]++; + _totallength[difficulty] += delta; + } + _currentconfig[difficulty].addKey(keys(key));*/ +// cout << "addkey end" << endl; +} + +void Track::remKey(uint32 time, uint8 note) +{ + _totalnotes[note]++; +// cout << "remkey begin" << endl; + uint8 difficulty = note / 12 - 5; + uint8 key = note % 12; +// cout << "- diff=" << difficulty+0 << " key=" << key+0 << " note=" << note+0 << endl; + if (difficulty >= NBDIFFICULTIES || difficulty+0 < 0) + { +// cout << "Wrong difficulty!" << difficulty << endl; + return; + } + //Notes could be other stuff + if (key >= 5) + { +// cout << "- Key : " << key+0 << " difficulty : " << difficulty+0 << endl; + return; + } + if (_notes[difficulty].count(_currentconfig[difficulty].getTime()) == 0) + { + _currentconfig[difficulty].setTicks(time - _currentconfig[difficulty].getTime()); + //compute the note duration and position + uint32 currenttempo = 0, lasttick = 0; + map::iterator ti = _tempo.begin(); + uint32 tickpos = _currentconfig[difficulty].getTime(); + while (ti != _tempo.end() && (*ti).first <= tickpos) + { + _currentconfig[difficulty].setPosition(_currentconfig[difficulty].getPosition() + ((*ti).first - lasttick) * (currenttempo / 480000.0)); + lasttick = (*ti).first; + currenttempo = (*ti).second; + ti++; + } + if (tickpos > lasttick) + _currentconfig[difficulty].setPosition(_currentconfig[difficulty].getPosition() + (tickpos - lasttick) * (currenttempo / 480000.0)); + + while (tickpos < time) + { + if (ti != _tempo.end() && (*ti).first < time) + { + _currentconfig[difficulty].setEnd(_currentconfig[difficulty].getPosition() + ((*ti).first - tickpos) * (currenttempo / 480000.0)); + tickpos = (*ti).first; + currenttempo = (*ti).second; + ti++; + } + else + { + _currentconfig[difficulty].setEnd(_currentconfig[difficulty].getPosition() + (time - tickpos) * (currenttempo / 480000.0)); + tickpos = time; + } + } + + + _notes[difficulty][_currentconfig[difficulty].getTime()] = _currentconfig[difficulty]; + +// cout << "add note pos=" << _notes[difficulty][_currentconfig[difficulty].getTime()].getPosition() << " duration=" << _notes[difficulty][_currentconfig[difficulty].getTime()].getDuration() << endl; + + + _currentconfig[difficulty].setPosition(0); + _currentconfig[difficulty].setEnd(0); + _currentconfig[difficulty].setTicks(0); + _nbnotes[difficulty]++; + } + _currentconfig[difficulty].remKey(keys(key)); +/* + //if delta is 0, this is a new note + if (delta > 0) + { + _notes[difficulty][_currentconfig[difficulty].getTime()] = _currentconfig[difficulty]; + //set the new position + _currentconfig[difficulty].setTime(_currentconfig[difficulty].getTime() + _currentconfig[difficulty].getDuration()); + //set the new duration + _currentconfig[difficulty].setDuration(delta); + } + _currentconfig[difficulty].remKey(keys(key)); + */ +/* if (_notes[difficulty].empty()) + { + _currentconfig[difficulty] = delta; + _currentconfig[difficulty].remKey(keys(key)); + _notes[difficulty].push_back(_currentconfig[difficulty]); + _nbnotes[difficulty]++; + _totallength[difficulty] += delta; + return; + } + + if (delta > 0) + { + _currentconfig[difficulty].remKey(keys(key)); + _notes[difficulty].push_back(_currentconfig[difficulty]); + _currentconfig[difficulty].setTime(delta); + _nbnotes[difficulty]++; + _totallength[difficulty] += delta; + } + _currentconfig[difficulty].remKey(keys(key));*/ +// cout << "remkey end" << endl; +} + +Config Track::getNote(uint32 pos, uint8 difficulty) +{ + if (_notes[difficulty].count(pos) == 0) + throw 0; + return _notes[difficulty][pos]; +} + +uint32 Track::getTempo(uint32 pos) +{ + if (_tempo.count(pos) == 0) + throw 0; + return _tempo[pos]; +} + +void Track::computeBips() +{ + double pos = 0; + uint32 currenttempo = 120; + map::iterator p = _tempo.begin(); + for (uint32 i = 0 ; i < getEndOfTrack() ; i += 480) + { + //cout << "Bip @ " << pos << endl; + _bips.push_back(pos); + if (p != _tempo.end() && (*p).first < i + 480) + { + pos += ((*p).first - i) * (currenttempo / 480000.0); + currenttempo = (*p).second; + pos += (i + 480 - (*p).first) * (currenttempo / 480000.0); + ++p; + } + else + pos += currenttempo / 1000.0; + } +} + +void Track::displayTracks() +{ + cout << "TRACK:" << endl; + for (uint8 k=0 ; k < NBDIFFICULTIES ; k++) + { + cout << "Difficulty " << (k+0) << ":" << endl; + for(map::iterator i = _notes[k].begin(); i != _notes[k].end(); ++i) + cout << (*i).first << ": " << (*i).second << endl; + } +} + +void Track::debugTempo() +{ + cout << "Tempo changes: " << endl; + for( map::iterator ii=_tempo.begin(); ii!=_tempo.end(); ++ii) + cout << (*ii).first << ": " << (*ii).second << " (" << ticksToBeats((*ii).second) << ")" << endl; +} + +void Track::drawFrets(double postime) const +{ + static list::const_iterator startingbips = _bips.begin(); + +// on avance tant que les bips sont dépassées + while (startingbips != _bips.end() && *startingbips < postime) + { + Mixer::getInstance()->playSound("bip"); + if (logfile) + fprintf(logfile, "Bip;%f;%f;%f\n", *startingbips, postime, postime - *startingbips); + startingbips++; + } + + list::const_iterator b = startingbips; + + glMatrixMode(GL_MODELVIEW); + //on dessine les frettes jusqu'à 10s + while (b != _bips.end() && *b < postime + 10000) + { + glPushMatrix(); + glTranslatef(0, 0, - SECONDSIZE * *b); + glBegin(GL_QUADS); + glColor3f(0.8, 0.8, 0.0); // Set The Color To Green + glNormal3f(0, 0.5, 0.5); + glVertex3f( NECKWIDTH,0, 0.1); + glVertex3f( NECKWIDTH,0.1, 0); + glVertex3f(-NECKWIDTH,0.1, 0); + glVertex3f(-NECKWIDTH,0, 0.1); + glNormal3f(0, 0.5, -0.5); + glVertex3f( NECKWIDTH,0.1, 0); + glVertex3f( NECKWIDTH,0, -0.1); + glVertex3f(-NECKWIDTH,0, -0.1); + glVertex3f(-NECKWIDTH,0.1, 0); + glEnd(); + glPopMatrix(); + b++; + } +} + +void Track::drawNotes(double postime, uint8 diff) const +{ + static map::const_iterator startingn = _notes[diff].begin(); + static double startingpos = 0.0; + +// cout << "startingpos=" << startingpos << " postime=" << postime << " first note at " << (*startingn).first << ":" << (*startingn).second.getPosition() << endl; + + // on avance tant que les notes sont dépassées + while (startingn != _notes[diff].end()) + { + double endpos = (*startingn).second.getPosition(); + if ((*startingn).second.getTicks() > 240) + endpos = (*startingn).second.getEnd(); + if (endpos >= postime) + break; + startingpos = (*startingn).second.getPosition(); + (*startingn).second.log("Note", logfile); + startingn++; + } + + map::const_iterator n = startingn; + + glMatrixMode(GL_MODELVIEW); + //on dessine les notes jusqu'à 10s + while (n != _notes[diff].end() && (*n).second.getEnd() < postime + 10000) + { + glPushMatrix(); + glTranslatef(0, 0, - SECONDSIZE * (*n).second.getPosition()); + (*n).second.display(); + glPopMatrix(); + n++; + } +} diff --git a/src/Triplet.cpp b/src/Triplet.cpp new file mode 100644 index 0000000..0b5363d --- /dev/null +++ b/src/Triplet.cpp @@ -0,0 +1,215 @@ +/* + * This source file is part of Dungeon Digger + * Website: http://sourceforge.net/projects/dungeondigger/ + * + * Copyright (C) 2006 Dungeon Digger Team + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ +#ifdef __TRIPLET__ + +#include +using namespace std; + +template +Triplet::Triplet(const T &x, const U &y, const V &z) +:px(x), py(y), pz(z) +{ +} + +template +Triplet::Triplet(const Triplet &p) +:px(p.px), py(p.py), pz(p.pz) +{ +} + +template +Triplet::~Triplet() +{ +} + +template +const T &Triplet::getX() const +{ + return px; +} + +template +const U &Triplet::getY() const +{ + return py; +} + +template +const V &Triplet::getZ() const +{ + return pz; +} + +template +void Triplet::setX(const T &x) +{ + px = x; +} + +template +void Triplet::setY(const U &y) +{ + py = y; +} + +template +void Triplet::setZ(const V &z) +{ + pz = z; +} + +///Use an exception ? +// template +// T &Triplet::operator [] (const int &i) +// { +// if (i == 0) +// return px; +// else +// return py; +// } +// +// template +// T Triplet::operator [] (const int &i) const +// { +// if (i == 0) +// return px; +// else +// return py; +// } + + +template +const Triplet & Triplet::operator = (const Triplet &p) +{ + px = p.px; + py = p.py; + pz = p.pz; + return *this; +} + +template +bool Triplet::operator == (const Triplet &p) const +{ + return (px == p.px) && (py == p.py) && (pz == p.pz); +} + +template +Triplet operator + (const Triplet &p1, const Triplet &p2) +{ + Triplet result; + result.px = p1.px + p2.px; + result.py = p1.py + p2.py; + result.pz = p1.pz + p2.pz; + return result; +} + +template +Triplet operator + (const T &a, const Triplet &p) +{ + return p + Triplet(a, a, a); +} + +template +Triplet operator + (const Triplet &p, const U &a) +{ + return p + Triplet(a, a, a); +} + +template +Triplet operator - (const Triplet &p1, const Triplet &p2) +{ + Triplet result; + result.px = p1.px - p2.px; + result.py = p1.py - p2.py; + result.py = p1.pz - p2.pz; + return result; +} + +template +Triplet operator - (const T &a, const Triplet &p) +{ + return Triplet(a, a, a) - p ; +} + +template +Triplet operator - (const Triplet &p, const U &a) +{ + return p - Triplet(a, a, a); +} + +template +Triplet Triplet::operator - (void) +{ + return Triplet(-px, -py, -pz); +} + +template +Triplet operator * (const Triplet &p1, const Triplet &p2) +{ + Triplet result; + result.px = p1.px * p2.px; + result.py = p1.py * p2.py; + result.pz = p1.pz * p2.pz; + return result; +} + +template +Triplet operator * (const T &a, const Triplet &p) +{ + return p * Triplet(a, a, a); +} + +template +Triplet operator * (const Triplet &p, const U &a) +{ + return p * Triplet(a, a, a); +} + +template +Triplet operator / (const Triplet &p1, const Triplet &p2) +{ + Triplet result; + result.px = p1.px / p2.px; + result.py = p1.py / p2.py; + result.pz = p1.pz / p2.pz; + return result; +} + +template +Triplet operator / (const T &a, const Triplet &p) +{ + return Triplet(a, a, a) / p; +} + +template +Triplet operator / (const Triplet &p, const U &a) +{ + return p / Triplet(a, a, a); +} + +template +ostream &operator << (ostream &os, const Triplet &p) +{ + os << "(" << p.px << "," << p.py << "," << p.pz << ")"; + return os; +} + +#endif diff --git a/src/Vector2D.cpp b/src/Vector2D.cpp new file mode 100644 index 0000000..12abaf6 --- /dev/null +++ b/src/Vector2D.cpp @@ -0,0 +1,199 @@ +/* + * This source file is part of Dungeon Digger + * Website: http://sourceforge.net/projects/dungeondigger/ + * + * Copyright (C) 2006 Dungeon Digger Team + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ +#ifdef __VECTOR2D__ + +#include +using namespace std; + +template +Vector2D::Vector2D(const T &x, const T &y) +:Pair(x, y) +{ +} + +template +Vector2D::Vector2D(const Vector2D &p) +:Pair(p) +{ +} + +template +Vector2D::~Vector2D() +{ +} + +/* +template +T Vector2D::getX() const +{ + return px; +} + +template +T Vector2D::getY() const +{ + return py; +} + +template +void Vector2D::setX(const T &x) +{ + px = x; +} + +template +void Vector2D::setY(const T &y) +{ + py = y; +}*/ + +///Use an exception ? +template +T &Vector2D::operator [] (const int &i) +{ + if (i == 0) + return this->px; + else + return this->py; +} + +template +const T &Vector2D::operator [] (const int &i) const +{ + if (i == 0) + return this->px; + else + return this->py; +} + +/* +template +const Vector2D & Vector2D::operator = (const Vector2D &p) +{ + px = p.px; + py = p.py; + return *this; +} + +template +bool Vector2D::operator == (const Vector2D &p) const +{ + return (px == p.px) && (py == p.py); +}*/ + +template +Vector2D operator + (const Vector2D &p1, const Vector2D &p2) +{ + Vector2D result; + result.px = p1.px + p2.px; + result.py = p1.py + p2.py; + return result; +} + +template +Vector2D operator + (const T &a, const Vector2D &p) +{ + return p + Vector2D(a, a); +} + +template +Vector2D operator + (const Vector2D &p, const T &a) +{ + return p + Vector2D(a, a); +} + +template +Vector2D operator - (const Vector2D &p1, const Vector2D &p2) +{ + Vector2D result; + result.px = p1.px - p2.px; + result.py = p1.py - p2.py; + return result; +} + +template +Vector2D operator - (const T &a, const Vector2D &p) +{ + return Vector2D(a, a) - p ; +} + +template +Vector2D operator - (const Vector2D &p, const T &a) +{ + return p - Vector2D(a, a); +} + +template +Vector2D Vector2D::operator - (void) +{ + return Vector2D(-this->px, -this->py); +} + +template +Vector2D operator * (const Vector2D &p1, const Vector2D &p2) +{ + Vector2D result; + result.px = p1.px * p2.px; + result.py = p1.py * p2.py; + return result; +} + +template +Vector2D operator * (const T &a, const Vector2D &p) +{ + return p * Vector2D(a, a); +} + +template +Vector2D operator * (const Vector2D &p, const T &a) +{ + return p * Vector2D(a, a); +} + +template +Vector2D operator / (const Vector2D &p1, const Vector2D &p2) +{ + Vector2D result; + result.px = p1.px / p2.px; + result.py = p1.py / p2.py; + return result; +} + +template +Vector2D operator / (const T &a, const Vector2D &p) +{ + return Vector2D(a, a) / p; +} + +template +Vector2D operator / (const Vector2D &p, const T &a) +{ + return p / Vector2D(a, a); +} + +/*template +ostream &operator << (ostream &os, const Vector2D &p) +{ + os << "(" << p.px << "," << p.py << ")"; + return os; +}*/ + +#endif diff --git a/src/Vector3D.cpp b/src/Vector3D.cpp new file mode 100644 index 0000000..a2fa6e9 --- /dev/null +++ b/src/Vector3D.cpp @@ -0,0 +1,160 @@ +/* + * This source file is part of Dungeon Digger + * Website: http://sourceforge.net/projects/dungeondigger/ + * + * Copyright (C) 2006 Dungeon Digger Team + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ +#ifdef __VECTOR3D__ + +#include +using namespace std; + +template +Vector3D::Vector3D(const T &x, const T &y, const T &z) +:Triplet(x, y, z) +{ +} + +template +Vector3D::Vector3D(const Vector3D &p) +:Triplet(p) +{ +} + +template +Vector3D::~Vector3D() +{ +} + +///Use an exception ? +template +T &Vector3D::operator [] (const int &i) +{ + if (i == 0) + return this->px; + else if (i == 1) + return this->py; + else + return this->pz; +} + +template +const T &Vector3D::operator [] (const int &i) const +{ + if (i == 0) + return this->px; + else if (i == 1) + return this->py; + else + return this->pz; +} + +template +Vector3D operator + (const Vector3D &p1, const Vector3D &p2) +{ + Vector3D result; + result.px = p1.px + p2.px; + result.py = p1.py + p2.py; + result.pz = p1.pz + p2.pz; + return result; +} + +template +Vector3D operator + (const T &a, const Vector3D &p) +{ + return p + Vector3D(a, a, a); +} + +template +Vector3D operator + (const Vector3D &p, const T &a) +{ + return p + Vector3D(a, a, a); +} + +template +Vector3D operator - (const Vector3D &p1, const Vector3D &p2) +{ + Vector3D result; + result.px = p1.px - p2.px; + result.py = p1.py - p2.py; + result.pz = p1.pz - p2.pz; + return result; +} + +template +Vector3D operator - (const T &a, const Vector3D &p) +{ + return Vector3D(a, a, a) - p ; +} + +template +Vector3D operator - (const Vector3D &p, const T &a) +{ + return p - Vector3D(a, a, a); +} + +template +Vector3D Vector3D::operator - (void) +{ + return Vector3D(-this->px, -this->py, -this->pz); +} + +template +Vector3D operator * (const Vector3D &p1, const Vector3D &p2) +{ + Vector3D result; + result.px = p1.px * p2.px; + result.py = p1.py * p2.py; + result.pz = p1.pz * p2.pz; + return result; +} + +template +Vector3D operator * (const T &a, const Vector3D &p) +{ + return p * Vector3D(a, a, a); +} + +template +Vector3D operator * (const Vector3D &p, const T &a) +{ + return p * Vector3D(a, a, a); +} + +template +Vector3D operator / (const Vector3D &p1, const Vector3D &p2) +{ + Vector3D result; + result.px = p1.px / p2.px; + result.py = p1.py / p2.py; + result.pz = p1.pz / p2.pz; + return result; +} + +template +Vector3D operator / (const T &a, const Vector3D &p) +{ + return Vector3D(a, a, a) / p; +} + +template +Vector3D operator / (const Vector3D &p, const T &a) +{ + return p / Vector3D(a, a, a); +} + +#endif diff --git a/src/Wiimote.cpp b/src/Wiimote.cpp new file mode 100644 index 0000000..9698669 --- /dev/null +++ b/src/Wiimote.cpp @@ -0,0 +1,119 @@ +#include "Wiimote.hpp" + +#include +using namespace std; + +#define MAX(X,Y) (((X)>(Y))?(X):(Y)) +#define MIN(X,Y) (((X)<(Y))?(X):(Y)) + +Wiimote::Wiimote(int nb) +:_wiimotes(wiiuse_init(nb)), _nb(nb), _strumstate(false) +{ + for (int i = 0 ; i < 5 ; i++) + _keystate[i] = false; + + printf("wiimote structure : %p\n", _wiimotes); + + int found = wiiuse_find(_wiimotes, nb, 5); + if (!found) + { + printf ("No wiimotes found.\n"); + throw 0; + } + + int connected = wiiuse_connect(_wiimotes, nb); + if (connected) + printf("Connected to %d wiimotes (of %d found).\n", connected, found); + else + { + printf("Failed to connect to any wiimote.\n"); + throw 1; + } + + for (int i = 0 ; i < MIN(nb,4) ; i++) + { +// cout << "+ leds of " << i << endl; + wiiuse_set_leds(_wiimotes[i], WIIMOTE_LED_1 * i); +// cout << "- leds of " << i << endl; + } + +} +void Wiimote::handleKey(guitar_hero_3_t* gh3, int key, int button) +{ + if (_keystate[key]) + { + if (!IS_PRESSED(gh3, button)) + handleButtonOff(key); + _keystate[key] = false; + } + else + { + if (IS_PRESSED(gh3, button)) + handleButtonOn(key); + _keystate[key] = true; + } +} + +void Wiimote::handleEvents() +{ + if (!wiiuse_poll(_wiimotes, _nb)) + return; + for (int i = 0 ; i < _nb ; i++) + { + switch(_wiimotes[i]->event) + { + //normal event + case WIIUSE_EVENT: + if (_wiimotes[i]->exp.type == EXP_GUITAR_HERO_3) + { + struct guitar_hero_3_t* gh3 = (guitar_hero_3_t *)&_wiimotes[i]->exp.gh3; + + if (_strumstate) + { + if (!IS_PRESSED(gh3, GUITAR_HERO_3_BUTTON_STRUM_UP) && !IS_PRESSED(gh3, GUITAR_HERO_3_BUTTON_STRUM_DOWN)) + { + handleStrumOff(); + _strumstate = false; + } + } + else + { + if (IS_PRESSED(gh3, GUITAR_HERO_3_BUTTON_STRUM_UP) || IS_PRESSED(gh3, GUITAR_HERO_3_BUTTON_STRUM_DOWN)) + { + handleStrumOn(); + _strumstate = true; + } + } + + handleButtons(IS_PRESSED(gh3, GUITAR_HERO_3_BUTTON_GREEN), + IS_PRESSED(gh3, GUITAR_HERO_3_BUTTON_RED), + IS_PRESSED(gh3, GUITAR_HERO_3_BUTTON_YELLOW), + IS_PRESSED(gh3, GUITAR_HERO_3_BUTTON_BLUE), + IS_PRESSED(gh3, GUITAR_HERO_3_BUTTON_ORANGE)); +/* handleKey(gh3, 0, GUITAR_HERO_3_BUTTON_GREEN); + handleKey(gh3, 1, GUITAR_HERO_3_BUTTON_RED); + handleKey(gh3, 2, GUITAR_HERO_3_BUTTON_YELLOW); + handleKey(gh3, 3, GUITAR_HERO_3_BUTTON_BLUE); + handleKey(gh3, 4, GUITAR_HERO_3_BUTTON_ORANGE);*/ + } + + break; + + case WIIUSE_GUITAR_HERO_3_CTRL_INSERTED: + cout << "Ready to rock!" << endl; + break; + + case WIIUSE_GUITAR_HERO_3_CTRL_REMOVED: + cout << "This is the end..." << endl; + break; + + default: + break; + } + } + +} + +void Wiimote::vibration(int wiimote, int time) +{ +} diff --git a/src/main.cpp b/src/main.cpp new file mode 100644 index 0000000..f353f6b --- /dev/null +++ b/src/main.cpp @@ -0,0 +1,561 @@ +#include + +#include "MIDIReader.hpp" +#include "Track.hpp" +#include "Texture.hpp" +#include "Mixer.hpp" + +#include +#include +/*#ifdef __APPLE__ +#include +#else +#include +#endif*/ + +#include +#include +#include +#include +extern double SECONDSIZE; + +#include "Wiimote.hpp" + +double posx, posy, posz; +struct timeval start; +Texture *texturebois, *texturefond; +int resolution_x, resolution_y; +Config fromKeyboard; + +int bandVolume, guitarVolume, bipVolume; + +FILE *logfile = NULL; +//list bips; +//list::iterator cb; + +void init() +{ + //initializes SDL + cout << "init SDL" << endl; + const SDL_VideoInfo* info = NULL; + + atexit(SDL_Quit); + + if( SDL_Init(SDL_INIT_EVERYTHING) <0 ) + throw "Error while loading SDL"; + + //Initialize SDL_mixer + if (Mix_OpenAudio( 22050, MIX_DEFAULT_FORMAT, 2, 1024 ) == -1 ); +// throw String("Can't initialize sound"); + + cout << "get video info" << endl; + info = SDL_GetVideoInfo(); + if(!info) + throw "Impossible to get information from SDL"; + + SDL_EnableUNICODE(1); + +// int width, height; + // we search for the available screen sizes + int searchflags = SDL_HWSURFACE;// | SDL_FULLSCREEN; + SDL_Rect **modes = SDL_ListModes(NULL, searchflags); + if (modes == NULL) + throw "Impossible to get the screen resolution !"; + else if (modes == (SDL_Rect **)-1) + { + resolution_x = 1280; + resolution_y = 1024; + } + else + { + int i; + for (i=0 ; modes[i] ; i++) + { + cout << "Resolution available: " << modes[i]->w << "x" << modes[i]->h << endl; + if (modes[i]->w == 1280 && modes[i]->h == 1024) + { + resolution_x = modes[i]->w; + resolution_y = modes[i]->h; + break; + } + } + if (!modes[i]) + { + cout << "Resolution wanted not available" << endl; + resolution_x = 1024; + resolution_y = 768; + } + } + + //initializes Opengl + if (SDL_InitSubSystem(SDL_INIT_VIDEO) < 0) + throw "Couldn't initialise Video SubSystem: %s\n"; + + SDL_GL_SetAttribute(SDL_GL_RED_SIZE, 8); + SDL_GL_SetAttribute(SDL_GL_GREEN_SIZE, 8); + SDL_GL_SetAttribute(SDL_GL_BLUE_SIZE, 8); + SDL_GL_SetAttribute(SDL_GL_ALPHA_SIZE, 8); + SDL_GL_SetAttribute(SDL_GL_STENCIL_SIZE, 8); + SDL_GL_SetAttribute(SDL_GL_DOUBLEBUFFER, 1); + SDL_GL_SetAttribute(SDL_GL_ACCUM_RED_SIZE, 8); + SDL_GL_SetAttribute(SDL_GL_ACCUM_GREEN_SIZE, 8); + SDL_GL_SetAttribute(SDL_GL_ACCUM_BLUE_SIZE, 8); + SDL_GL_SetAttribute(SDL_GL_ACCUM_ALPHA_SIZE, 8); + + int flags = SDL_OPENGL | SDL_OPENGLBLIT | SDL_HWSURFACE;// | SDL_FULLSCREEN; + +// int flags = SDL_OPENGL | SDL_OPENGLBLIT | SDL_SWSURFACE | SDL_FULLSCREEN; + SDL_Surface * screen; + if (!(screen = SDL_SetVideoMode(resolution_x, resolution_y, 0, flags))) + throw "Impossible to change the video mode"; + + // Utilisation de l'anti-aliasing possible ? + if (SDL_GL_SetAttribute(SDL_GL_MULTISAMPLEBUFFERS, 1) == -1) + throw "Impossible to initialize SDL_GL_MULTISAMPLEBUFFERS"; + + // Nombre de tampons utilisés pour l'anti-aliasing (la valeur utilisée dépend de la carte graphique) + if (SDL_GL_SetAttribute(SDL_GL_MULTISAMPLESAMPLES, 6) == -1) + throw "Impossible to initialize SDL_GL_MULTISAMPLESAMPLES"; + + GLdouble ratio = (GLdouble) screen->w / screen->h; + + printf("infos : %d %d %d %d\n", screen->flags, screen->w, screen->h, screen->pitch); + printf("Video resolution: %dx%dx%d (ratio = %3.2f)\n", screen->w, screen->h, screen->format->BitsPerPixel, ratio); + printf("OpenGL infos\n"); + printf("------------\n"); + printf("Vendor : %s\n", glGetString(GL_VENDOR)); + printf("Renderer : %s\n", glGetString(GL_RENDERER)); + printf("Version : %s\n", glGetString(GL_VERSION)); + printf("Extensions: %s\n", glGetString(GL_EXTENSIONS)); + + glClearColor(1.0, 1.0, 1.0, 0.0); + glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); + glViewport(0, 0, resolution_x, resolution_y); + + glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); + glEnable(GL_BLEND); + glShadeModel(GL_SMOOTH); + glEnable(GL_NORMALIZE); + + GLfloat light_ambient[] = { 0.8, 0.7, 0.9, 1.0 }; + GLfloat light_diffuse[] = { 1.0, 0.9, 0.8, 1.0 }; + GLfloat light_specular[] = { 1.0, 0.9, 0.7, 1.0}; + glLightfv(GL_LIGHT0, GL_AMBIENT, light_ambient); + glLightfv(GL_LIGHT0, GL_DIFFUSE, light_diffuse); + glLightfv(GL_LIGHT0, GL_SPECULAR, light_specular); +// glLightf(GL_LIGHT0, GL_SPOT_EXPONENT, 0.5); + glLightf(GL_LIGHT0, GL_QUADRATIC_ATTENUATION, 0.01); + glLightf(GL_LIGHT0, GL_LINEAR_ATTENUATION, 0.01); + glEnable(GL_LIGHTING); + glEnable(GL_LIGHT0); +// SDL_EnableKeyRepeat(10, 100); + + texturebois = new Texture("wood.jpg", true); + texturefond = new Texture("back.jpg"); + + posx=0.0; + posy=25.0; + posz=0.0; + + fromKeyboard.setPosition(-1); + fromKeyboard.setEnd(-1); +} + +#define POSITION_EYE 45 +#define POSITION_CENTER (-80) +#define VIEWLENGTH 250 + + +void draw(Track &t, uint8 diff) +{ + struct timeval now; + gettimeofday(&now, NULL); + double postime = (now.tv_sec - start.tv_sec) * 1000. + (now.tv_usec - start.tv_usec) / 1000.0; + posz = -SECONDSIZE * postime; + +// cout << "draw screen" << endl; + glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); +// glColor(1.0, 1.0, 1.0, 0.0); + + //Draw the back + glDisable(GL_LIGHTING); + glMatrixMode(GL_PROJECTION); + glLoadIdentity(); + gluOrtho2D(0, resolution_x, resolution_y, 0); + glMatrixMode(GL_MODELVIEW); + glLoadIdentity(); + + glEnable(GL_TEXTURE_2D); + texturefond->useTexture(); + glBegin(GL_QUADS); + glColor3f(1.0, 1.0, 1.0); + glTexCoord2d(0.0, 0.0); glVertex2f(0.0, 0.0); + glTexCoord2d(0.0, 1.0); glVertex2f(0.0, resolution_y); + glTexCoord2d(1.0, 1.0); glVertex2f(resolution_x, resolution_y); + glTexCoord2d(1.0, 0.0); glVertex2f(resolution_x, 0.0); + glEnd(); + glDisable(GL_TEXTURE_2D); + + glMatrixMode(GL_PROJECTION); + glLoadIdentity(); + gluPerspective( 45.0f, double(resolution_x) / double(resolution_y), POSITION_EYE+3, VIEWLENGTH ); + glMatrixMode(GL_MODELVIEW); + glLoadIdentity(); + //cout << "posz=" << posz << endl; + gluLookAt(posx, posy, posz + POSITION_EYE, 0, 0, posz + POSITION_CENTER, 0.0,1.0,0.0); +// gluLookAt(posx-50, posy, posz-POSITION, 0, 0,posz-POSITION, 0.0,1.0,0.0); + GLfloat light_position[] = { 0.0, 10.0 , posz, 1.0 }; + glLightfv(GL_LIGHT1, GL_POSITION, light_position); + +// cout << "End: " << t.getEndOfTrack() << endl; + +//glEnable(GL_LIGHTING); + + // Draw the guitar neck + glEnable(GL_TEXTURE_2D); + texturebois->useTexture(); + glBegin(GL_QUADS); + glColor3f(1.0, 1.0, 1.0); // Set The Color To Green + glTexCoord2d(0.0, 0.0); glVertex3f( NECKWIDTH,0, 0); + glTexCoord2d(0.0, 20000); glVertex3f( NECKWIDTH,0,-1500000); + glTexCoord2d(1.0, 20000); glVertex3f(-NECKWIDTH,0,-1500000); + glTexCoord2d(1.0, 0.0); glVertex3f(-NECKWIDTH,0, 0); + glEnd(); + glDisable(GL_TEXTURE_2D); + + //Draw the position bar + glMatrixMode(GL_MODELVIEW); + glPushMatrix(); + glTranslatef(0,0,posz); + glBegin(GL_QUADS); + glColor3f(0.8, 0.8, 0.8); + glNormal3f(0, 1, 0); + glVertex3f( NECKWIDTH,0, 1); + glVertex3f( NECKWIDTH,0.2, 0); + glVertex3f(-NECKWIDTH,0.2, 0); + glVertex3f(-NECKWIDTH,0, 1); + glVertex3f( NECKWIDTH,0.2, 0); + glVertex3f( NECKWIDTH,0, -1); + glVertex3f(-NECKWIDTH,0, -1); + glVertex3f(-NECKWIDTH,0.2, 0); + glEnd(); + glBegin(GL_QUADS); + glColor3f(0.8, 0.8, 0.8); + glNormal3f(0, 1, 0); + glVertex3f(NECKWIDTH, 0, 1); + glVertex3f(NECKWIDTH+.1,0.2, 1); + glVertex3f(NECKWIDTH+.1,0.2,-VIEWLENGTH); + glVertex3f(NECKWIDTH,0, -VIEWLENGTH); + glVertex3f(NECKWIDTH+.1, 0.2, 1); + glVertex3f(NECKWIDTH+.2,0, 1); + glVertex3f(NECKWIDTH+.2,0,-VIEWLENGTH); + glVertex3f(NECKWIDTH+.1,0.2, -VIEWLENGTH); + glEnd(); + glBegin(GL_QUADS); + glColor3f(0.8, 0.8, 0.8); + glNormal3f(0, 1, 0); + glVertex3f(-NECKWIDTH, 0, 1); + glVertex3f(-NECKWIDTH-.1,0.2, 1); + glVertex3f(-NECKWIDTH-.1,0.2,-VIEWLENGTH); + glVertex3f(-NECKWIDTH,0, -VIEWLENGTH); + glVertex3f(-NECKWIDTH-.1, 0.2, 1); + glVertex3f(-NECKWIDTH-.2,0, 1); + glVertex3f(-NECKWIDTH-.2,0,-VIEWLENGTH); + glVertex3f(-NECKWIDTH-.1,0.2, -VIEWLENGTH); + glEnd(); + fromKeyboard.display(); + glPopMatrix(); + + //draw the frets + t.drawFrets(postime); + + // Draw the notes + t.drawNotes(postime, diff); + + SDL_GL_SwapBuffers(); +} + +void handleKeyOn(keys k) +{ + fromKeyboard.addKey(k); +/* switch(k) + { + case KEY0: + cout << "\033[1;32mGREEN\033[0m" << endl; + break; + case KEY1: + cout << "\033[0;31mRED\033[0m" << endl; + break; + case KEY2: + cout << "\033[1;33mYELLOW\033[0m" << endl; + break; + case KEY3: + cout << "\033[1;34mBLUE\033[0m" << endl; + break; + case KEY4: + cout << "\033[0;33mORANGE\033[0m" << endl; + break; + }*/ +} + +void handleKeyOff(keys k) +{ +// fromKeyboard.remKey(k); + if (fromKeyboard.getPosition() == -1) + return; + + struct timeval now; + gettimeofday(&now, NULL); + double postime = (now.tv_sec - start.tv_sec) * 1000 + (now.tv_usec - start.tv_usec) / 1000.0; + fromKeyboard.setEnd(postime); + cout << fromKeyboard << endl; + fromKeyboard.log("Play", logfile); + + fromKeyboard.setPosition(postime); + fromKeyboard.setEnd(-1); +} + +void handleKeys(bool a, bool b, bool c, bool d, bool e) +{ + if (fromKeyboard.isNone()) + fromKeyboard.setPosition(-1); + fromKeyboard.setKeys(a, b, c, d, e); +} + +void handleStrokeOn() +{ + struct timeval now; + gettimeofday(&now, NULL); + double postime = (now.tv_sec - start.tv_sec) * 1000 + (now.tv_usec - start.tv_usec) / 1000.0; + //cout << postime << endl; + + if (fromKeyboard.getPosition() != -1) + { + fromKeyboard.setEnd(postime); + cout << fromKeyboard << endl; + fromKeyboard.log("Play", logfile); + } + fromKeyboard.setPosition(postime); + fromKeyboard.setEnd(-1); +} + +void handleStrokeOff() +{ +} + +class MyWiimote: public Wiimote +{ + public: + MyWiimote():Wiimote(1){} + + void handleStrumOn() { handleStrokeOn(); } + void handleStrumOff() { handleStrokeOff(); } + void handleButtonOn(int k) { handleKeyOn(keys(k)); } + void handleButtonOff(int k) { handleKeyOff(keys(k)); } + void handleButtons(bool a, bool b, bool c, bool d, bool e) { handleKeys(a, b, c, d, e); } +}; + +bool processEvents() +{ + SDL_Event event; +// bool quitProgram = false; + + while (SDL_PollEvent (&event)) + { + Uint8 *keystate; + switch (event.type) + { + case SDL_QUIT: + return true; + break; + + case SDL_KEYDOWN: + keystate = SDL_GetKeyState(NULL); + handleKeys(keystate[SDLK_a], keystate[SDLK_z], keystate[SDLK_e], keystate[SDLK_r], keystate[SDLK_t]); + switch(((SDL_KeyboardEvent *)(&event))->keysym.sym) + { + case SDLK_ESCAPE: + return true; + case SDLK_UP: + SECONDSIZE +=10; + break; + case SDLK_DOWN: + SECONDSIZE -=1; + break; + case SDLK_LEFT: + posy +=1; + break; + case SDLK_RIGHT: + posy -=1; + break; + case SDLK_KP_PLUS: + Mixer::getInstance()->setMusicVolume(Mixer::getInstance()->getMusicVolume() + 10); + Mixer::getInstance()->setSoundVolume(Mixer::getInstance()->getSoundVolume() + 10); + break; + case SDLK_KP_MINUS: + Mixer::getInstance()->setMusicVolume(Mixer::getInstance()->getMusicVolume() - 10); + Mixer::getInstance()->setSoundVolume(Mixer::getInstance()->getSoundVolume() - 10); + break; +/* case SDLK_a: + handleKeyOn(KEY0); + break; + case SDLK_z: + handleKeyOn(KEY1); + break; + case SDLK_e: + handleKeyOn(KEY2); + break; + case SDLK_r: + handleKeyOn(KEY3); + break; + case SDLK_t: + handleKeyOn(KEY4); + break;*/ + case SDLK_SPACE: + handleStrokeOn(); + break; + default: + break; + } + break; + + case SDL_KEYUP: + switch(((SDL_KeyboardEvent *)(&event))->keysym.sym) + { + case SDLK_a: + handleKeyOff(KEY0); + break; + case SDLK_z: + handleKeyOff(KEY1); + break; + case SDLK_e: + handleKeyOff(KEY2); + break; + case SDLK_r: + handleKeyOff(KEY3); + break; + case SDLK_t: + handleKeyOff(KEY4); + break; + case SDLK_SPACE: + handleStrokeOff(); + break; + default: + break; + } + keystate = SDL_GetKeyState(NULL); + handleKeys(keystate[SDLK_a], keystate[SDLK_z], keystate[SDLK_e], keystate[SDLK_r], keystate[SDLK_t]); + break; + default: + // lasteventtype = OTHER; + break; + } + } + return false; +} + +int main(int argc, char *argv[]) +{ + bool iswiimoteconnected = false; + Wiimote *mw; + try + { + mw = new MyWiimote(); + iswiimoteconnected = true; + } + catch(...){} + + if (argc < 2) + { + cout << "Usage : " << argv[0] << "songname" << endl; + exit(0); + } + String songname(argv[1]); + + if (argc >= 3) + { + time_t tim = time(NULL); + struct tm *t = gmtime(&tim); + String logfilename = String(argv[2]) + "-" + String(1900 + t->tm_year) + "-" + String(t->tm_mon) + "-" + String(t->tm_mday) + "-" + String(t->tm_hour) + "-" + String(t->tm_min) + "-" + String(t->tm_sec) + "-" + String(argv[1]); + logfile = fopen(logfilename.c_str(), "w"); + } + + init(); + + cout << "Loading song" << endl; + MIDIReader *test; + try + { + test = new MIDIReader(songname + "/notes.mid"); + } + catch(...) + { + cerr << "Unable to load the song file" << endl; + exit(0); + } + + cout << "Loading notes" << endl; + + test->readHeader(); + Track tr; + test->readTracks(tr); + + cout << "Computing metronome bips" << endl; + + //compute the ticks positions + tr.computeBips(); + + bool quitProgram = false; + + cout << "Loading sounds" << endl; + + Mixer::getInstance()->addSound("guitar", songname + "/guitar.ogg"); + bool rhythm = Mixer::getInstance()->addSound("rhythm", songname + "/rhythm.ogg"); + + Mixer::getInstance()->addSound("bip","bip.ogg"); + Mixer::getInstance()->setMusicVolume(30); + Mixer::getInstance()->setSoundVolume(30); + + cout << "LET'S ROCK!" << endl; + + Mixer::getInstance()->playMusic(songname + "/song.ogg"); + Mixer::getInstance()->playSound("guitar"); + if (rhythm) + Mixer::getInstance()->playSound("rhythm"); + gettimeofday(&start, NULL); +/* + Sound music; + cout << "Load sounds" << endl; + music.addSound(songname + "/song.ogg"); + music.addSound(songname + "/guitar.ogg"); + music.addSound(songname + "/rhythm.ogg"); + cout << "Mixing sounds" << endl; + Mix_Chunk *m_chunk = music.mix(); + cout << "Play music" << endl; + Mix_PlayChannel(-1, m_chunk, 1); +*/ +/* + Mix_Chunk *Mix_LoadWAV(char *file) x2/3 + for(...) + a/3+b/3+c/3; + int Mix_SetPanning(int channel, Uint8 left, Uint8 right) left + right + int Mix_PlayChannel(int channel, Mix_Chunk *chunk, int loops) +*/ + + while(!quitProgram) + { +// cout << "events" << endl; + quitProgram = processEvents(); + if (iswiimoteconnected) + mw->handleEvents(); +// cout << "draw" << endl; + draw(tr, NORMAL); +// cout << "pause" << endl; +// SDL_Delay(10); + } + + if (logfile) + fclose(logfile); + + return 1; +}