Page MenuHomePhabricator (Chris)

No OneTemporary

Authored By
Unknown
Size
59 KB
Referenced Files
None
Subscribers
None
diff --git a/util/.ebox.cpp.swp b/util/.ebox.cpp.swp
new file mode 100644
index 00000000..a5795e3c
Binary files /dev/null and b/util/.ebox.cpp.swp differ
diff --git a/util/.token.cpp.swp b/util/.token.cpp.swp
new file mode 100644
index 00000000..9424dae6
Binary files /dev/null and b/util/.token.cpp.swp differ
diff --git a/util/bitmap.cpp b/util/bitmap.cpp
new file mode 100644
index 00000000..080e2483
--- /dev/null
+++ b/util/bitmap.cpp
@@ -0,0 +1,725 @@
+#include <allegro.h>
+#include "bitmap.h"
+#include "font.h"
+#include <stdarg.h>
+#include <vector>
+#include <string>
+#include <iostream>
+// #include <fblend.h>
+
+#ifdef WINDOWS
+#include <winalleg.h>
+#endif
+
+using namespace std;
+
+#ifndef debug
+#define debug cout<<"File: "<<__FILE__<<" Line: "<<__LINE__<<endl;
+#endif
+
+const int Bitmap::MaskColor = MASK_COLOR_16;
+
+const int Bitmap::MODE_TRANS = 0;
+const int Bitmap::MODE_SOLID = 1;
+
+Bitmap * Bitmap::Screen;
+
+Bitmap::Bitmap():
+error( false ){
+ setBitmap( create_bitmap( 10, 10 ) );
+ if ( ! getBitmap() ){
+ error = true;
+ cerr << "Could not create bitmap!" << endl;
+ } else {
+ clear();
+ own = new int;
+ *own = 1;
+ }
+}
+
+Bitmap::Bitmap( int x, int y ):
+error( false ){
+ if ( x < 1 ){
+ x = 1;
+ }
+ if ( y < 1 ){
+ y = 1;
+ }
+ setBitmap( create_bitmap( x, y ) );
+ if ( ! getBitmap() ){
+ error = true;
+ cerr << "Could not create bitmap!" << endl;
+ } else {
+ clear();
+ own = new int;
+ *own = 1;
+ }
+}
+
+/* If a BITMAP is given to us, we didnt make it so we dont own it */
+Bitmap::Bitmap( BITMAP * who, bool deep_copy ):
+error( false ){
+
+ if ( deep_copy ){
+ BITMAP * his = who;
+ setBitmap( create_bitmap( his->w, his->h ) );
+ ::blit( his, getBitmap(), 0, 0, 0, 0, his->w, his->h );
+ own = new int;
+ *own = 1;
+ } else {
+ setBitmap( who );
+ own = NULL;
+ }
+}
+
+Bitmap::Bitmap( const char * load_file ):
+error( false ){
+ internalLoadFile( load_file );
+ /*
+ my_bitmap = load_bitmap( load_file, NULL );
+ if ( !my_bitmap ){
+ my_bitmap = create_bitmap( 100, 100 );
+ clear( my_bitmap );
+ cout<<"Could not load "<<load_file<<endl;
+ error = true;
+ }
+ own = true;
+ */
+}
+
+Bitmap::Bitmap( const string & load_file ):
+error( false ){
+ internalLoadFile( load_file.c_str() );
+}
+
+Bitmap::Bitmap( const char * load_file, int sx, int sy ):
+error( false ){
+ path = load_file;
+ BITMAP * temp = load_bitmap( load_file, NULL );
+ // my_bitmap = load_bitmap( load_file, NULL );
+ setBitmap( create_bitmap( sx, sy ) );
+ // clear( my_bitmap );
+ clear();
+ if ( !temp ){
+ cout<<"Could not load "<<load_file<<endl;
+ error = true;
+ } else {
+ stretch_blit( temp, getBitmap(), 0, 0, temp->w, temp->h, 0, 0, getBitmap()->w, getBitmap()->h );
+ destroy_bitmap( temp );
+ }
+ // own = true;
+ own = new int;
+ *own = 1;
+}
+
+Bitmap::Bitmap( const char * load_file, int sx, int sy, double accuracy ):
+error( false ){
+ path = load_file;
+ BITMAP * temp = load_bitmap( load_file, NULL );
+ own = new int;
+ *own = 1;
+ if ( !temp ){
+ cout<<"Could not load "<<load_file<<endl;
+ setBitmap( create_bitmap( sx, sy ) );
+ // clear( my_bitmap );
+ clear();
+ error = true;
+ } else {
+ if ( temp->w > sx || temp->h > sy ){
+ double bx = temp->w / sx;
+ double by = temp->h / sy;
+ double use;
+ use = bx > by ? bx : by;
+ int fx = (int)(sx / use);
+ int fy = (int)(sy / use);
+ setBitmap( create_bitmap( fx, fy ) );
+
+ stretch_blit( temp, getBitmap(), 0, 0, temp->w, temp->h, 0, 0, getBitmap()->w, getBitmap()->h );
+
+ destroy_bitmap( temp );
+ } else setBitmap( temp );
+ }
+ // own = true;
+}
+
+Bitmap::Bitmap( const Bitmap & copy, int sx, int sy ):
+error( false ){
+ path = copy.getPath();
+ BITMAP * temp = copy.getBitmap();
+ setBitmap( create_bitmap( sx, sy ) );
+ // clear( my_bitmap );
+ clear();
+ stretch_blit( temp, getBitmap(), 0, 0, temp->w, temp->h, 0, 0, getBitmap()->w, getBitmap()->h );
+ // own = true;
+ // own = copy.own;
+ own = new int;
+ *own = 1;
+}
+
+Bitmap::Bitmap( const Bitmap & copy, int sx, int sy, double accuracy ):
+error( false ){
+ path = copy.getPath();
+ BITMAP * temp = copy.getBitmap();
+ own = new int;
+ *own = 1;
+ if ( temp->w > sx || temp->h > sy ){
+ double bx = (double)temp->w / (double)sx;
+ double by = (double)temp->h / (double)sy;
+ double use;
+ use = bx > by ? bx : by;
+ int fx = (int)(temp->w / use);
+ int fy = (int)(temp->h / use);
+ setBitmap( create_bitmap( fx, fy ) );
+ if ( ! getBitmap() ){
+ allegro_message("Could not create bitmap\n");
+ // own = false;
+ // own = copy.own;
+ // *own++;
+ error = true;
+ return;
+ }
+
+ stretch_blit( temp, getBitmap(), 0, 0, temp->w, temp->h, 0, 0, getBitmap()->w, getBitmap()->h );
+ // destroy_bitmap( temp );
+ } else {
+ setBitmap( create_bitmap( temp->w, temp->h ) );
+ blit( temp, getBitmap(), 0, 0, 0, 0, temp->w, temp->h );
+ // own = new int
+ // own = true;
+ }
+}
+
+Bitmap::Bitmap( const Bitmap & copy, bool deep_copy ):
+error( false ){
+
+ path = copy.getPath();
+ if ( deep_copy ){
+ BITMAP * his = copy.getBitmap();
+ setBitmap( create_bitmap( his->w, his->h ) );
+ ::blit( his, getBitmap(), 0, 0, 0, 0, his->w, his->h );
+ own = new int;
+ *own = 1;
+ } else {
+ setBitmap( copy.getBitmap() );
+ // own = false;
+ own = copy.own;
+ if ( own ){
+ *own = *own + 1;
+ }
+ }
+ /*
+ BITMAP * his = copy.getBitmap();
+ my_bitmap = create_bitmap( his->w, his->h );
+ ::blit( his, my_bitmap, 0, 0, 0, 0, his->w, his->h );
+ own = true;
+ */
+}
+
+Bitmap::Bitmap( const Bitmap & copy, int x, int y, int width, int height ):
+error( false ){
+ path = copy.getPath();
+ BITMAP * his = copy.getBitmap();
+ if ( x < 0 )
+ x = 0;
+ if ( y < 0 )
+ y = 0;
+ if ( width > his->w )
+ width = his->w;
+ if ( height > his->h )
+ height = his->h;
+ setBitmap( create_sub_bitmap( his, x, y, width, height ) );
+
+ if ( ! getBitmap() ){
+ cout<<"Could not create sub-bitmap"<<endl;
+ setBitmap( create_bitmap( 10, 10 ) );
+ // clear( my_bitmap );
+ clear();
+ }
+ // own = true;
+ own = new int;
+ *own = 1;
+}
+
+void Bitmap::internalLoadFile( const char * load_file ){
+ path = load_file;
+ setBitmap( load_bitmap( load_file, NULL ) );
+ if ( ! getBitmap() ){
+ cout<<"Could not load "<<load_file<<". Using default"<<endl;
+ setBitmap( create_bitmap( 100, 100 ) );
+ if ( ! getBitmap() ){
+ cout<<"Out of memory or Allegro not initialized"<<endl;
+ error = true;
+ return;
+ }
+ // clear( my_bitmap );
+ clear();
+ // cout<<"Could not load "<<load_file<<endl;
+ error = true;
+ }
+ // own = true;
+ own = new int;
+ *own = 1;
+}
+
+void Bitmap::save( const string & str ){
+ save_bitmap( str.c_str(), getBitmap(), NULL );
+}
+
+/* decrement bitmap reference counter and free memory if counter hits 0 */
+void Bitmap::releaseInternalBitmap(){
+ if ( own ){
+ (*own)--;
+ if ( *own == 0 ){
+ delete own;
+ destroy_bitmap( getBitmap() );
+ own = NULL;
+ }
+ }
+}
+
+const int Bitmap::getWidth() const{
+ return getBitmap()->w;
+}
+
+const int Bitmap::getHeight() const{
+ return getBitmap()->h;
+}
+
+int Bitmap::getRed( int x ){
+ return ::getr( x );
+}
+
+int Bitmap::getBlue( int x ){
+ return ::getg( x );
+}
+
+int Bitmap::getGreen( int x ){
+ return ::getb( x );
+}
+
+/* resize the internal bitmap. not guaranteed to destroy the internal bitmap */
+void Bitmap::resize( const int width, const int height ){
+
+ /* if internal bitmap is already the proper size, do nothing */
+ if ( getWidth() == width && getHeight() == height ){
+ return;
+ }
+
+ releaseInternalBitmap();
+
+ own = new int;
+ setBitmap( create_bitmap( width, height ) );
+ *own = 1;
+}
+
+/*
+const string & Bitmap::getPath() const{
+ return path;
+}
+*/
+
+void Bitmap::debugSelf() const{
+ cout<<"Bitmap: "<<endl;
+ cout<<"Self = "<< getBitmap() <<endl;
+ cout<<"Own = "<< own <<" : "<< *own <<endl;
+ cout<<"Path = "<<path<<endl;
+}
+
+Bitmap & Bitmap::operator=( const Bitmap & copy ){
+
+ /*
+ if ( own ){
+ (*own)--;
+ if ( *own == 0 ){
+ destroy_bitmap( getBitmap() );
+ delete own;
+ }
+ }
+ */
+
+ releaseInternalBitmap();
+
+ path = copy.getPath();
+ setBitmap( copy.getBitmap() );
+ // own = false;
+ own = copy.own;
+ if ( own )
+ *own++;
+
+ return *this;
+}
+
+Bitmap::~Bitmap(){
+ /*
+ if ( own ){
+ (*own)--;
+
+ if ( *own == 0 ){
+ destroy_bitmap( getBitmap() );
+ delete own;
+ } else {
+ // cout<<"Not destroying bitmap "<<this<<endl;
+ }
+ }
+ */
+ releaseInternalBitmap();
+}
+
+void Bitmap::detach(){
+
+ /*
+ if ( own ){
+ (*own)--;
+
+ if ( *own == 0 ){
+ destroy_bitmap( getBitmap() );
+ delete own;
+ }
+ }
+ */
+ releaseInternalBitmap();
+}
+
+/*
+BITMAP * Bitmap::getBitmap() const{
+ return my_bitmap;
+}
+*/
+
+bool Bitmap::getError(){
+ return error;
+}
+
+/*
+int Bitmap::getWidth(){
+ return my_bitmap->w;
+}
+
+int Bitmap::getHeight(){
+ return my_bitmap->h;
+}
+*/
+
+void Bitmap::acquire(){
+ acquire_bitmap( getBitmap() );
+}
+
+void Bitmap::release(){
+ release_bitmap( getBitmap() );
+}
+
+void Bitmap::circleFill( int x, int y, int radius, int color ) const{
+ ::circlefill( getBitmap(), x, y, radius, color );
+}
+
+void Bitmap::circle( int x, int y, int radius, int color ) const{
+ ::circle( getBitmap(), x, y, radius, color );
+}
+
+void Bitmap::line( const int x1, const int y1, const int x2, const int y2, const int color ) const{
+
+ ::line( getBitmap(), x1, y1, x2, y2, color );
+
+}
+
+void Bitmap::transBlender( int r, int g, int b, int a ){
+ set_trans_blender( r, g, b, a );
+}
+
+void Bitmap::multiplyBlender( int r, int g, int b, int a ){
+ set_multiply_blender( r, g, b, a );
+}
+
+void Bitmap::drawingMode( int mode ){
+ // drawing_mode( DRAW_MODE_TRANS, NULL, 0, 0 );
+ switch( mode ){
+ case MODE_TRANS : {
+ drawing_mode( DRAW_MODE_TRANS, NULL, 0, 0 );
+ break;
+ }
+ case MODE_SOLID : {
+ drawing_mode( DRAW_MODE_SOLID, NULL, 0, 0 );
+ break;
+ }
+ }
+}
+
+/*
+const int Bitmap::getWidth() const{
+ return getBitmap()->w;
+}
+
+const int Bitmap::getHeight() const{
+ return getBitmap()->h;
+}
+*/
+
+const int Bitmap::getPixel( const int x, const int y ) const{
+ if ( x >= 0 && x < getBitmap()->w && y >= 0 && y < getBitmap()->h )
+ return _getpixel16( getBitmap(), x, y );
+ return -1;
+}
+
+void Bitmap::readLine( vector< int > & vec, int y ){
+ if ( y >= 0 && y < getBitmap()->h ){
+ for ( int q = 0; q < getBitmap()->w; q++ ){
+ // int col = my_bitmap->line[ y ][ q ];
+ int col = _getpixel16( getBitmap(), q, y );
+ vec.push_back( col );
+ }
+ }
+}
+
+int Bitmap::setGfxModeText(){
+ return ::set_gfx_mode( GFX_TEXT, 0, 0, 0, 0 );
+}
+
+int Bitmap::setGfxModeFullscreen( int x, int y ){
+ return ::set_gfx_mode( GFX_AUTODETECT_FULLSCREEN, x, y, 0, 0 );
+}
+
+int Bitmap::setGfxModeWindowed( int x, int y ){
+ return ::set_gfx_mode( GFX_AUTODETECT_WINDOWED, x, y, 0, 0 );
+}
+
+int Bitmap::makeColor( int r, int g, int b ){
+ return ::makecol16( r, g, b );
+}
+
+void Bitmap::hsvToRGB( float h, float s, float v, int * r, int * g, int * b ){
+ ::hsv_to_rgb( h, s, v, r, g, b );
+}
+
+int Bitmap::addColor( int color1, int color2 ){
+ return makeColor( getr( color1 ) + getr( color2 ),
+ getg( color1 ) + getg( color2 ),
+ getb( color1 ) + getb( color2 ) );
+}
+
+void Bitmap::putPixel( int x, int y, int col ) const{
+ if ( x >= 0 && x < getBitmap()->w && y >= 0 && y < getBitmap()->h )
+ _putpixel16( getBitmap(), x, y, col );
+}
+
+void Bitmap::printf( int x, int y, int color, FONT * f, const char * str, ... ) const{
+
+ char buf[512];
+ va_list ap;
+
+ va_start(ap, str);
+ uvszprintf(buf, sizeof(buf), str, ap);
+ va_end(ap);
+
+ textout_ex( getBitmap(), f, buf, x, y, color, -1);
+}
+
+void Bitmap::printf( int x, int y, int color, Font * f, const char * str, ... ) const{
+
+ char buf[512];
+ va_list ap;
+
+ va_start(ap, str);
+ uvszprintf(buf, sizeof(buf), str, ap);
+ va_end(ap);
+
+ textout_ex( getBitmap(), f->getInternalFont(), buf, x, y, color, -1);
+}
+
+void Bitmap::printf( int x, int y, int color, Font * f, const string & str ) const{
+ printf( x, y, color, f, str.c_str() );
+}
+
+void Bitmap::printfNormal( int x, int y, int color, const char * str, ... ) const{
+
+ char buf[512];
+ va_list ap;
+
+ va_start(ap, str);
+ uvszprintf(buf, sizeof(buf), str, ap);
+ va_end(ap);
+
+ textout_ex( getBitmap(), font, buf, x, y, color, -1);
+
+}
+
+void Bitmap::printfNormal( int x, int y, int color, const string & str ) const{
+ printfNormal( x, y, color, "%s", str.c_str() );
+}
+
+void Bitmap::triangle( int x1, int y1, int x2, int y2, int x3, int y3, int color ) const{
+ ::triangle( getBitmap(), x1, y1, x2, y2, x3, y3, color );
+}
+
+void Bitmap::ellipse( int x, int y, int rx, int ry, int color ) const {
+ ::ellipse( getBitmap(), x, y, rx, ry, color );
+}
+
+void Bitmap::ellipseFill( int x, int y, int rx, int ry, int color ) const {
+ ::ellipsefill( getBitmap(), x, y, rx, ry, color );
+}
+
+void Bitmap::rectangle( int x1, int y1, int x2, int y2, int color ) const{
+ ::rect( getBitmap(), x1, y1, x2, y2, color );
+}
+
+void Bitmap::rectangleFill( int x1, int y1, int x2, int y2, int color ) const{
+ ::rectfill( getBitmap(), x1, y1, x2, y2, color );
+}
+
+/*
+int Bitmap::getPixel( int x, int y ){
+ if ( x >= 0 && x < my_bitmap->w && y >= 0 && y <= my_bitmap->h )
+ return _getpixel16( my_bitmap, x, y );
+ return -1;
+}
+*/
+
+/*
+int Bitmap::makeColor( int r, int g, int b ){
+ return makecol16( r, g, b );
+}
+*/
+
+void Bitmap::hLine( const int x1, const int y, const int x2, const int color ) const{
+ ::hline( getBitmap(), x1, y, x2, color );
+}
+
+void Bitmap::horizontalLine( const int x1, const int y, const int x2, const int color ) const{
+ this->hLine( x1, y, x2, color );
+}
+
+void Bitmap::vLine( const int y1, const int x, const int y2, const int color ) const{
+ ::vline( getBitmap(), x, y1, y2, color );
+}
+
+void Bitmap::polygon( const int * verts, const int nverts, const int color ) const{
+ ::polygon( getBitmap(), nverts, verts, color );
+}
+
+/*
+void Bitmap::clear(){
+ this->fill( 0 );
+}
+*/
+
+void Bitmap::fill( int color ) const{
+ ::clear_to_color( getBitmap(), color );
+}
+
+void Bitmap::draw( const int x, const int y, const Bitmap & where ) const{
+ ::draw_sprite( where.getBitmap(), getBitmap(), x, y );
+}
+
+void Bitmap::drawHFlip( const int x, const int y, const Bitmap & where ){
+ ::draw_sprite_h_flip( where.getBitmap(), getBitmap(), x, y );
+}
+
+void Bitmap::drawLit( const int x, const int y, const int level, const Bitmap & where ) const{
+ ::draw_lit_sprite( where.getBitmap(), getBitmap(), x, y, level );
+}
+
+void Bitmap::drawTrans( const int x, const int y, const Bitmap & where ) const{
+ ::draw_trans_sprite( where.getBitmap(), getBitmap(), x, y );
+}
+
+void Bitmap::drawRotate( const int x, const int y, const int angle, const Bitmap & where ){
+ ::fixed fang = itofix( (360 - angle) % 360 * 256 / 360 );
+ ::rotate_sprite( where.getBitmap(), getBitmap(), x, y, fang );
+}
+
+void Bitmap::drawStretched( const int x, const int y, const int new_width, const int new_height, const Bitmap & who ){
+ BITMAP * bmp = who.getBitmap();
+ ::masked_stretch_blit( getBitmap(), bmp, 0, 0, getBitmap()->w, getBitmap()->h, x,y, new_height, new_width );
+}
+
+void Bitmap::drawMask( const int _x, const int _y, const Bitmap & where ){
+ int mask = Bitmap::MaskColor;
+ for ( int x = 0; x < getWidth(); x++ ){
+ for ( int y = 0; y < getHeight(); y++ ){
+ if ( getPixel( x,y ) == mask ){
+ where.putPixel( x+_x, y+_y, mask );
+ }
+ }
+ }
+}
+
+void Bitmap::StretchBy2( const Bitmap & where ){
+ BITMAP * bmp = where.getBitmap();
+
+ if ( where.getWidth() == getWidth() && where.getHeight() == getHeight() ){
+ ::blit( getBitmap(), bmp, 0, 0, 0, 0, getBitmap()->w, getBitmap()->h );
+ return;
+ }
+
+ if ( where.getWidth() != getWidth()*2 ||
+ where.getHeight() != getHeight()*2 ){
+ cout<<"Wrong dimensions"<<endl;
+ cout<<"My: "<< getWidth() << " " << getHeight() << endl;
+ cout<<"Him: "<<where.getWidth()<< " " << where.getHeight()<<endl;
+ return;
+ }
+ // debug
+ ::stretch_blit( getBitmap(), bmp, 0, 0, getBitmap()->w, getBitmap()->h, 0, 0, bmp->w, bmp->h );
+ // fblend_2x_stretch( my_bitmap, bmp, 0, 0, 0, 0, my_bitmap->w, my_bitmap->h);
+ // scale2x_allegro( my_bitmap, bmp, 2 );
+ // debug
+
+}
+
+void Bitmap::StretchBy4( const Bitmap & where ){
+
+ BITMAP * bmp = where.getBitmap();
+ if ( where.getWidth() != getWidth()*4 ||
+ where.getHeight() != getHeight()*4 ){
+ cout<<"Wrong dimensions"<<endl;
+ cout<<"My: "<< getWidth() << " " << getHeight() << endl;
+ cout<<"Him: "<<where.getWidth()<< " " << where.getHeight()<<endl;
+ cout<<"Scaled: "<<getWidth()*4<<" "<< getHeight()*4<<endl;
+ return;
+ }
+ // fblend_2x_stretch( my_bitmap, bmp, 0, 0, 0, 0, my_bitmap->w, my_bitmap->h);
+ // scale4x_allegro( my_bitmap, bmp, 2 );
+ ::stretch_blit( getBitmap(), bmp, 0, 0, getBitmap()->w, getBitmap()->h, 0, 0, bmp->w, bmp->h );
+
+}
+
+void Bitmap::Stretch( const Bitmap & where ){
+ BITMAP * bmp = where.getBitmap();
+ ::stretch_blit( getBitmap(), bmp, 0, 0, getBitmap()->w, getBitmap()->h, 0, 0, bmp->w, bmp->h );
+}
+
+void Bitmap::Blit( const string & xpath ){
+ Bitmap duh( xpath );
+ duh.Blit( *this );
+}
+
+void Bitmap::Blit( const int x, const int y, const Bitmap & where ){
+ BITMAP * bmp = where.getBitmap();
+ /*
+ acquire_bitmap( bmp );
+ acquire_bitmap( my_bitmap );
+ */
+ ::blit( getBitmap(), bmp, 0, 0, x, y, getBitmap()->w, getBitmap()->h );
+ /*
+ release_bitmap( my_bitmap );
+ release_bitmap( bmp );
+ */
+}
+
+void Bitmap::Blit( const int mx, const int my, const int wx, const int wy, const Bitmap & where ){
+ BITMAP * bmp = where.getBitmap();
+ ::blit( getBitmap(), bmp, mx, my, wx, wy, getBitmap()->w, getBitmap()->h );
+}
+
+void Bitmap::Blit( const int mx, const int my, const int width, const int height, const int wx, const int wy, Bitmap & where ){
+ BITMAP * bmp = where.getBitmap();
+ ::blit( getBitmap(), bmp, mx, my, wx, wy, width, height );
+}
+
+void Bitmap::Blit( const Bitmap & where ){
+ this->Blit( 0, 0, where );
+}
+
+void Bitmap::BlitToScreen(){
+ this->Blit( *Bitmap::Screen );
+}
diff --git a/util/bitmap.h b/util/bitmap.h
new file mode 100644
index 00000000..51f9ac26
--- /dev/null
+++ b/util/bitmap.h
@@ -0,0 +1,199 @@
+#ifndef _bitmap_h_
+#define _bitmap_h_
+
+#include <string>
+#include <vector>
+
+#include <iostream>
+
+/*
+#ifdef WINDOWS
+#include <winalleg.h>
+#endif
+*/
+
+struct BITMAP;
+struct FONT;
+class Font;
+
+using namespace std;
+
+class Bitmap{
+public:
+
+ static Bitmap * Screen;
+
+ /* default constructor makes 10x10 bitmap */
+ Bitmap();
+ Bitmap( int x, int y );
+ Bitmap( const char * load_file );
+ Bitmap( const string & load_file );
+ Bitmap( const char * load_file, int sx, int sy );
+ Bitmap( const char * load_file, int sx, int sy, double accuracy );
+ Bitmap( BITMAP * who, bool deep_copy = false );
+ Bitmap( const Bitmap & copy, bool deep_copy = false );
+ Bitmap( const Bitmap & copy, int sx, int sy );
+ Bitmap( const Bitmap & copy, int sx, int sy, double accuracy );
+ Bitmap( const Bitmap & copy, int x, int y, int width, int height );
+ virtual ~Bitmap();
+
+ virtual void save( const string & str );
+
+ Bitmap & operator=( const Bitmap & );
+
+ const int getWidth() const;
+ const int getHeight() const;
+
+ /*
+ inline const int getWidth() const{
+ return getBitmap()->w;
+ }
+
+ inline const int getHeight() const{
+ return getBitmap()->h;
+ }
+ */
+
+ /*
+ inline const int getWidth() const{
+ return my_bitmap->w;
+ }
+
+ inline const int getHeight() const{
+ return my_bitmap->h;
+ }
+ */
+
+ void detach();
+
+ static void transBlender( int r, int g, int b, int a );
+ static void multiplyBlender( int r, int g, int b, int a );
+
+ static void drawingMode( int type );
+
+ void acquire();
+ void release();
+
+ void resize( const int width, const int height );
+
+ void debugSelf() const;
+
+ void printf( int x, int y, int color, FONT * f, const char * str, ... ) const;
+ void printf( int x, int y, int color, Font * f, const char * str, ... ) const;
+ void printf( int x, int y, int color, Font * f, const string & str ) const;
+ void printfNormal( int x, int y, int color, const char * str, ... ) const;
+ void printfNormal( int x, int y, int color, const string & str ) const;
+ void triangle( int x1, int y1, int x2, int y2, int x3, int y3, int color ) const;
+ void ellipse( int x, int y, int rx, int ry, int color ) const;
+ void ellipseFill( int x, int y, int rx, int ry, int color ) const;
+
+ void rectangle( int x1, int y1, int x2, int y2, int color ) const;
+ void rectangleFill( int x1, int y1, int x2, int y2, int color ) const;
+ void circleFill( int x, int y, int radius, int color ) const;
+ void circle( int x, int y, int radius, int color ) const;
+ void line( const int x1, const int y1, const int x2, const int y2, const int color ) const;
+
+ void horizontalLine( const int x1, const int y, const int x2, const int color ) const;
+ void hLine( const int x1, const int y, const int x2, const int color ) const;
+ void vLine( const int y1, const int x, const int y2, const int color ) const;
+ void polygon( const int * verts, const int nverts, const int color ) const;
+
+ void draw( const int x, const int y, const Bitmap & where ) const;
+ void drawLit( const int x, const int y, const int level, const Bitmap & where ) const;
+ void drawHFlip( const int x, const int y, const Bitmap & where );
+ void drawTrans( const int x, const int y, const Bitmap & where ) const;
+ void drawMask( const int x, const int y, const Bitmap & where );
+ void drawStretched( const int x, const int y, const int new_width, const int new_height, const Bitmap & who );
+ void drawRotate( const int x, const int y, const int angle, const Bitmap & where );
+
+ void Stretch( const Bitmap & where );
+ void StretchBy2( const Bitmap & where );
+ void StretchBy4( const Bitmap & where );
+ void Blit( const string & xpath );
+ void Blit( const Bitmap & where );
+ void Blit( const int x, const int y, const Bitmap & where );
+ void Blit( const int mx, const int my, const int wx, const int wy, const Bitmap & where );
+ void Blit( const int mx, const int my, const int width, const int height, const int wx, const int wy, Bitmap & where );
+ void BlitToScreen();
+ void fill( int color ) const;
+
+ inline void clear() const{
+ this->fill( 0 );
+ }
+
+ bool getError();
+
+ inline BITMAP * getBitmap() const{
+ return _my_bitmap;
+ }
+
+ void readLine( vector< int > & vec, int y );
+ const int getPixel( const int x, const int y ) const;
+
+ void putPixel( int x, int y, int col ) const;
+
+ /*
+ inline int getPixel( int x, int y ) const{
+ if ( x >= 0 && x < my_bitmap->w && y >= 0 && y <= my_bitmap->h )
+ return _getpixel16( my_bitmap, x, y );
+ return -1;
+ }
+
+ inline void putPixel( int x, int y, int col ) const{
+ if ( x >= 0 && x < my_bitmap->w && y >= 0 && y <= my_bitmap->h )
+ _putpixel16( my_bitmap, x, y, col );
+ }
+ */
+
+ inline const string & getPath() const{
+ return path;
+ }
+
+ static int setGfxModeText();
+ static int setGfxModeFullscreen( int x, int y );
+ static int setGfxModeWindowed( int x, int y );
+
+ static int makeColor( int r, int g, int b );
+ static void hsvToRGB( float h, float s, float v, int * r, int * g, int * b );
+
+ static int getRed( int x );
+ static int getBlue( int x );
+ static int getGreen( int x );
+
+ /* Add two colors together
+ */
+ static int addColor( int color1, int color2 );
+
+ /*
+ inline static int makeColor( int r, int g, int b ){
+ return makecol16( r, g, b );
+ }
+ */
+
+ // static const int MaskColor = MASK_COLOR_16;
+ static const int MaskColor;
+ static const int MODE_TRANS;
+ static const int MODE_SOLID;
+
+protected:
+
+ void releaseInternalBitmap();
+
+ inline void setBitmap( BITMAP * bitmap ){
+ if ( bitmap == NULL ){
+ cout << "*FATAL* Setting null bitmap" << endl;
+ }
+ _my_bitmap = bitmap;
+ }
+
+ void internalLoadFile( const char * load_file );
+
+ BITMAP * _my_bitmap;
+ int * own;
+ // bool own;
+ bool error;
+ string path;
+
+};
+
+#endif
diff --git a/util/ebox.cpp b/util/ebox.cpp
new file mode 100644
index 00000000..a03f292f
--- /dev/null
+++ b/util/ebox.cpp
@@ -0,0 +1,579 @@
+/* ebox version 2:
+ * by Jon Rafkind
+ */
+
+#include "ebox.h"
+#include <stdio.h>
+#include "bitmap.h"
+#include <iostream>
+#include "timedifference.h"
+
+// using namespace Ebox2;
+
+#ifndef debug
+// #define debug printf("File: %s Line: %d\n", __FILE__, __LINE__ );
+#define debug std::cout<<"File: "<<__FILE__<<" Line: "<<__LINE__<<std::endl;
+#endif
+
+// #define MIN_SIZE 8
+const int MIN_SIZE = 8;
+
+EQuad::EQuad( EQuad * const head ):
+width( head->width ),
+height( head->height ),
+full( head->full ),
+min_x( head->min_x ),
+min_y( head->min_y ),
+parent( NULL ),
+num_quads( head->num_quads ){
+
+ for ( int q = 0; q < 4; q++ )
+ quads[q] = NULL;
+
+ for ( int i = 0; i < head->numQuads(); i++ ){
+ // EQuad * tmp = head->getQuad( i );
+ quads[i] = new EQuad( head->getQuad( i ) );
+ quads[i]->parent = this;
+ }
+
+}
+
+EQuad::EQuad( int w, int h, EQuad * _parent ):
+width( w ),
+height( h ),
+min_x( 0 ),
+min_y( 0 ),
+parent( _parent ),
+num_quads( 0 ){
+ full = true;
+ for ( int i = 0; i < 4; i++ )
+ quads[i] = NULL;
+}
+
+EQuad::EQuad( const Bitmap * who, int min_size, int mask_pixel, int _min_x, int _min_y, EQuad * _parent ):
+width( who->getWidth() ),
+height( who->getHeight() ),
+full( false ),
+min_x( _min_x ),
+min_y( _min_y ),
+parent( _parent ){
+
+ Bitmap * b1, * b2, * b3, * b4;
+ EQuad * quad1, * quad2, * quad3, * quad4;
+ quad1 = quad2 = quad3 = quad4 = NULL;
+
+ if ( width > min_size && height > min_size ){
+
+
+ int w = who->getWidth() >> 1;
+ int h = who->getHeight() >> 1;
+
+ // b1 = create_sub_Bitmap( who, 0, 0, w, h );
+ b1 = new Bitmap( *who, 0, 0, w, h );
+ quad1 = new EQuad( b1, min_size, mask_pixel, 0, 0, this );
+ // destroy_Bitmap( b1 );
+ delete b1;
+
+ // b2 = create_sub_Bitmap( who, w, 0, w, h );
+ b2 = new Bitmap( *who, w, 0, w, h );
+ quad2 = new EQuad( b2, min_size, mask_pixel, w, 0, this );
+ delete b2;
+ // destroy_Bitmap( b2 );
+
+
+ // b3 = create_sub_Bitmap( who, 0, h, w, h );
+ b3 = new Bitmap( *who, 0, h, w, h );
+ quad3 = new EQuad( b3, min_size, mask_pixel, 0, h, this );
+ delete b3;
+ // destroy_Bitmap( b3 );
+
+ // b4 = create_sub_Bitmap( who, w, h, w, h );
+ b4 = new Bitmap( *who, w, h, w, h );
+ quad4 = new EQuad( b4, min_size, mask_pixel, w, h, this );
+ delete b4;
+ // destroy_Bitmap( b4 );
+
+ if ( quad1->empty() ){
+ delete quad1;
+ quad1 = NULL;
+ }
+ if ( quad2->empty() ){
+ delete quad2;
+ quad2 = NULL;
+ }
+ if ( quad3->empty() ){
+ delete quad3;
+ quad3 = NULL;
+ }
+ if ( quad4->empty() ){
+ delete quad4;
+ quad4 = NULL;
+ }
+
+ if ( quad1 && quad2 && quad3 && quad4 )
+ if ( quad1->full && quad2->full && quad3->full && quad4->full ){
+ delete quad1;
+ delete quad2;
+ delete quad3;
+ delete quad4;
+ quad1 = NULL;
+ quad2 = NULL;
+ quad3 = NULL;
+ quad4 = NULL;
+ full = true;
+ }
+
+ checkQuad( quad1 );
+ checkQuad( quad2 );
+ checkQuad( quad3 );
+ checkQuad( quad4 );
+
+ } else {
+ // printf("Size X:%d Y:%d\n", width, height );
+ int total = 0;
+ for ( int x = 0; x < who->getWidth(); x++ )
+ for ( int y = 0; y < who->getHeight(); y++ ){
+ // int pixel = _getpixel16( who, x, y );
+ int pixel = who->getPixel( x, y );
+ if ( pixel != mask_pixel )
+ ++total;
+ }
+
+ if ( total*100/(who->getWidth()*who->getHeight()) > 50 ){
+ full = true;
+ }
+
+ }
+
+ for ( int i = 0; i < 4; i++ )
+ quads[i] = NULL;
+
+ int i = 0;
+ if ( quad1 ) quads[i++] = quad1;
+ if ( quad2 ) quads[i++] = quad2;
+ if ( quad3 ) quads[i++] = quad3;
+ if ( quad4 ) quads[i++] = quad4;
+
+ num_quads = numQuads();
+
+}
+
+bool EQuad::addQuad( EQuad * who ){
+ int n = numQuads();
+ if ( n < 4 ){
+ quads[n] = who;
+ full = false;
+ return true;
+ } else return false;
+}
+
+void EQuad::checkQuad( EQuad *& q ){
+ if ( q != NULL ){
+ while ( q->numQuads() == 1 ){
+ EQuad * const newquad = q->getQuad();
+ q->detach( newquad );
+ int x = q->getMinX();
+ int y = q->getMinY();
+ delete q;
+ q = newquad;
+ newquad->setMinX( newquad->getMinX() + x );
+ newquad->setMinY( newquad->getMinY() + y );
+ q->parent = this;
+ }
+ }
+}
+
+int EQuad::totalQuads(){
+ if ( full ) return 1;
+ int total = 0;
+ for ( int i = 0; i < numQuads(); i++ )
+ if ( quads[i] )
+ total += quads[i]->totalQuads();
+ /*
+ if ( quad1 ) total += quad1->totalQuads();
+ if ( quad2 ) total += quad2->totalQuads();
+ if ( quad3 ) total += quad3->totalQuads();
+ if ( quad4 ) total += quad4->totalQuads();
+ */
+
+ return total;
+}
+
+void EQuad::setMinX( int x ){
+ min_x = x;
+}
+
+void EQuad::setMinY( int y ){
+ min_y = y;
+}
+
+/*
+int EQuad::numQuads() const{
+ int total = 0;
+ / *
+ if ( quad1 ) ++total;
+ if ( quad2 ) ++total;
+ if ( quad3 ) ++total;
+ if ( quad4 ) ++total;
+ * /
+ for ( total = 0; total < 4 && quads[total] != NULL; total++ );
+
+ return total;
+}
+*/
+
+EQuad * const EQuad::getQuad() const{
+ return quads[0];
+ /*
+ if ( quad1 ) return quad1;
+ if ( quad2 ) return quad2;
+ if ( quad3 ) return quad3;
+ if ( quad4 ) return quad4;
+ return NULL;
+ */
+}
+
+EQuad * const EQuad::getQuad( int x ) const{
+ return quads[x];
+}
+
+void EQuad::detach( EQuad * const who ){
+
+ // printf("Detach %p\n", who );
+ /*
+ if ( who == quad1 ) quad1 = NULL;
+ if ( who == quad2 ) quad2 = NULL;
+ if ( who == quad3 ) quad3 = NULL;
+ if ( who == quad4 ) quad4 = NULL;
+ */
+ for ( int i = 0; i < numQuads(); i++ )
+ if ( who == quads[i] )
+ quads[i] = NULL;
+
+ EQuad * tmp[ 4 ];
+ int begin = 0;
+ for ( int i = 0; i < 4; i++ )
+ if ( quads[i] ){
+ tmp[begin++] = quads[i];
+ quads[i] = NULL;
+ }
+
+ for ( int q = 0; q < begin; q++ )
+ quads[q] = tmp[q];
+
+}
+
+int EQuad::calcSize(){
+ int total = sizeof(*this);
+ for ( int q = 0; q < numQuads(); q++ ){
+ total += quads[q]->calcSize();
+ }
+ return total;
+}
+
+bool EQuad::empty(){
+
+ if ( numQuads() == 0 ) return !full;
+ // if ( !quad1 && !quad2 && !quad3 && !quad4 ) return !full;
+ return false;
+
+}
+
+void EQuad::draw( const Bitmap & work, int x, int y, int color, bool flipped ){
+
+ int mx = x + getMinX();
+ int my = y + getMinY();
+ // std::cout<<"getMinX: "<<getMinX()<<std::endl;
+ if ( flipped ){
+ if ( parent ){
+ mx = x + parent->getWidth() - (getMinX()+getWidth());
+ // mx = getMinX() - parent->getWidth()/2 + x;
+ // my = y + parent->getHeight()/2 - getMinY();
+ // my = y + getMinY();
+
+ // mx2 = mx - getWidth();
+ // mx2 = mx + getWidth();
+
+ /*
+ int i;
+ i = mx;
+ mx = mx2;
+ mx2 = i;
+ */
+ }
+ }
+
+ int mx2 = mx + getWidth();
+ int my2 = my + getHeight();
+
+ for ( int i = 0; i < numQuads(); i++ )
+ quads[i]->draw( work, mx, my, color, flipped );
+
+ if ( full )
+ work.rectangle( mx, my, mx2, my2, color );
+ /*
+ if ( full )
+ work->rectangle( x+getMinX(), y+getMinY(), x+getMinX()+getWidth(), y+getMinY()+getHeight(), Bitmap::makeColor(255,64,32) );
+ else
+ work->rectangle( x+getMinX(), y+getMinY(), x+getMinX()+getWidth(), y+getMinY()+getHeight(), color );
+ */
+}
+
+void EQuad::draw( const Bitmap & work, int x, int y, int color, EQuad * who ){
+
+ bool cy = false;
+ for ( int i = 0; i < numQuads(); i++ )
+ if ( who == quads[i] )
+ cy = true;
+
+ int mx = x + getMinX();
+ int my = y + getMinY();
+ if ( cy )
+ who->draw( work, mx, my, color );
+ else {
+ for ( int i = 0; i < numQuads(); i++ )
+ quads[i]->draw( work, mx, my, color, who );
+ }
+
+}
+
+bool boxCollide( int zx1, int zy1, int zx2, int zy2, int zx3, int zy3, int zx4, int zy4 ){
+
+ if ( zx1 < zx3 && zx1 < zx4 &&
+ zx2 < zx3 && zx2 < zx4 ) return false;
+ if ( zx1 > zx3 && zx1 > zx4 &&
+ zx2 > zx3 && zx2 > zx4 ) return false;
+ if ( zy1 < zy3 && zy1 < zy4 &&
+ zy2 < zy3 && zy2 < zy4 ) return false;
+ if ( zy1 > zy3 && zy1 > zy4 &&
+ zy2 > zy3 && zy2 > zy4 ) return false;
+
+ return true;
+
+}
+
+bool EQuad::collide( int mx, int my, int x1, int y1, int x2, int y2, EQuad ** last, bool xflipped, bool yflipped ){
+
+ int rx = mx + getMinX();
+ int ry = my + getMinY();
+
+ if ( parent ){
+ if ( xflipped ){
+ rx = mx + parent->getWidth() - (getMinX()+getWidth());
+ }
+ if ( yflipped ){
+ ry = my + parent->getHeight() - (getMinY()+getHeight());
+ }
+ }
+ int rx2 = rx + getWidth();
+ int ry2 = ry + getHeight();
+
+ // rect( screen, rx, ry, rx2, ry2, makecol(255,255,0) );
+
+ bool cy = boxCollide( rx, ry, rx2, ry2, x1, y1, x2, y2 );
+ if ( !cy ) return false;
+
+ for ( int i = 0; i < numQuads(); i++ )
+ if ( quads[i]->collide( rx, ry, x1, y1, x2, y2, last ) )
+ return true;
+
+ if ( !full ) return false;
+ if ( cy ) *last = this;
+ return cy;
+
+ return false;
+
+}
+
+EQuad::~EQuad(){
+ /*
+ if ( quad1 ) delete quad1;
+ if ( quad2 ) delete quad2;
+ if ( quad3 ) delete quad3;
+ if ( quad4 ) delete quad4;
+ */
+
+ for ( int q = 0; q < 4; q++ )
+ if ( quads[q] != NULL )
+ delete quads[q];
+}
+
+long long ECollide::totalTime = 0;
+void ECollide::initECollide( const Bitmap * who, int mask_pixel ){
+ /*
+ TimeDifference dif;
+ dif.startTime();
+ */
+ head_quad = new EQuad( who, MIN_SIZE, mask_pixel, 0, 0, NULL );
+ last_collide = NULL;
+
+ /*
+ dif.endTime();
+ totalTime += dif.getTime();
+ cout<<"Total time taken: "<< totalTime / 1000 <<" ms" <<endl;
+ */
+}
+
+ECollide::ECollide( const Bitmap * who, int mask_pixel ){
+ initECollide( who, mask_pixel );
+ /*
+ head_quad = new EQuad( who, MIN_SIZE, mask_pixel, 0, 0, NULL );
+ last_collide = NULL;
+ */
+
+}
+
+ECollide::ECollide( const Bitmap & who, int mask_pixel ){
+
+ initECollide( &who, mask_pixel );
+
+ /*
+ head_quad = new EQuad( &who, MIN_SIZE, mask_pixel, 0, 0, NULL );
+ last_collide = NULL;
+ */
+
+}
+
+ECollide::ECollide( BITMAP * who, int mask_pixel ){
+
+ Bitmap tmp( who );
+ initECollide( &tmp, mask_pixel );
+
+ /*
+ head_quad = new EQuad( &tmp, MIN_SIZE, mask_pixel, 0, 0, NULL );
+ last_collide = NULL;
+ */
+}
+
+ECollide::ECollide( int width, int height ){
+
+ last_collide = NULL;
+ head_quad = new EQuad( width, height, NULL );
+
+}
+
+ECollide::ECollide( const ECollide * e ){
+
+ initQuad( e->head_quad );
+ /*
+ last_collide = NULL;
+ head_quad = new EQuad( e->head_quad );
+ */
+}
+
+ECollide::ECollide( const ECollide & e ){
+ initQuad( e.head_quad );
+ /*
+ last_collide = NULL;
+ head_quad = new EQuad( e.head_quad );
+ */
+}
+
+ECollide::ECollide( EQuad * const head ){
+ initQuad( head );
+ /*
+ last_collide = NULL;
+ head_quad = new EQuad( head );
+ */
+}
+
+void ECollide::initQuad( EQuad * const head ){
+ last_collide = NULL;
+ head_quad = new EQuad( head );
+}
+
+ECollide * ECollide::copy(){
+ return new ECollide( head_quad );
+}
+
+int ECollide::getMinHeight(){
+ return head_quad->getMinY();
+}
+
+int ECollide::getMaxHeight(){
+ return head_quad->getMinY() + head_quad->getHeight();
+}
+
+int ECollide::getMinWidth(){
+ return head_quad->getMinX();
+}
+
+int ECollide::getMaxWidth(){
+ return head_quad->getMinX() + head_quad->getWidth();
+}
+
+int ECollide::calcSize(){
+ int total = sizeof(*this);
+ if ( head_quad )
+ total += head_quad->calcSize();
+ return total;
+}
+
+bool ECollide::collide( int mx, int my, int x1, int y1, int x2, int y2, bool xflipped, bool yflipped ){
+
+ last_collide = NULL;
+
+ return head_quad->collide(mx,my,x1,y1,x2,y2,&last_collide, xflipped, yflipped );
+
+}
+
+bool ECollide::Collision( int mx, int my, int ax, int ay, bool xflipped, bool ylfipped ){
+
+ return collide( mx, my, ax, ay, ax, ay );
+
+}
+
+bool ECollide::Collision( int mx, int my, int x1, int y1, int x2, int y2, bool xflipped, bool yflipped ){
+
+ return collide( mx, my, x1, y1, x2, y2 );
+
+}
+
+bool ECollide::Collision( ECollide * col, int mx, int my, int ax, int ay, bool my_xflipped, bool my_yflipped, bool him_xflipped, bool him_yflipped ){
+ if ( !col ) return false;
+
+ int x1 = mx > ax ? mx : ax;
+ int y1 = my > ay ? my : ay;
+ int x2 = (mx+getWidth()) < (ax+col->getWidth()) ? (mx+getWidth()) : (ax+col->getWidth());
+ int y2 = (my+getHeight()) < (ay+col->getHeight()) ? (my+getHeight()) : (ay+col->getHeight());
+
+ if ( x1 > x2 ) return false;
+ if ( y1 > y2 ) return false;
+
+ return ( collide(mx,my,x1,y1,x2,y2,my_xflipped,my_yflipped) && col->collide(ax,ay,x1,y1,x2,y2,him_xflipped,him_yflipped) );
+
+}
+
+/*
+int ECollide::getWidth() const{
+ return head_quad->getWidth();
+}
+
+int ECollide::getHeight() const{
+ return head_quad->getHeight();
+}
+*/
+
+void ECollide::draw( const Bitmap & work, int x, int y, bool flipped ){
+
+ head_quad->draw( work, x, y, Bitmap::makeColor(255,255,255), flipped );
+
+}
+
+int ECollide::numQuads() const{
+ return head_quad->totalQuads();
+}
+
+void ECollide::draw( const Bitmap & work, int x, int y, int color, EQuad * who ){
+ if ( head_quad == who )
+ head_quad->draw( work, x, y, color );
+ else head_quad->draw( work, x, y, color, who );
+}
+
+EQuad * ECollide::getLast(){
+ return last_collide;
+}
+
+ECollide::~ECollide(){
+ delete head_quad;
+}
diff --git a/util/ebox.h b/util/ebox.h
new file mode 100644
index 00000000..8ecfec1e
--- /dev/null
+++ b/util/ebox.h
@@ -0,0 +1,162 @@
+/* ebox version 2:
+ * by Jon Rafkind
+ */
+
+#ifndef _ebox_2_h
+#define _ebox_2_h
+
+#include "bitmap.h"
+
+class EQuad{
+public:
+
+ EQuad( EQuad * const head );
+ EQuad( int w, int h, EQuad * _parent );
+ EQuad( const Bitmap * who, int min_size, int mask_pixel, int min_x, int min_y, EQuad * _parent );
+
+ void draw( const Bitmap & work, int x, int y, int color, bool flipped = false );
+ void draw( const Bitmap & work, int x, int y, int color, EQuad * who );
+
+ inline int getWidth() const{
+ return width;
+ }
+
+ inline int getHeight() const{
+ return height;
+ }
+
+ inline void setFull( bool x ){
+ full = x;
+ }
+
+ EQuad * const getQuad( int x ) const;
+
+ bool addQuad( EQuad * who );
+
+ inline int getPosX() const {
+ if ( parent )
+ return min_x + parent->getPosX();
+ return min_x;
+ }
+
+ inline int getPosY() const {
+ if ( parent )
+ return min_y + parent->getPosY();
+ return min_y;
+ }
+
+ // bool collide( int mx, int my, int x1, int y1, int x2, int y2, EQuad ** last );
+ bool collide( int mx, int my, int x1, int y1, int x2, int y2, EQuad ** last, bool xflipped = false, bool yflipped = false );
+ // int collide( int mx, int my, int x1, int y1, int x2, int y2, EQuad ** last, int depth );
+
+ int calcSize();
+
+ void setMinX( int x );
+ void setMinY( int y );
+
+ inline int getMinX() const{
+ return min_x;
+ }
+
+ inline int getMinY() const{
+ return min_y;
+ }
+
+ int totalQuads();
+
+ ~EQuad();
+
+protected:
+
+ EQuad * const getQuad() const;
+ void detach( EQuad * const who );
+ void checkQuad( EQuad *& q );
+
+ inline int numQuads() const{
+ int total = 0;
+ if ( quads[0] != NULL ) total++;
+ if ( quads[1] != NULL ) total++;
+ if ( quads[2] != NULL ) total++;
+ if ( quads[3] != NULL ) total++;
+ // for ( int total = 0; total < 4 && quads[total] != NULL; total++ );
+ return total;
+ }
+
+ bool empty();
+ // bool boxCollide( int zx1, int zy1, int zx2, int zy2, int zx3, int zy3, int zx4, int zy4 );
+
+protected:
+
+ int width, height;
+ // EQuad * quad1, * quad2, * quad3, * quad4;
+
+ bool full;
+
+ int min_x, min_y;
+ EQuad * quads[ 4 ];
+ EQuad * parent;
+ int num_quads;
+
+};
+
+class ECollide{
+public:
+ ECollide( EQuad * const head );
+ ECollide( BITMAP * who, int mask_pixel = Bitmap::MaskColor );
+ ECollide( const Bitmap * who, int mask_pixel = Bitmap::MaskColor );
+ ECollide( const Bitmap & who, int mask_pixel = Bitmap::MaskColor );
+ ECollide( const ECollide & e );
+ ECollide( const ECollide * e );
+ ECollide( int width, int height );
+
+ void draw( const Bitmap & work, int x, int y, bool flipped = false );
+ void draw( const Bitmap & work, int x, int y, int color, EQuad * who );
+
+ bool Collision( ECollide * col, int mx, int my, int ax, int ay, bool my_xflipped = false, bool my_yflipped = false, bool him_xflipped = false, bool him_flipped = false );
+ bool Collision( int mx, int my, int ax, int ay, bool xflipped = false, bool yflipped = false );
+ bool Collision( int mx, int my, int x1, int y1, int x2, int y2, bool xflipped = false, bool yflipped = false );
+
+ int getMinHeight();
+ int getMaxHeight();
+ int getMinWidth();
+ int getMaxWidth();
+
+ ECollide * copy();
+
+ EQuad * getLast();
+
+ EQuad * getHead() const{
+ return head_quad;
+ }
+
+ int calcSize();
+
+ inline int getWidth() const{
+ return head_quad->getWidth();
+ }
+
+ inline int getHeight() const{
+ return head_quad->getHeight();
+ }
+
+ int numQuads() const;
+
+ ~ECollide();
+
+private:
+ void initECollide( const Bitmap * who, int mask_pixel );
+ void initQuad( EQuad * const head );
+
+ static long long totalTime;
+
+protected:
+
+ bool collide( int mx, int my, int x1, int y1, int x2, int y2, bool xflipped = false, bool yflipped = false );
+ // bool collide( int mx, int my, int x1, int y1 );
+
+ EQuad * head_quad;
+ EQuad * last_collide;
+
+};
+
+#endif
diff --git a/util/font.cpp b/util/font.cpp
new file mode 100644
index 00000000..264afe6e
--- /dev/null
+++ b/util/font.cpp
@@ -0,0 +1,18 @@
+#include <allegro.h>
+#include "font.h"
+
+Font::Font( FONT * f ):
+my_font( f ){
+}
+
+Font::Font( const Font & f ):
+my_font( f.getInternalFont() ){
+}
+
+const int Font::textLength( const char * text ){
+ return text_length( getInternalFont(), text );
+}
+
+const int Font::getHeight() const{
+ return text_height( getInternalFont() );
+}
diff --git a/util/font.h b/util/font.h
new file mode 100644
index 00000000..a33fa6c3
--- /dev/null
+++ b/util/font.h
@@ -0,0 +1,23 @@
+#ifndef _paintown_font_h
+#define _paintown_font_h
+
+struct FONT;
+
+class Font{
+public:
+ Font( FONT * f );
+ Font( const Font & f );
+
+ inline FONT * getInternalFont() const{
+ return my_font;
+ }
+
+ const int textLength( const char * text );
+
+ const int getHeight() const;
+
+protected:
+ FONT * my_font;
+};
+
+#endif
diff --git a/util/funcs.cpp b/util/funcs.cpp
new file mode 100644
index 00000000..cb469e4c
--- /dev/null
+++ b/util/funcs.cpp
@@ -0,0 +1,40 @@
+#include "funcs.h"
+#include <allegro.h>
+
+/*
+inline int rnd( int q ){
+ if ( q <= 0 ) return 0;
+ return (int)( rand() % q );
+}
+*/
+
+int rnd( int q, int min, int range ){
+ return q - min + rnd( range );
+}
+
+int rnd( int min, int max ){
+ return rnd( max - min ) + min;
+}
+
+void blend_palette( int * pal, int mp, int sc, int ec ) {
+
+ ASSERT( pal );
+ ASSERT( mp != 0 );
+
+ int sc_r = getr( sc );
+ int sc_g = getg( sc );
+ int sc_b = getb( sc );
+
+ int ec_r = getr( ec );
+ int ec_g = getg( ec );
+ int ec_b = getb( ec );
+
+ for ( int q = 0; q < mp; q++ ) {
+ float j = (float)( q ) / (float)( mp );
+ int f_r = (int)( 0.5 + (float)( sc_r ) + (float)( ec_r-sc_r ) * j );
+ int f_g = (int)( 0.5 + (float)( sc_g ) + (float)( ec_g-sc_g ) * j );
+ int f_b = (int)( 0.5 + (float)( sc_b ) + (float)( ec_b-sc_b ) * j );
+ pal[q] = makecol( f_r, f_g, f_b );
+ }
+
+}
diff --git a/util/funcs.h b/util/funcs.h
new file mode 100644
index 00000000..f095a318
--- /dev/null
+++ b/util/funcs.h
@@ -0,0 +1,20 @@
+#ifndef _funcs_h
+#define _funcs_h
+
+#include <stdlib.h>
+
+// int rnd( int q );
+inline int rnd( int q ){
+ if ( q <= 0 ) return 0;
+ return (int)( rand() % q );
+}
+
+/* return a random number + some range between min/max */
+int rnd( int q, int min, int max );
+
+/* return a number between min/max */
+int rnd( int min, int max );
+
+void blend_palette( int * pal, int mp, int sc, int ec );
+
+#endif
diff --git a/util/keyboard.cpp b/util/keyboard.cpp
new file mode 100644
index 00000000..f253984d
--- /dev/null
+++ b/util/keyboard.cpp
@@ -0,0 +1,51 @@
+#include "keyboard.h"
+#include "allegro.h"
+#include <iostream>
+#include <vector>
+#include <map>
+
+using namespace std;
+
+#ifndef debug
+#define debug cout<<"File: "<<__FILE__<<" Line: "<<__LINE__<<endl;
+#endif
+
+const int Keyboard::Key_A = KEY_A;
+const int Keyboard::Key_S = KEY_S;
+const int Keyboard::Key_D = KEY_D;
+
+const int Keyboard::Key_LEFT = KEY_LEFT;
+const int Keyboard::Key_RIGHT = KEY_RIGHT;
+const int Keyboard::Key_UP = KEY_UP;
+const int Keyboard::Key_DOWN = KEY_DOWN;
+const int Keyboard::Key_SPACE = KEY_SPACE;
+
+Keyboard::Keyboard(){
+}
+
+/* KEY_MAX is defined in allegro at
+ * allegro/include/allegro/keyboard.h
+ */
+void Keyboard::poll(){
+
+ for ( int q = 0; q < KEY_MAX; q++ ){
+ my_keys[ q ] = key[ q ];
+ }
+
+}
+
+void Keyboard::readKeys( vector< int > & all_keys ) const{
+ for ( map<int,bool>::const_iterator it = my_keys.begin(); it != my_keys.end(); it++ ){
+ if ( (*it).second ){
+ all_keys.push_back( (*it).first );
+ }
+ }
+}
+
+bool Keyboard::keypressed() const{
+ for ( map<int,bool>::const_iterator it = my_keys.begin(); it != my_keys.end(); it++ ){
+ const bool & n = (*it).second;
+ if ( n ) return true;
+ }
+ return false;
+}
diff --git a/util/keyboard.h b/util/keyboard.h
new file mode 100644
index 00000000..a13d7906
--- /dev/null
+++ b/util/keyboard.h
@@ -0,0 +1,55 @@
+#ifndef _keyboard_h
+#define _keyboard_h
+
+#include <map>
+#include <vector>
+
+using namespace std;
+
+/* handles allegro key[] array better than keypressed()
+ * and readkey()
+ */
+class Keyboard{
+public:
+
+ Keyboard();
+
+ /* poll:
+ * Put the keys in Allegro's key[] array into our map of int -> bool
+ */
+ void poll();
+
+ /* []:
+ * Extract a boolean value given a key number
+ */
+ inline const bool operator[] ( const int i ){
+ return my_keys[ i ];
+ }
+
+ /* keypressed:
+ * Returns true if a key is pressed
+ */
+ bool keypressed() const;
+
+ /* readKeys:
+ * Store all pressed keys in a user supplied vector
+ */
+ void readKeys( vector< int > & all_keys ) const;
+
+ static const int Key_A;
+ static const int Key_S;
+ static const int Key_D;
+
+ static const int Key_LEFT;
+ static const int Key_RIGHT;
+ static const int Key_UP;
+ static const int Key_DOWN;
+ static const int Key_SPACE;
+
+protected:
+
+ map<int,bool> my_keys;
+
+};
+
+#endif
diff --git a/util/load_exception.cpp b/util/load_exception.cpp
new file mode 100644
index 00000000..2d358633
--- /dev/null
+++ b/util/load_exception.cpp
@@ -0,0 +1,14 @@
+#include <string>
+#include "load_exception.h"
+
+LoadException::LoadException():
+exception(){
+}
+
+LoadException::LoadException( const string & reason ):
+exception(){
+ this->reason = reason;
+}
+
+LoadException::~LoadException() throw(){
+}
diff --git a/util/load_exception.h b/util/load_exception.h
new file mode 100644
index 00000000..1cb2158b
--- /dev/null
+++ b/util/load_exception.h
@@ -0,0 +1,28 @@
+#ifndef _load_exception_h
+#define _load_exception_h
+
+/* Generic load exception class. Thrown whenever a structure is being created
+ * and an error occurs.
+ */
+
+#include <exception>
+#include <string>
+
+using namespace std;
+
+class LoadException: public exception{
+public:
+ LoadException();
+ LoadException( const string & reason );
+
+ inline const string & getReason() const {
+ return reason;
+ }
+
+ ~LoadException() throw();
+
+protected:
+ string reason;
+};
+
+#endif
diff --git a/util/sound.cpp b/util/sound.cpp
new file mode 100644
index 00000000..c8cfb0a7
--- /dev/null
+++ b/util/sound.cpp
@@ -0,0 +1,50 @@
+#include <allegro.h>
+#include <string>
+
+#include "sound.h"
+#include "load_exception.h"
+
+using namespace std;
+
+Sound::Sound( const string & path ) throw( LoadException ):
+my_sound( NULL ),
+own( NULL ){
+
+ my_sound = load_sample( path.c_str() );
+
+ if ( !my_sound ){
+ string xf( "Could not load " );
+ xf += path;
+ throw LoadException( xf );
+ }
+
+ own = new int;
+ *own = 1;
+
+}
+
+Sound::Sound( const Sound & copy ):
+my_sound( NULL ),
+own( NULL ){
+ own = copy.own;
+ if ( own ){
+ *own += 1;
+ }
+ my_sound = copy.my_sound;
+}
+
+void Sound::play(){
+ if ( my_sound )
+ play_sample( my_sound, 255, 128, 1000, false );
+}
+
+Sound::~Sound(){
+ if ( own ){
+ *own -= 1;
+
+ if ( *own == 0 ){
+ delete own;
+ destroy_sample( my_sound );
+ }
+ }
+}
diff --git a/util/sound.h b/util/sound.h
new file mode 100644
index 00000000..b488fd5d
--- /dev/null
+++ b/util/sound.h
@@ -0,0 +1,28 @@
+#ifndef _pain_sound_h
+#define _pain_sound_h
+
+#include <string>
+#include "load_exception.h"
+
+struct SAMPLE;
+
+using namespace std;
+
+/* a sound! */
+class Sound{
+public:
+ Sound( const string & path ) throw( LoadException );
+ Sound( const Sound & copy );
+
+ void play();
+
+ virtual ~Sound();
+
+protected:
+
+ SAMPLE * my_sound;
+ int * own;
+
+};
+
+#endif
diff --git a/util/timedifference.cpp b/util/timedifference.cpp
new file mode 100644
index 00000000..50e7ba34
--- /dev/null
+++ b/util/timedifference.cpp
@@ -0,0 +1,35 @@
+#include "timedifference.h"
+#include <iostream>
+#include <string>
+using namespace std;
+
+TimeDifference::TimeDifference(){
+ start.tv_usec = 0;
+ start.tv_sec = 0;
+ end.tv_usec = 0;
+ end.tv_sec = 0;
+}
+
+void TimeDifference::printTime(){
+
+ this->printTime("Function");
+
+}
+
+unsigned long long int TimeDifference::getTime(){
+ unsigned long long int g = (end.tv_sec*1000000+end.tv_usec) - (start.tv_sec*1000000 + start.tv_usec );
+ return g;
+}
+
+void TimeDifference::printTime( const string & s ){
+
+ unsigned long long int micro = (end.tv_sec*1000000+end.tv_usec) - (start.tv_sec*1000000 + start.tv_usec );
+ unsigned long long int milli = micro / 1000;
+ unsigned long long int sec = milli / 1000;
+
+ cout<<s<<" took "<<micro<<" microseconds / "<< milli << " milliseconds / " <<sec<< " seconds "<< endl;
+
+}
+
+TimeDifference::~TimeDifference(){
+}
diff --git a/util/timedifference.h b/util/timedifference.h
new file mode 100644
index 00000000..410872c4
--- /dev/null
+++ b/util/timedifference.h
@@ -0,0 +1,39 @@
+#ifndef _time_difference_h
+#define _time_difference_h
+
+#include <time.h>
+#include <sys/time.h>
+#include <string>
+
+using namespace std;
+
+class TimeDifference{
+public:
+
+ TimeDifference();
+
+ inline void startTime(){
+ #ifndef WINDOWS
+ gettimeofday( &start, NULL );
+ #endif
+ }
+
+ inline void endTime(){
+ #ifndef WINDOWS
+ gettimeofday( &end, NULL );
+ #endif
+ }
+
+ unsigned long long int getTime();
+
+ void printTime();
+ void printTime( const string & s );
+
+ ~TimeDifference();
+
+protected:
+ struct timeval start, end;
+
+};
+
+#endif
diff --git a/util/token.cpp b/util/token.cpp
new file mode 100644
index 00000000..884478b2
--- /dev/null
+++ b/util/token.cpp
@@ -0,0 +1,169 @@
+#include "token.h"
+#include "token_exception.h"
+#include <string>
+#include <vector>
+#include <sstream>
+#include <iostream>
+#include <sstream>
+
+using namespace std;
+
+Token::Token(){
+ name = "HEAD";
+ num_token = 1;
+}
+
+Token::Token( string tok, bool parse ):
+num_token( 1 ){
+
+ /* legacy code, not used much */
+ if ( !parse ){
+ name = tok;
+ while ( name.find(' ' ) == 0 )
+ name.erase( 0, 1 );
+ lowerCase( name );
+ return;
+ }
+
+}
+
+/* Dump token to the screen */
+void Token::print( const string & space ){
+ cout<<space<<"Token: "<< getName() << endl;
+ for ( signed int i = 0; i < numTokens(); i++ ){
+ Token * x = getToken( i );
+ x->print( space + " |--" );
+ }
+
+}
+
+/* helper function */
+void Token::lowerCase( string & s ){
+ for ( unsigned int q = 0; q < s.length(); q++ ){
+ if ( s[q] >= 'A' && s[q] <= 'Z' )
+ s[q] = s[q] - 'A' + 'a';
+ }
+}
+
+/* Return next token and increment the internal position
+ * of the current token
+ */
+Token * Token::readToken(){
+ if ( num_token < tokens.size() ){
+ return tokens[ num_token++ ];
+ }
+ return NULL;
+}
+
+bool Token::hasTokens(){
+ return num_token < tokens.size();
+}
+
+Token * Token::getToken( unsigned int n ){
+ int q = numTokens();
+ if ( q == -1 ) return NULL;
+ if ( n >= 0 && (signed int)n < q )
+ return tokens[n+1];
+ return NULL;
+}
+
+/* If the token has children then the name of this token
+ * is the name of the first child token.
+ * Otherwise, the name is this token's name
+ */
+const string & Token::getName(){
+ if ( numTokens() != -1 ){
+ return tokens[0]->_getName();
+ }
+ // cout<<"No tokens!!"<<endl;
+ return name;
+}
+
+/* A token's identity is its name
+ */
+bool Token::operator== ( const string & rhs ){
+ return getName() == rhs;
+}
+
+bool Token::operator!= ( const string & rhs ){
+ return !( *this == rhs );
+}
+
+/* extracting operators */
+Token & Token::operator>>( Token * & rhs ) throw( TokenException ){
+ Token * x = readToken();
+ if ( x == NULL ){
+ throw TokenException("No more elements");
+ }
+ rhs = x;
+ return *this;
+}
+
+Token & Token::operator>>( string & rhs ) throw( TokenException ){
+ Token * l = readToken();
+ if ( l == NULL ){
+ throw TokenException("No more elements");
+ }
+ rhs = l->getName();
+
+ // rhs = getName();
+
+ return *this;
+}
+
+Token & Token::operator>>( int & rhs ) throw( TokenException ){
+ Token * l = readToken();
+ if ( l == NULL ){
+ throw TokenException("No more elements");
+ }
+ istringstream is ( l->getName() );
+ is >> rhs;
+ return *this;
+}
+
+Token & Token::operator>>( double & rhs ) throw( TokenException ){
+ Token * l = readToken();
+ if ( l == NULL ){
+ throw TokenException("No more elements");
+ }
+ istringstream is ( l->getName() );
+ is >> rhs;
+ return *this;
+}
+
+Token & Token::operator>>( bool & rhs ) throw( TokenException ){
+ Token * l = readToken();
+ if ( l == NULL ){
+ throw TokenException("No more elements");
+ }
+ istringstream is ( l->getName() );
+ is >> rhs;
+ return *this;
+}
+
+void Token::addToken( Token * t ){
+ tokens.push_back( t );
+}
+
+/* Delete tokens that are commented.
+ * A commented token has a '!' character as the first
+ * character in the name, e.g:
+ * (!a_token (child_token 2))
+ */
+void Token::finalize(){
+ for ( vector< Token * >::iterator it = tokens.begin(); it != tokens.end(); ){
+ Token * t = *it;
+ if ( t->getName().find('!') == 0 ){
+ delete t;
+ it = tokens.erase( it );
+ } else {
+ t->finalize();
+ it++;
+ }
+ }
+}
+
+Token::~Token(){
+ for ( vector< Token * >::iterator it = tokens.begin(); it != tokens.end(); it++ )
+ delete *it;
+}
diff --git a/util/token.h b/util/token.h
new file mode 100644
index 00000000..bba081e6
--- /dev/null
+++ b/util/token.h
@@ -0,0 +1,76 @@
+#ifndef _token_h
+#define _token_h
+
+#include <string>
+#include <vector>
+#include "token_exception.h"
+
+class TokenReader;
+
+using namespace std;
+
+/* Token:
+ * Basically a tree where each node stores a value in a string
+ * and can have 0 or more children
+ */
+class Token{
+public:
+
+ void addToken( Token * t );
+
+ /*
+ inline const string & getName(){
+ return name;
+ }
+ */
+ const string & getName();
+
+ void print( const string & space );
+
+ Token * getToken( unsigned int n );
+
+ inline signed int numTokens() const{
+ return tokens.size() - 1;
+ }
+
+ inline const vector< Token * > * getTokens() const{
+ return &tokens;
+ }
+
+ inline void resetToken(){
+ num_token = 1;
+ }
+
+ Token * readToken();
+ bool hasTokens();
+
+ bool operator== ( const string & rhs );
+ bool operator!= ( const string & rhs );
+
+ Token & operator>>( string & rhs ) throw( TokenException );
+ Token & operator>>( int & rhs ) throw( TokenException );
+ Token & operator>>( double & rhs ) throw( TokenException );
+ Token & operator>>( Token * & rhs ) throw( TokenException );
+ Token & operator>>( bool & rhs ) throw( TokenException );
+
+
+protected:
+ /* Only TokenReader can create and destroy a Token */
+ Token();
+ Token( string tok, bool parse = true );
+ virtual ~Token();
+ friend class TokenReader;
+
+ virtual inline const string & _getName(){
+ return name;
+ }
+
+ void lowerCase( string & s );
+ void finalize();
+
+ unsigned int num_token;
+ vector< Token * > tokens;
+ string name;
+};
+
+#endif
diff --git a/util/token_exception.cpp b/util/token_exception.cpp
new file mode 100644
index 00000000..3854ed2f
--- /dev/null
+++ b/util/token_exception.cpp
@@ -0,0 +1,15 @@
+#include <exception>
+#include <string>
+#include "token_exception.h"
+
+TokenException::TokenException():
+exception(){
+}
+
+TokenException::TokenException( const string & reason ):
+exception(){
+ this->reason = reason;
+}
+
+TokenException::~TokenException() throw() {
+}
diff --git a/util/token_exception.h b/util/token_exception.h
new file mode 100644
index 00000000..34ad7178
--- /dev/null
+++ b/util/token_exception.h
@@ -0,0 +1,25 @@
+#ifndef _token_exception_h
+#define _token_exception_h
+
+#include <exception>
+#include <string>
+
+using namespace std;
+
+class TokenException : public exception{
+public:
+ TokenException();
+ TokenException( const string & reason );
+
+ ~TokenException() throw();
+
+ inline const string & getReason() const{
+ return reason;
+ }
+
+protected:
+ string reason;
+
+};
+
+#endif
diff --git a/util/tokenreader.cpp b/util/tokenreader.cpp
new file mode 100644
index 00000000..00437720
--- /dev/null
+++ b/util/tokenreader.cpp
@@ -0,0 +1,140 @@
+#include <fstream>
+#include <iostream>
+#include <string>
+#include <vector>
+
+#include "token.h"
+#include "token_exception.h"
+#include "tokenreader.h"
+
+using namespace std;
+
+TokenReader::TokenReader( const char * file ){
+ ifile.open( file );
+ myfile = file;
+ ifile >> noskipws;
+ cout<<"Opened "<<file<<endl;
+}
+
+TokenReader::~TokenReader(){
+ ifile.close();
+
+ /* tokenreader giveth, and tokenreader taketh */
+ for ( vector< Token * >::iterator it = my_tokens.begin(); it != my_tokens.end(); it++ ){
+ delete *it;
+ }
+}
+
+Token * TokenReader::readToken() throw( TokenException ){
+
+ if ( !ifile ) throw TokenException("Could not load file");
+ // Token * t;
+
+ // string token_string;
+
+ char open_paren = 'x';
+ int parens = 1;
+ while ( ifile.good() && open_paren != '(' ){
+ ifile >> open_paren;
+ }
+ // token_string += '(';
+
+ Token * cur_token = new Token();
+ my_tokens.push_back( cur_token );
+ Token * first = cur_token;
+ vector< Token * > token_stack;
+ token_stack.push_back( cur_token );
+
+ char n;
+ string cur_string = "";
+ // while ( parens != 0 ){
+
+ /* in_quote is true if a " is read and before another " is read */
+ bool in_quote = false;
+
+ /* escaped unconditionally adds the next character to the string */
+ bool escaped = false;
+ while ( !token_stack.empty() ){
+ if ( !ifile ){
+ cout<<__FILE__<<": "<<myfile<<" is bad. Open parens "<<parens<<endl;
+ // cout<<"Dump: "<< token_string << "Last token = [" << n << "]" << (int)n << endl;
+ first->print( " " );
+ throw TokenException("Wrong number of parentheses");
+ }
+ // char n;
+ // slow as we go
+ ifile >> n;
+
+ const char * alpha = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789./-_!";
+ const char * nonalpha = " ()#\"";
+ // cout<<"Alpha char: "<<n<<endl;
+
+ if ( escaped ){
+ cur_string += n;
+ escaped = false;
+ continue;
+ }
+
+ if ( n == '\\' ){
+ escaped = true;
+ continue;
+ }
+
+ if ( in_quote ){
+ if ( n == '"' ){
+ in_quote = false;
+
+ Token * sub = new Token( cur_string, false );
+ cur_token->addToken( sub );
+ cur_string = "";
+
+ } else
+ cur_string += n;
+
+ } else {
+ if ( n == '"' )
+ in_quote = true;
+
+ if ( strchr( alpha, n ) != NULL ){
+ cur_string += n;
+ } else if ( cur_string != "" && strchr( nonalpha, n ) != NULL ){
+ // cout<<"Made new token "<<cur_string<<endl;
+ Token * sub = new Token( cur_string, false );
+ cur_token->addToken( sub );
+ cur_string = "";
+ }
+ }
+
+ if ( n == '#' ){
+ while ( n != '\n' && !ifile.eof() ){
+ ifile >> n;
+ }
+ continue;
+ } else if ( n == '(' ){
+ Token * another = new Token();
+ cur_token->addToken( another );
+ cur_token = another;
+ token_stack.push_back( cur_token );
+ /*
+ parens++;
+ cout<<"Inc Parens is "<<parens<<endl;
+ */
+ } else if ( n == ')' ){
+
+ if ( token_stack.empty() ){
+ cout<<"Stack is empty"<<endl;
+ throw TokenException("Stack is empty");
+ }
+ token_stack.pop_back();
+ cur_token = token_stack.back();
+
+ }
+
+ }
+
+ // first->print("");
+ first->finalize();
+ return first;
+
+}
+
diff --git a/util/tokenreader.h b/util/tokenreader.h
new file mode 100644
index 00000000..ee1107c6
--- /dev/null
+++ b/util/tokenreader.h
@@ -0,0 +1,30 @@
+#ifndef _tokenreader_h
+#define _tokenreader_h
+
+#include <fstream>
+#include <string>
+#include <vector>
+#include "token_exception.h"
+
+using namespace std;
+
+class Token;
+
+class TokenReader{
+public:
+ TokenReader( const char * filename );
+
+ // returns a token which YOU must delete
+ Token * readToken() throw( TokenException );
+
+ ~TokenReader();
+
+protected:
+
+ ifstream ifile;
+ string myfile;
+ vector< Token * > my_tokens;
+
+};
+
+#endif

File Metadata

Mime Type
text/x-diff
Expires
Thu, Jun 11, 2:20 PM (3 w, 4 d ago)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
69436
Default Alt Text
(59 KB)

Event Timeline