Page Menu
Home
Phabricator (Chris)
Search
Configure Global Search
Log In
Files
F127080
No One
Temporary
Actions
View File
Edit File
Delete File
View Transforms
Subscribe
Flag For Later
Award Token
Authored By
Unknown
Size
59 KB
Referenced Files
None
Subscribers
None
View Options
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
Details
Attached
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)
Attached To
Mode
R75 R-Tech1
Attached
Detach File
Event Timeline