--- /dev/null
+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 $<
--- /dev/null
+#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 <GL/glew.h>
+#include <iostream>
+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
--- /dev/null
+/*
+ * 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 <iostream>
+using namespace std;
+
+template <class T> class List;
+
+template <class T> List<T> &operator+(const T &elt, List<T> &l);
+template <class T> ostream &operator << (ostream &os, const List<T> &l);
+
+
+template <class T>
+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<T> &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<T> &operator- (const T &elt);
+ //remove the element of position pos in the list
+ List<T> &operator- (const int &pos);
+
+ //add an element at the head
+ friend List<T> &operator+ <>(const T &elt, List<T> &l);
+ //add an element at the tail
+ List<T> &operator+ (const T &elt);
+ List<T> &operator+= (const T &elt);
+ //concatenate two lists
+ List<T> &operator+ (const List<T> &l);
+ List<T> &operator+= (const List<T> &l);
+
+ List<T> &operator= (const List<T> &l);
+
+ friend ostream &operator<< <>(ostream &os, const List<T> &l);
+
+ //friend istream &operator >> (istream & is, const List &l);
+ protected:
+
+ void deleteElt(Node *elt);
+
+ Node *head, *tail;
+};
+
+#include "../src/List.cpp"
+#endif
--- /dev/null
+#ifndef __MIDIREADER__
+#define __MIDIREADER__
+
+#include <stdio.h>
+
+#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
--- /dev/null
+/*
+ * 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 <SDL_mixer/SDL_mixer.h>
+#else
+#include <SDL/SDL_mixer.h>
+#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<Sound *> _sounds;
+ static Mix_Music *_music;
+ static int *_soundChannels;
+
+ int _musicVolume, _soundVolume;
+
+ static Mixer *_minstance;
+};
+
+#endif
--- /dev/null
+/*
+ * 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 <iostream>
+using namespace std;
+
+template <class T, class U> class Pair;
+
+template <class T, class U> Pair<T, U> operator + (const Pair<T, U> &p1, const Pair<T, U> &p2);
+template <class T, class U> Pair<T, U> operator + (const T &a, const Pair<T, U> &p);
+template <class T, class U> Pair<T, U> operator + (const Pair<T, U> &p1, const U &a);
+template <class T, class U> Pair<T, U> operator - (const Pair<T, U> &p1, const Pair<T, U> &p2);
+template <class T, class U> Pair<T, U> operator - (const T &a, const Pair<T, U> &p);
+template <class T, class U> Pair<T, U> operator - (const Pair<T, U> &p1, const U &a);
+template <class T, class U> Pair<T, U> operator * (const Pair<T, U> &p1, const Pair<T, U> &p2);
+template <class T, class U> Pair<T, U> operator * (const T &a, const Pair<T, U> &p);
+template <class T, class U> Pair<T, U> operator * (const Pair<T, U> &p1, const U &a);
+template <class T, class U> Pair<T, U> operator / (const Pair<T, U> &p1, const Pair<T, U> &p2);
+template <class T, class U> Pair<T, U> operator / (const T &a, const Pair <T, U>&p);
+template <class T, class U> Pair<T, U> operator / (const Pair<T, U> &p1, const U &a);
+template <class T, class U> ostream &operator << (ostream &os, const Pair<T, U> &s);
+
+template <class T, class U>
+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
--- /dev/null
+/*
+ * 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 <iostream>
+using namespace std;
+
+#include "String.hpp"
+#include "List.hpp"
+#include "Pair.hpp"
+
+template <class T>
+class PrefixTree;
+
+template <class T>
+ostream &operator << (ostream &os, const PrefixTree<T> &t);
+
+template <class T>
+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<String, T> elt()
+ {
+ if (current->haskey)
+ return Pair<String, T>(current->wholePrefix(), current->key);
+ else
+ throw "No key";
+ //should not happen
+ return Pair<String, T>();
+ }
+ 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<String> sonsList(const String &pref) const;
+ String completePrefix(const String &pref) const;
+
+ friend ostream &operator<< <>(ostream &os, const PrefixTree<T> &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 <class T>
+// ostream &operator << (ostream &os, const typename PrefixTree<T>::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 <class T>
+// ostream &operator<< <>(ostream &os, const typename PrefixTree<T>::TNode &n);
+
+#include "../src/PrefixTree.cpp"
+#endif
--- /dev/null
+/*
+ * 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 <string>
+#include <iostream>
+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
--- /dev/null
+/*
+ * 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 <GL/glew.h>
+#include <SDL/SDL.h>
+// #include <SDL/SDL_opengl.h>
+
+#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<int> getSize() const;
+
+ private:
+ SDL_Surface *surface;
+ unsigned int gltex;
+ GLuint texture;
+ Vector2D<int> size;
+ bool repeat;
+};
+
+#endif
--- /dev/null
+/*
+ * 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 <cmath>
+
+#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<int> rotatePoint(const Vector2D<int> pos, const Vector2D<int> center, const double &angle);
+
+template<class T>T maxi(const T&a, const T&b)
+{
+ if (a>b)
+ return a;
+ else
+ return b;
+}
+
+template<class T>T mini(const T&a, const T&b)
+{
+ if (a<b)
+ return a;
+ else
+ return b;
+}
+
+double mod2pi(const double &a);
+
+#endif
--- /dev/null
+#ifndef __TRACK__
+#define __TRACK__
+
+#define NBDIFFICULTIES 4
+
+enum difficulties { EASY, NORMAL, HARD, EXPERT };
+
+#include <list>
+#include <map>
+/*#include <iostream>
+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<uint32, Config> _notes[NBDIFFICULTIES];
+ map<uint32, uint32> _tempo;
+
+// private:
+ list<double> _bips;
+
+ Config _currentconfig[NBDIFFICULTIES];
+
+ uint32 _nbnotes[NBDIFFICULTIES];
+ uint32 _totallength[NBDIFFICULTIES];
+ uint32 _totalnotes[128];
+ uint32 _trackSize;
+ bool _active;
+};
+
+#endif
--- /dev/null
+/*
+ * 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 <iostream>
+using namespace std;
+
+template <class T, class U, class V> class Triplet;
+
+template <class T, class U, class V> Triplet<T, U, V> operator + (const Triplet<T, U, V> &p1, const Triplet<T, U, V> &p2);
+template <class T, class U, class V> Triplet<T, U, V> operator + (const T &a, const Triplet<T, U, V> &p);
+template <class T, class U, class V> Triplet<T, U, V> operator + (const Triplet<T, U, V> &p1, const U &a);
+template <class T, class U, class V> Triplet<T, U, V> operator - (const Triplet<T, U, V> &p1, const Triplet<T, U, V> &p2);
+template <class T, class U, class V> Triplet<T, U, V> operator - (const T &a, const Triplet<T, U, V> &p);
+template <class T, class U, class V> Triplet<T, U, V> operator - (const Triplet<T, U, V> &p1, const U &a);
+template <class T, class U, class V> Triplet<T, U, V> operator * (const Triplet<T, U, V> &p1, const Triplet<T, U, V> &p2);
+template <class T, class U, class V> Triplet<T, U, V> operator * (const T &a, const Triplet<T, U, V> &p);
+template <class T, class U, class V> Triplet<T, U, V> operator * (const Triplet<T, U, V> &p1, const U &a);
+template <class T, class U, class V> Triplet<T, U, V> operator / (const Triplet<T, U, V> &p1, const Triplet<T, U, V> &p2);
+template <class T, class U, class V> Triplet<T, U, V> operator / (const T &a, const Triplet <T, U, V>&p);
+template <class T, class U, class V> Triplet<T, U, V> operator / (const Triplet<T, U, V> &p1, const U &a);
+template <class T, class U, class V> ostream &operator << (ostream &os, const Triplet<T, U, V> &s);
+
+template <class T, class U, class V>
+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
--- /dev/null
+/*
+ * 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 <iostream>
+using namespace std;*/
+
+template <class T> class Vector2D;
+
+template <class T> Vector2D<T> operator + (const Vector2D<T> &p1, const Vector2D<T> &p2);
+template <class T> Vector2D<T> operator + (const T &a, const Vector2D<T> &p);
+template <class T> Vector2D<T> operator + (const Vector2D<T> &p1, const T &a);
+template <class T> Vector2D<T> operator - (const Vector2D<T> &p1, const Vector2D<T> &p2);
+template <class T> Vector2D<T> operator - (const T &a, const Vector2D<T> &p);
+template <class T> Vector2D<T> operator - (const Vector2D<T> &p1, const T &a);
+template <class T> Vector2D<T> operator * (const Vector2D<T> &p1, const Vector2D<T> &p2);
+template <class T> Vector2D<T> operator * (const T &a, const Vector2D<T> &p);
+template <class T> Vector2D<T> operator * (const Vector2D<T> &p1, const T &a);
+template <class T> Vector2D<T> operator / (const Vector2D<T> &p1, const Vector2D<T> &p2);
+template <class T> Vector2D<T> operator / (const T &a, const Vector2D <T>&p);
+template <class T> Vector2D<T> operator / (const Vector2D<T> &p1, const T &a);
+// template <class T> ostream &operator << (ostream &os, const Vector2D<T> &s);
+
+enum { C_X=0, C_Y=1, C_Z=2 };
+
+template <class T>
+class Vector2D: public Pair<T, T>
+{
+ 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
--- /dev/null
+/*
+ * 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 <iostream>
+using namespace std;*/
+
+template <class T> class Vector3D;
+
+template <class T> Vector3D<T> operator + (const Vector3D<T> &p1, const Vector3D<T> &p2);
+template <class T> Vector3D<T> operator + (const T &a, const Vector3D<T> &p);
+template <class T> Vector3D<T> operator + (const Vector3D<T> &p1, const T &a);
+template <class T> Vector3D<T> operator - (const Vector3D<T> &p1, const Vector3D<T> &p2);
+template <class T> Vector3D<T> operator - (const T &a, const Vector3D<T> &p);
+template <class T> Vector3D<T> operator - (const Vector3D<T> &p1, const T &a);
+template <class T> Vector3D<T> operator * (const Vector3D<T> &p1, const Vector3D<T> &p2);
+template <class T> Vector3D<T> operator * (const T &a, const Vector3D<T> &p);
+template <class T> Vector3D<T> operator * (const Vector3D<T> &p1, const T &a);
+template <class T> Vector3D<T> operator / (const Vector3D<T> &p1, const Vector3D<T> &p2);
+template <class T> Vector3D<T> operator / (const T &a, const Vector3D <T>&p);
+template <class T> Vector3D<T> operator / (const Vector3D<T> &p1, const T &a);
+// template <class T> ostream &operator << (ostream &os, const Vector3D<T> &s);
+
+template <class T>
+class Vector3D: public Triplet<T, T, T>
+{
+ 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
--- /dev/null
+#ifndef __WIIMOTE__
+#define __WIIMOTE__
+
+#ifndef WIN32
+ #include <unistd.h>
+#endif
+
+#include <wiiuse.h>
+
+
+#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
--- /dev/null
+#include "Config.hpp"
+#include <stdio.h>
+
+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;
+}
--- /dev/null
+/*
+ * 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 <class T>
+List<T>::List()
+:head(NULL), tail(NULL)
+{
+}
+
+template <class T>
+List<T>::List(const List<T> &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 <class T>
+List<T>::~List()
+{
+ empty();
+}
+
+template <class T>
+void List<T>::empty()
+{
+ Node *temp = head;
+ while(temp)
+ {
+ Node *temp2 = temp;
+ temp = temp->next;
+ delete temp2;
+ }
+ head = NULL;
+ tail = NULL;
+}
+
+template <class T>
+T &List<T>::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 <class T>
+unsigned int List<T>::size() const
+{
+ Node *temp = head;
+ int s=0;
+ while(temp)
+ {
+ s++;
+ temp = temp->next;
+ }
+ return s;
+}
+
+template <class T>
+bool List<T>::isEmpty() const
+{
+ return head == NULL;
+}
+
+template <class T>
+typename List<T>::Node *List<T>::getHead() const
+{
+ return head;
+}
+
+template <class T>
+void List<T>::setHead(typename List<T>::Node *n)
+{
+ head = n;
+}
+
+template <class T>
+typename List<T>::Node *List<T>::getTail()const
+{
+ return tail;
+}
+
+template <class T>
+void List<T>::setTail(typename List<T>::Node *n)
+{
+ tail = n;
+}
+
+template <class T>
+void List<T>::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 <class T>
+void List<T>::onBottom(const T&elt)
+{
+ *this = *this - elt + elt;
+}
+
+template <class T>
+void List<T>::deleteElt(typename List<T>::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 <class T>
+List<T> &List<T>::operator- (const T &elt)
+{
+ Node *temp = head;
+ while(temp)
+ {
+ if (temp->key == elt)
+ {
+ deleteElt(temp);
+ return *this;
+ }
+ temp = temp->next;
+ }
+ return *this;
+}
+
+template <class T>
+List<T> &List<T>::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 <class T>
+List<T> &operator+ (const T &elt, List<T> &l)
+{
+ typename List<T>::Node *newnode = new typename List<T>::Node(elt, l.getHead(), NULL);
+ if (l.isEmpty())
+ l.setTail(newnode);
+ else
+ l.getHead()->previous = newnode;
+ l.setHead(newnode);
+ return l;
+}
+
+template <class T>
+List<T> &List<T>::operator+ (const T &elt)
+{
+ Node *newnode = new Node(elt, NULL, tail);
+ if (isEmpty())
+ head = newnode;
+ else
+ tail->next = newnode;
+ tail = newnode;
+ return *this;
+}
+
+template <class T>
+List<T> &List<T>::operator+= (const T &elt)
+{
+ return *this + elt;
+}
+
+//TODO: use iterators
+template <class T>
+List<T> &List<T>::operator+ (const List<T> &l)
+{
+ Node *temp = l.head;
+ while(temp)
+ {
+ *this = *this + temp->key;
+ temp = temp->next;
+ }
+ return *this;
+}
+
+//TODO: use iterators
+template <class T>
+List<T> &List<T>::operator+= (const List<T> &l)
+{
+ Node *temp = l.head;
+ while(temp)
+ {
+ *this = *this + temp->key;
+ temp = temp->next;
+ }
+ return *this;
+}
+
+template <class T>
+List<T> &List<T>::operator= (const List<T> &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 <class T>
+ostream &operator<< (ostream &os, const List<T> &l)
+{
+ typename List<T>::Node *temp = l.getHead();
+ while(temp)
+ {
+ os << temp->key;
+ if (temp->next)
+ os << ", ";
+ temp = temp->next;
+ }
+ return os;
+}
+
+#endif
--- /dev/null
+// For format explanation, see http://www.sonicspot.com/guide/midifiles.html
+
+#include <MIDIReader.hpp>
+#include <arpa/inet.h>
+#include <iostream>
+using namespace std;
+#include <string.h>
+
+#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 ; i<nb ; i++)
+ ((uint8 *)data)[i] = temp[nb - i - 1];
+ _position += nb;
+}
+
+void MIDIReader::printBytes(uint8 *data, uint32 length)
+{
+ for (uint32 i=0 ; i < length ; i++)
+ cout << data[length - i - 1];
+ cout << endl;
+}
--- /dev/null
+/*
+ * 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 "Mixer.hpp"
+#include "Tools.hpp"
+//#include "log.hpp"
+
+Sound::Sound()
+:nbrchunks(0), _chunks(NULL)
+{
+}
+
+Sound::Sound(const Sound &s)
+:nbrchunks(s.nbrchunks), _chunks(s._chunks)
+{
+}
+
+Sound::Sound(const String &filename)
+:nbrchunks(0), _chunks(NULL)
+{
+ addSound(filename);
+}
+
+bool Sound::addSound(const String &filename)
+{
+ 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;
+
+ //_debug_(stderr, "Sound(%s)\n",buffer.c_str());
+
+ if (buffer != "")
+ {
+ Mix_Chunk *c = Mix_LoadWAV(buffer.c_str());
+ if(c)
+ return addChunk(c);
+ else
+ fprintf(stderr, "cannot load sound %s ; %s\n",buffer.c_str(), SDL_GetError());
+ }
+ else
+ fprintf(stderr, "sound file %s not found\n",filename.c_str());
+
+ return false;
+}
+
+bool Sound::addChunk(Mix_Chunk *c)
+{
+ if(c == NULL)
+ return false;
+
+ if(_chunks == NULL)
+ {
+ _chunks=new Mix_Chunk*[1];
+ nbrchunks=1;
+ _chunks[0]=c;
+ }
+ else
+ {
+ nbrchunks++;
+ Mix_Chunk **t=new Mix_Chunk*[nbrchunks];
+ for (int i = 0 ; i < nbrchunks - 1 ; i++)
+ t[i] = _chunks[i];
+ t[nbrchunks-1] = c;
+ delete [] _chunks;
+ _chunks=t;
+ }
+
+ return true;
+}
+
+Sound::~Sound()
+{
+ if (_chunks)
+ {
+ // TODO FIX: if we copy the sound (with the copy constructor)
+ // the destructor doesn't have to destroy the chunk !
+ for(int i = 0 ; i < nbrchunks ; i++)
+ Mix_FreeChunk(_chunks[i]);
+ delete [] _chunks;
+ }
+}
+
+Mix_Chunk *Sound::getChunk()
+{
+ if(!_chunks)
+ return NULL;
+ int i = rand() % nbrchunks;
+ return _chunks[i];
+}
+
+Mix_Chunk *Sound::mix()
+{
+ if (nbrchunks <= 0)
+ return NULL;
+ Mix_Chunk *m = new(Mix_Chunk);
+ m->allocated = _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<msg_t>::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);
+}
+
--- /dev/null
+/*
+ * 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 <iostream>
+using namespace std;
+
+template <class T, class U>
+Pair<T, U>::Pair(const T &x, const U &y)
+:px(x), py(y)
+{
+}
+
+template <class T, class U>
+Pair<T, U>::Pair(const Pair<T, U> &p)
+:px(p.px), py(p.py)
+{
+}
+
+template <class T, class U>
+Pair<T, U>::~Pair()
+{
+}
+
+template <class T, class U>
+const T &Pair<T, U>::getX() const
+{
+ return px;
+}
+
+template <class T, class U>
+const U &Pair<T, U>::getY() const
+{
+ return py;
+}
+
+template <class T, class U>
+void Pair<T, U>::setX(const T &x)
+{
+ px = x;
+}
+
+template <class T, class U>
+void Pair<T, U>::setY(const U &y)
+{
+ py = y;
+}
+
+///Use an exception ?
+// template <class T, class U>
+// T &Pair<T, U>::operator [] (const int &i)
+// {
+// if (i == 0)
+// return px;
+// else
+// return py;
+// }
+//
+// template <class T, class U>
+// T Pair<T, U>::operator [] (const int &i) const
+// {
+// if (i == 0)
+// return px;
+// else
+// return py;
+// }
+
+
+template <class T, class U>
+const Pair<T, U> & Pair<T, U>::operator = (const Pair<T, U> &p)
+{
+ px = p.px;
+ py = p.py;
+ return *this;
+}
+
+template <class T, class U>
+bool Pair<T, U>::operator == (const Pair<T, U> &p) const
+{
+ return (px == p.px) && (py == p.py);
+}
+
+template <class T, class U>
+Pair<T, U> operator + (const Pair<T, U> &p1, const Pair<T, U> &p2)
+{
+ Pair<T, U> result;
+ result.px = p1.px + p2.px;
+ result.py = p1.py + p2.py;
+ return result;
+}
+
+template <class T, class U>
+Pair<T, U> operator + (const T &a, const Pair<T, U> &p)
+{
+ return p + Pair<T, U>(a, a);
+}
+
+template <class T, class U>
+Pair<T, U> operator + (const Pair<T, U> &p, const U &a)
+{
+ return p + Pair<T, U>(a, a);
+}
+
+template <class T, class U>
+Pair<T, U> operator - (const Pair<T, U> &p1, const Pair<T, U> &p2)
+{
+ Pair<T, U> result;
+ result.px = p1.px - p2.px;
+ result.py = p1.py - p2.py;
+ return result;
+}
+
+template <class T, class U>
+Pair<T, U> operator - (const T &a, const Pair<T, U> &p)
+{
+ return Pair<T, U>(a, a) - p ;
+}
+
+template <class T, class U>
+Pair<T, U> operator - (const Pair<T, U> &p, const U &a)
+{
+ return p - Pair<T, U>(a, a);
+}
+
+template <class T, class U>
+Pair<T, U> Pair<T, U>::operator - (void)
+{
+ return Pair<T, U>(-px, -py);
+}
+
+template <class T, class U>
+Pair<T, U> operator * (const Pair<T, U> &p1, const Pair<T, U> &p2)
+{
+ Pair<T, U> result;
+ result.px = p1.px * p2.px;
+ result.py = p1.py * p2.py;
+ return result;
+}
+
+template <class T, class U>
+Pair<T, U> operator * (const T &a, const Pair<T, U> &p)
+{
+ return p * Pair<T, U>(a, a);
+}
+
+template <class T, class U>
+Pair<T, U> operator * (const Pair<T, U> &p, const U &a)
+{
+ return p * Pair<T, U>(a, a);
+}
+
+template <class T, class U>
+Pair<T, U> operator / (const Pair<T, U> &p1, const Pair<T, U> &p2)
+{
+ Pair<T, U> result;
+ result.px = p1.px / p2.px;
+ result.py = p1.py / p2.py;
+ return result;
+}
+
+template <class T, class U>
+Pair<T, U> operator / (const T &a, const Pair<T, U> &p)
+{
+ return Pair<T, U>(a, a) / p;
+}
+
+template <class T, class U>
+Pair<T, U> operator / (const Pair<T, U> &p, const U &a)
+{
+ return p / Pair<T, U>(a, a);
+}
+
+template <class T, class U>
+ostream &operator << (ostream &os, const Pair<T, U> &p)
+{
+ os << "(" << p.px << "," << p.py << ")";
+ return os;
+}
+
+#endif
--- /dev/null
+/*
+ * 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 <class T>
+PrefixTree<T>::PrefixTree()
+:root(new TNode())
+{
+}
+
+template <class T>
+PrefixTree<T>::PrefixTree(const PrefixTree<T> &pt)
+:root(pt.root)
+{
+}
+
+template <class T>
+PrefixTree<T>::~PrefixTree()
+{
+ delete root;
+}
+
+template <class T>
+void PrefixTree<T>::addNode(const String &pref, const T&elt)
+{
+ root->insertInsideNode(pref, elt, 0, 0);
+}
+
+template <class T>
+void PrefixTree<T>::remNode(const T &elt)
+{
+ //TODO
+}
+
+template <class T>
+List<String> PrefixTree<T>::sonsList(const String &pref) const
+{
+ //TODO
+ return List<String>();
+}
+
+template <class T>
+String PrefixTree<T>::completePrefix(const String &pref) const
+{
+ return root->searchInsideNode(pref, 0, 0);
+}
+
+template <class T>
+PrefixTree<T>::TNode::TNode()
+:haskey(false), key(), prefix(""), son(NULL), brotherleft(NULL), brotherright(NULL), father(NULL)
+{
+}
+
+template <class T>
+PrefixTree<T>::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 <class T>
+PrefixTree<T>::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 <class T>
+PrefixTree<T>::TNode::~TNode()
+{
+ delete son;
+ delete brotherright;
+}
+
+template <class T>
+void PrefixTree<T>::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 <class T>
+String PrefixTree<T>::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 <class T>
+bool PrefixTree<T>::searchNode(const String &n)
+{
+ return root->nodeExists(n, 0, 0);
+}
+
+template <class T>
+bool PrefixTree<T>::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 <class T>
+const T &PrefixTree<T>::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 <class T>
+typename PrefixTree<T>::TNode * PrefixTree<T>::getRoot()
+{
+ return root;
+}
+/*
+template <class T>
+inline T &PrefixTree<T>::operator[](const String &key)
+{
+ return root->getNode(n, 0, 0);
+}*/
+
+template <class T>
+inline const T &PrefixTree<T>::operator[](const String &key) const
+{
+ return root->getNode(key, 0, 0);
+}
+
+template <class T>
+ostream &PrefixTree<T>::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 <class T>
+ostream &operator<< (ostream &os, const typename PrefixTree<T>::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 <class T>
+ostream &operator<< (ostream &os, const PrefixTree<T> &n)
+{
+ if (n.root)
+ n.root->display(os);
+ return os;
+}
+
+template <class T>
+typename PrefixTree<T>::TNode *PrefixTree<T>::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 <class T>
+String PrefixTree<T>::TNode::wholePrefix() const
+{
+ if (father)
+ return father->wholePrefix() + prefix;
+ else
+ return prefix;
+}
+
+#endif
--- /dev/null
+/*
+ * 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 <stdlib.h>
+#include <stdio.h>
+#include <cmath>
+#include <cfloat>
+#include <cstring>
+#include <iostream>
+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);
+// {
+//
+// }
--- /dev/null
+/*
+ * 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 <Ogl.h>
+// #include <SDL/SDL.h>
+#ifdef __APPLE__
+#include <SDL_image/SDL_image.h>
+#else
+#include <SDL/SDL_image.h>
+#endif
+// #include <SDL/SDL_opengl.h>
+#include <stdarg.h>
+
+#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<int> Texture::getSize() const
+{
+ return size;
+}
--- /dev/null
+/*
+ * 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 <cmath>
+#include <cstdio>
+#include <sys/types.h>
+#include <dirent.h>
+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<int> rotatePoint(const Vector2D<int> pos, const Vector2D<int> center, const double &angle)
+{
+ return Vector2D<int>(
+ 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;
+}
--- /dev/null
+#include "Track.hpp"
+
+#include "Mixer.hpp"
+
+#include <map>
+
+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<uint32, uint32>::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<uint32,uint32>::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<uint32,Config>::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<uint32,uint32>::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<double>::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<double>::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<uint32,Config>::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<uint32,Config>::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++;
+ }
+}
--- /dev/null
+/*
+ * 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 <iostream>
+using namespace std;
+
+template <class T, class U, class V>
+Triplet<T, U, V>::Triplet(const T &x, const U &y, const V &z)
+:px(x), py(y), pz(z)
+{
+}
+
+template <class T, class U, class V>
+Triplet<T, U, V>::Triplet(const Triplet<T, U, V> &p)
+:px(p.px), py(p.py), pz(p.pz)
+{
+}
+
+template <class T, class U, class V>
+Triplet<T, U, V>::~Triplet()
+{
+}
+
+template <class T, class U, class V>
+const T &Triplet<T, U, V>::getX() const
+{
+ return px;
+}
+
+template <class T, class U, class V>
+const U &Triplet<T, U, V>::getY() const
+{
+ return py;
+}
+
+template <class T, class U, class V>
+const V &Triplet<T, U, V>::getZ() const
+{
+ return pz;
+}
+
+template <class T, class U, class V>
+void Triplet<T, U, V>::setX(const T &x)
+{
+ px = x;
+}
+
+template <class T, class U, class V>
+void Triplet<T, U, V>::setY(const U &y)
+{
+ py = y;
+}
+
+template <class T, class U, class V>
+void Triplet<T, U, V>::setZ(const V &z)
+{
+ pz = z;
+}
+
+///Use an exception ?
+// template <class T, class U, class V>
+// T &Triplet<T, U, V>::operator [] (const int &i)
+// {
+// if (i == 0)
+// return px;
+// else
+// return py;
+// }
+//
+// template <class T, class U, class V>
+// T Triplet<T, U, V>::operator [] (const int &i) const
+// {
+// if (i == 0)
+// return px;
+// else
+// return py;
+// }
+
+
+template <class T, class U, class V>
+const Triplet<T, U, V> & Triplet<T, U, V>::operator = (const Triplet<T, U, V> &p)
+{
+ px = p.px;
+ py = p.py;
+ pz = p.pz;
+ return *this;
+}
+
+template <class T, class U, class V>
+bool Triplet<T, U, V>::operator == (const Triplet<T, U, V> &p) const
+{
+ return (px == p.px) && (py == p.py) && (pz == p.pz);
+}
+
+template <class T, class U, class V>
+Triplet<T, U, V> operator + (const Triplet<T, U, V> &p1, const Triplet<T, U, V> &p2)
+{
+ Triplet<T, U, V> result;
+ result.px = p1.px + p2.px;
+ result.py = p1.py + p2.py;
+ result.pz = p1.pz + p2.pz;
+ return result;
+}
+
+template <class T, class U, class V>
+Triplet<T, U, V> operator + (const T &a, const Triplet<T, U, V> &p)
+{
+ return p + Triplet<T, U, V>(a, a, a);
+}
+
+template <class T, class U, class V>
+Triplet<T, U, V> operator + (const Triplet<T, U, V> &p, const U &a)
+{
+ return p + Triplet<T, U, V>(a, a, a);
+}
+
+template <class T, class U, class V>
+Triplet<T, U, V> operator - (const Triplet<T, U, V> &p1, const Triplet<T, U, V> &p2)
+{
+ Triplet<T, U, V> result;
+ result.px = p1.px - p2.px;
+ result.py = p1.py - p2.py;
+ result.py = p1.pz - p2.pz;
+ return result;
+}
+
+template <class T, class U, class V>
+Triplet<T, U, V> operator - (const T &a, const Triplet<T, U, V> &p)
+{
+ return Triplet<T, U, V>(a, a, a) - p ;
+}
+
+template <class T, class U, class V>
+Triplet<T, U, V> operator - (const Triplet<T, U, V> &p, const U &a)
+{
+ return p - Triplet<T, U, V>(a, a, a);
+}
+
+template <class T, class U, class V>
+Triplet<T, U, V> Triplet<T, U, V>::operator - (void)
+{
+ return Triplet<T, U, V>(-px, -py, -pz);
+}
+
+template <class T, class U, class V>
+Triplet<T, U, V> operator * (const Triplet<T, U, V> &p1, const Triplet<T, U, V> &p2)
+{
+ Triplet<T, U, V> result;
+ result.px = p1.px * p2.px;
+ result.py = p1.py * p2.py;
+ result.pz = p1.pz * p2.pz;
+ return result;
+}
+
+template <class T, class U, class V>
+Triplet<T, U, V> operator * (const T &a, const Triplet<T, U, V> &p)
+{
+ return p * Triplet<T, U, V>(a, a, a);
+}
+
+template <class T, class U, class V>
+Triplet<T, U, V> operator * (const Triplet<T, U, V> &p, const U &a)
+{
+ return p * Triplet<T, U, V>(a, a, a);
+}
+
+template <class T, class U, class V>
+Triplet<T, U, V> operator / (const Triplet<T, U, V> &p1, const Triplet<T, U, V> &p2)
+{
+ Triplet<T, U, V> result;
+ result.px = p1.px / p2.px;
+ result.py = p1.py / p2.py;
+ result.pz = p1.pz / p2.pz;
+ return result;
+}
+
+template <class T, class U, class V>
+Triplet<T, U, V> operator / (const T &a, const Triplet<T, U, V> &p)
+{
+ return Triplet<T, U, V>(a, a, a) / p;
+}
+
+template <class T, class U, class V>
+Triplet<T, U, V> operator / (const Triplet<T, U, V> &p, const U &a)
+{
+ return p / Triplet<T, U, V>(a, a, a);
+}
+
+template <class T, class U, class V>
+ostream &operator << (ostream &os, const Triplet<T, U, V> &p)
+{
+ os << "(" << p.px << "," << p.py << "," << p.pz << ")";
+ return os;
+}
+
+#endif
--- /dev/null
+/*
+ * 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 <iostream>
+using namespace std;
+
+template <class T>
+Vector2D<T>::Vector2D(const T &x, const T &y)
+:Pair<T, T>(x, y)
+{
+}
+
+template <class T>
+Vector2D<T>::Vector2D(const Vector2D<T> &p)
+:Pair<T, T>(p)
+{
+}
+
+template <class T>
+Vector2D<T>::~Vector2D()
+{
+}
+
+/*
+template <class T>
+T Vector2D<T>::getX() const
+{
+ return px;
+}
+
+template <class T>
+T Vector2D<T>::getY() const
+{
+ return py;
+}
+
+template <class T>
+void Vector2D<T>::setX(const T &x)
+{
+ px = x;
+}
+
+template <class T>
+void Vector2D<T>::setY(const T &y)
+{
+ py = y;
+}*/
+
+///Use an exception ?
+template <class T>
+T &Vector2D<T>::operator [] (const int &i)
+{
+ if (i == 0)
+ return this->px;
+ else
+ return this->py;
+}
+
+template <class T>
+const T &Vector2D<T>::operator [] (const int &i) const
+{
+ if (i == 0)
+ return this->px;
+ else
+ return this->py;
+}
+
+/*
+template <class T>
+const Vector2D<T> & Vector2D<T>::operator = (const Vector2D<T> &p)
+{
+ px = p.px;
+ py = p.py;
+ return *this;
+}
+
+template <class T>
+bool Vector2D<T>::operator == (const Vector2D<T> &p) const
+{
+ return (px == p.px) && (py == p.py);
+}*/
+
+template <class T>
+Vector2D<T> operator + (const Vector2D<T> &p1, const Vector2D<T> &p2)
+{
+ Vector2D<T> result;
+ result.px = p1.px + p2.px;
+ result.py = p1.py + p2.py;
+ return result;
+}
+
+template <class T>
+Vector2D<T> operator + (const T &a, const Vector2D<T> &p)
+{
+ return p + Vector2D<T>(a, a);
+}
+
+template <class T>
+Vector2D<T> operator + (const Vector2D<T> &p, const T &a)
+{
+ return p + Vector2D<T>(a, a);
+}
+
+template <class T>
+Vector2D<T> operator - (const Vector2D<T> &p1, const Vector2D<T> &p2)
+{
+ Vector2D<T> result;
+ result.px = p1.px - p2.px;
+ result.py = p1.py - p2.py;
+ return result;
+}
+
+template <class T>
+Vector2D<T> operator - (const T &a, const Vector2D<T> &p)
+{
+ return Vector2D<T>(a, a) - p ;
+}
+
+template <class T>
+Vector2D<T> operator - (const Vector2D<T> &p, const T &a)
+{
+ return p - Vector2D<T>(a, a);
+}
+
+template <class T>
+Vector2D<T> Vector2D<T>::operator - (void)
+{
+ return Vector2D<T>(-this->px, -this->py);
+}
+
+template <class T>
+Vector2D<T> operator * (const Vector2D<T> &p1, const Vector2D<T> &p2)
+{
+ Vector2D<T> result;
+ result.px = p1.px * p2.px;
+ result.py = p1.py * p2.py;
+ return result;
+}
+
+template <class T>
+Vector2D<T> operator * (const T &a, const Vector2D<T> &p)
+{
+ return p * Vector2D<T>(a, a);
+}
+
+template <class T>
+Vector2D<T> operator * (const Vector2D<T> &p, const T &a)
+{
+ return p * Vector2D<T>(a, a);
+}
+
+template <class T>
+Vector2D<T> operator / (const Vector2D<T> &p1, const Vector2D<T> &p2)
+{
+ Vector2D<T> result;
+ result.px = p1.px / p2.px;
+ result.py = p1.py / p2.py;
+ return result;
+}
+
+template <class T>
+Vector2D<T> operator / (const T &a, const Vector2D<T> &p)
+{
+ return Vector2D<T>(a, a) / p;
+}
+
+template <class T>
+Vector2D<T> operator / (const Vector2D<T> &p, const T &a)
+{
+ return p / Vector2D<T>(a, a);
+}
+
+/*template <class T>
+ostream &operator << (ostream &os, const Vector2D<T> &p)
+{
+ os << "(" << p.px << "," << p.py << ")";
+ return os;
+}*/
+
+#endif
--- /dev/null
+/*
+ * 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 <iostream>
+using namespace std;
+
+template <class T>
+Vector3D<T>::Vector3D(const T &x, const T &y, const T &z)
+:Triplet<T, T, T>(x, y, z)
+{
+}
+
+template <class T>
+Vector3D<T>::Vector3D(const Vector3D<T> &p)
+:Triplet<T, T, T>(p)
+{
+}
+
+template <class T>
+Vector3D<T>::~Vector3D()
+{
+}
+
+///Use an exception ?
+template <class T>
+T &Vector3D<T>::operator [] (const int &i)
+{
+ if (i == 0)
+ return this->px;
+ else if (i == 1)
+ return this->py;
+ else
+ return this->pz;
+}
+
+template <class T>
+const T &Vector3D<T>::operator [] (const int &i) const
+{
+ if (i == 0)
+ return this->px;
+ else if (i == 1)
+ return this->py;
+ else
+ return this->pz;
+}
+
+template <class T>
+Vector3D<T> operator + (const Vector3D<T> &p1, const Vector3D<T> &p2)
+{
+ Vector3D<T> result;
+ result.px = p1.px + p2.px;
+ result.py = p1.py + p2.py;
+ result.pz = p1.pz + p2.pz;
+ return result;
+}
+
+template <class T>
+Vector3D<T> operator + (const T &a, const Vector3D<T> &p)
+{
+ return p + Vector3D<T>(a, a, a);
+}
+
+template <class T>
+Vector3D<T> operator + (const Vector3D<T> &p, const T &a)
+{
+ return p + Vector3D<T>(a, a, a);
+}
+
+template <class T>
+Vector3D<T> operator - (const Vector3D<T> &p1, const Vector3D<T> &p2)
+{
+ Vector3D<T> result;
+ result.px = p1.px - p2.px;
+ result.py = p1.py - p2.py;
+ result.pz = p1.pz - p2.pz;
+ return result;
+}
+
+template <class T>
+Vector3D<T> operator - (const T &a, const Vector3D<T> &p)
+{
+ return Vector3D<T>(a, a, a) - p ;
+}
+
+template <class T>
+Vector3D<T> operator - (const Vector3D<T> &p, const T &a)
+{
+ return p - Vector3D<T>(a, a, a);
+}
+
+template <class T>
+Vector3D<T> Vector3D<T>::operator - (void)
+{
+ return Vector3D<T>(-this->px, -this->py, -this->pz);
+}
+
+template <class T>
+Vector3D<T> operator * (const Vector3D<T> &p1, const Vector3D<T> &p2)
+{
+ Vector3D<T> result;
+ result.px = p1.px * p2.px;
+ result.py = p1.py * p2.py;
+ result.pz = p1.pz * p2.pz;
+ return result;
+}
+
+template <class T>
+Vector3D<T> operator * (const T &a, const Vector3D<T> &p)
+{
+ return p * Vector3D<T>(a, a, a);
+}
+
+template <class T>
+Vector3D<T> operator * (const Vector3D<T> &p, const T &a)
+{
+ return p * Vector3D<T>(a, a, a);
+}
+
+template <class T>
+Vector3D<T> operator / (const Vector3D<T> &p1, const Vector3D<T> &p2)
+{
+ Vector3D<T> result;
+ result.px = p1.px / p2.px;
+ result.py = p1.py / p2.py;
+ result.pz = p1.pz / p2.pz;
+ return result;
+}
+
+template <class T>
+Vector3D<T> operator / (const T &a, const Vector3D<T> &p)
+{
+ return Vector3D<T>(a, a, a) / p;
+}
+
+template <class T>
+Vector3D<T> operator / (const Vector3D<T> &p, const T &a)
+{
+ return p / Vector3D<T>(a, a, a);
+}
+
+#endif
--- /dev/null
+#include "Wiimote.hpp"
+
+#include <iostream>
+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)
+{
+}
--- /dev/null
+#include <iostream>
+
+#include "MIDIReader.hpp"
+#include "Track.hpp"
+#include "Texture.hpp"
+#include "Mixer.hpp"
+
+#include <sys/time.h>
+#include <list>
+/*#ifdef __APPLE__
+#include <SDL_mixer/SDL_mixer.h>
+#else
+#include <SDL/SDL_mixer.h>
+#endif*/
+
+#include <GL/glew.h>
+#include <SDL/SDL.h>
+#include <SDL/SDL_mixer.h>
+#include <SDL/SDL_image.h>
+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<double> bips;
+//list<double>::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;
+}