#ifndef NEX_H #define NEX_H #include #include #include #include #include #include #include #include #include "SDL.h" #include "SDL_thread.h" typedef uint32_t Pixel; typedef uint8_t Byte; #define COLOR(r,g,b) ((r<<16) | (g<<8) | (b)) #define COLORSTR(pixel) \ TQString("#%1%2%3").arg(TQString::number((pixel>>16) & 8, 16)) \ .arg(TQString::number((pixel>>8) & 8, 16)).arg(TQString::number(pixel& 8, 16)) #define STRCOLOR(pixel) \ Pixel(((pixel.mid(1,2).toInt(0, 16)) <<16) \ | ((pixel.mid(3,2).toInt(0, 16)) <<8) \ | (pixel.mid(5,2).toInt(0, 16))) const int samples=512+256; const int fhtsamples=512; const int width=320*2; const int height=240*2; #define PI 3.141592654 class Mutex { public: Mutex() { mMutex=::SDL_CreateMutex(); } ~Mutex() { ::SDL_DestroyMutex(mMutex); } inline bool lock() { return !::SDL_mutexP(mMutex); } inline bool unlock() { return !::SDL_mutexV(mMutex); } private: SDL_mutex *mMutex; }; class Thread { public: Thread(); /** * kill() the thread **/ virtual ~Thread(); void start(); void kill(); int wait(); protected: virtual int run()=0; private: static int threadRun(void *); SDL_Thread *mThread; }; class Spacer : public TQWidget { Q_OBJECT public: Spacer(TQWidget *parent) : TQWidget(parent) { setSizePolicy(TQSizePolicy(TQSizePolicy::MinimumExpanding, TQSizePolicy::MinimumExpanding)); } }; class Bitmap { public: Bitmap() : mData(0) { } ~Bitmap() { delete [] mData; } void resize(int w, int h); inline void setPixel(int x, int y, Pixel c) { mData[y*width+x] = c; } inline void drawVerticalLine(int x, int yBottom, int yTop, Pixel c) { int w=width; Pixel *d=mData+x+yTop*w; yBottom-=yTop; do { *d=c; d+=width; } while (yBottom--); } inline void drawHorizontalLine(int left, int right, int y, Pixel c) { Pixel *d=mData+y*width+left; right-=left; do { *(d++)=c; } while (right--); } void drawCircle(int x, int y, int radius, Pixel color); void fillCircle(int x, int y, int radius, Pixel color); void drawLine(int x1, int y1, int x2, int y2, Pixel color); inline int bytes() const { return width*height*sizeof(Pixel); } inline Pixel *pixels(int x, int y) { return &(mData[y*width+x]); } inline Pixel *pixels() const { return mData; } inline Pixel pixel(int x, int y) { return mData[y*width+x]; } inline Pixel *lastPixel() { return pixels(width-1, height-1); } void clear(); private: Pixel *mData; }; /** * maintains a list of bitmaps, so you * can recycle allocated segments * * Thread safe **/ class BitmapPool { public: BitmapPool(); ~BitmapPool(); Bitmap *get(bool clear=false); void release(Bitmap *bitmap); private: struct PoolItem; TQPtrList mBitmaps; Mutex mMutex; }; class StereoScope; struct convolve_state; class Input { public: Input(); ~Input(); /** * audio is a pair of pointers to the buffers, * one for each channel * * get the amount stated in the const global * samples **/ void getAudio(float **audio); void setConvolve(bool state); bool convolve() { return state; } private: void fht(float *p); void transform(float *p, long n, long k); void transform8(float *p); void connect(); private: StereoScope *mScope; float outleft[samples], outright[samples]; float haystack[512]; float temp[samples+256]; convolve_state *state; volatile bool mConvolve; float fhtBuf[samples-256]; float fhtTab[(samples-256)*2]; bool ok; TQObject *notifier; }; class OutputSDL { public: enum Event { None=0, Resize, Exit }; OutputSDL(); ~OutputSDL(); int display(Bitmap *source); private: // static for speed, since there can be only one anyway because SDL sucks static SDL_Surface *surface; }; #include #include class NexCheckBox : public TQCheckBox { Q_OBJECT public: NexCheckBox(TQWidget *parent, const TQString &, bool *v); private slots: void change(bool b); private: bool *value; }; class NexColorButton : public KColorButton { Q_OBJECT public: NexColorButton(TQWidget *parent, Pixel *color); private slots: void change(const TQColor &c); private: Pixel *c; }; class Renderer { public: Renderer(); virtual ~Renderer(); virtual Bitmap *render(float *pcm[4], Bitmap *source) = 0; virtual TQWidget *configure(TQWidget*) { return 0; } virtual void save(TQDomElement &) {} virtual void load(const TQDomElement &) {} }; class TQCheckBox; class TQMultiLineEdit; class RendererList; class RendererListConfigurator : public TQWidget { Q_OBJECT public: RendererListConfigurator(RendererList *l, TQWidget *parent); ~RendererListConfigurator(); public slots: void eraseOn(bool state); void convolve(bool state); private: TQCheckBox *mErase; TQMultiLineEdit *mComments; RendererList *mList; }; class RendererList : public Renderer, public Mutex { friend class RendererListConfigurator; public: RendererList(); virtual ~RendererList(); virtual Bitmap *render(float *pcm[4], Bitmap *source); TQPtrList &renderers() { return mRendererList; } const TQPtrList &renderers() const { return mRendererList; } bool clearAfter() const { return mClearAfter; } void setClearAfter(bool b) { mClearAfter=b; } virtual TQWidget *configure(TQWidget *parent); virtual void save(TQDomElement &e); virtual void load(const TQDomElement &e); private: TQPtrList mRendererList; volatile bool mClearAfter; TQString mComments; Bitmap *mFrame; }; typedef Renderer* (CreatorSig)(); class Nex { public: Nex(); ~Nex(); void go(); void setupSize(int w, int h); static Nex *nex() { return sNex; } BitmapPool *bitmapPool() { return mBitmapPool; } RendererList *rendererList() { return mRendererList; } Input *input() { return mInput; } Renderer *renderer(const TQString &name); TQStringList renderers() const; public: static Nex *sNex; private: Input *mInput; OutputSDL mOutput; BitmapPool *mBitmapPool; RendererList *mRendererList; TQDict mCreators; }; #define nex Nex::nex() #endif