qafEnvironment.h

00001 /* 
00002 ** Qaf Framework 1.2
00003 ** June 2006
00004 ** 
00005 ** Pedro Luchini de Moraes, Public Domain - Free Lunch Code
00006 */
00007 
00008 #ifndef QAF_ENVIRONMENT_H
00009 #define QAF_ENVIRONMENT_H
00010 
00011 #include "qafDef.h"
00012 #include "qafGameObjFactory.h"
00013 #include "qafJoystickSystem.h"
00014 #include "qafRoom.h"
00015 #include "qafutil/qafBigTexture.h"
00016 #include "qafutil/qafVector2D.h"
00017 #include "qafutil/qafVector3D.h"
00018 
00019 
00020 
00021 namespace qaf {
00022     
00053     template <typename T>
00054     class ObjIterator {
00055         public:
00060             bool hasNext () {
00061                 return (currObjInx >= 0);
00062             };
00063             
00070             T * next () {
00071                 if ( currObjInx < 0 )
00072                     return NULL;
00073                 else {
00074                     currObjInx--;
00075                     return objects->elem( currObjInx + 1 );
00076                 }
00077             }
00078             
00082             int getCount () {
00083                 return objects->getCount();
00084             }
00085             
00086         private:
00087             friend class Environment;
00088             
00089             int currObjInx;
00090             const Container<T *> * objects;
00091             
00092             inline ObjIterator ( const Container<T *> * _objects ) : objects(_objects) {
00093                 currObjInx = _objects->getCount() - 1;
00094             }
00095     };
00096     
00097     
00098     
00099     
00115     class DebugVector {
00116     public:
00117         DebugVector () {}
00118         
00119         DebugVector ( Vector2D & _p1, Vector2D & _p2, DWORD _color );
00120         
00121         void render ();
00122         
00123     private:
00124         Vector2D p1, p2;
00125         DWORD color;
00126     };
00127     
00128     
00129     
00130     
00149     class Environment {
00150     public:
00151 
00162         static float time;
00163         
00168         static int frames;
00169         
00170 
00188         static bool initialize ( bool useBackBuffer, bool useDebug );
00189         
00197         static void update ( float dt );
00198         
00206         static void enableObjUpdate ( bool flag );
00207         
00212         static bool isObjUpdateEnabled ();
00213         
00225         static void enableRender ( bool flag );
00226         
00231         static bool isRenderEnabled ();
00232         
00233         
00246         static void shutdown ();
00247         
00263         static void enableBackBuffer ( bool flag );
00264         
00271         static bool isBackBufferEnabled ();
00272         
00281         static unsigned long getBackBuffer ();
00282         
00283         
00290         static void setGameObjFactory ( GameObjFactory * _gameObjFactory );
00291         
00297         static GameObjFactory * getGameObjFactory ();
00298         
00315         static void setPrologueCallback ( void (*cb) () );
00316         
00333         static void setEpilogueCallback ( void (*cb) () );
00334         
00335         
00360         static bool loadRoom ( std::string filename );
00361         
00366         static Room * getLoadedRoom ();
00367 
00382         static void unloadRoom ();
00383         
00384         
00395         static void setScrollingPoint ( int x, int y );
00396         
00403         static void moveScrollingPoint ( int dx, int dy );
00404         
00420         static void centerScrollingPoint ( int x, int y );
00421         
00426         static int getScrollingX ();
00427         
00432         static int getScrollingY ();
00433         
00434         
00441         static int getScreenWidth ();
00442         
00449         static int getScreenHeight ();
00450         
00451         
00467         static void addGameObj ( GameObj * obj, int layer = -1, bool onTop = true );
00468         
00486         static int findGameObj ( GameObj * obj, int * index = NULL );
00487         
00504         static void removeGameObj ( GameObj * obj, bool deleteIt, int srcLayer = -1 );
00505         
00526         static void moveGameObj ( GameObj * obj, int destLayer, int srcLayer = -1 );
00527         
00542         static void bringGameObjToFront ( GameObj * obj, int srcLayer = -1 );
00543         
00558         static void sendGameObjToBack ( GameObj * obj, int srcLayer = -1 );
00559         
00560         
00561         
00566         static int getNumberOfJoysticks ();
00567         
00574         static Joystick * getJoystick ( int i );
00575         
00576         
00592         static const BigTexture * loadBigTexture ( const char * filename );
00593         
00605         static void freeBigTexture ( const BigTexture * tex );
00606         
00623         static void setBigTextureCacheSize ( int size );
00624         
00625         
00626     private:
00627         
00628         // A Container of pointers to Containers of pointers to GameObjs.
00629         // This stores all currently active GameObjs.
00630         static Container<Container<GameObj *> *> gameObjLayers;
00631         
00632         // A generic object discriminator:
00633         class AbstractObjDiscriminator {
00634             public:
00635                 virtual void addGameObj ( GameObj * obj ) = 0;
00636                 virtual void removeGameObj ( GameObj * obj ) = 0;
00637                 virtual void removeAll () = 0;
00638                 virtual ~AbstractObjDiscriminator () {}
00639         };
00640         
00641         // A type-specific object discriminator:
00642         template <typename T>
00643         class ObjDiscriminator : public AbstractObjDiscriminator {
00644             public:
00645                 // The constructor looks through the current object list for
00646                 // objects that match its target class:
00647                 ObjDiscriminator () {
00648                     for ( int layerInx = 0; layerInx < gameObjLayers.getCount(); layerInx++ ) {
00649                         for ( int objInx = 0; objInx < gameObjLayers[layerInx]->getCount(); objInx++ ) {
00650                             // Try to cast this pointer to the correct type:
00651                             T * t_obj = dynamic_cast<T *> ( gameObjLayers[layerInx]->elem( objInx ) );
00652                             if ( t_obj ) {
00653                                 // Add it:
00654                                 objects.add( t_obj );
00655                             }
00656                         }
00657                     }
00658                 }
00659                 
00660                 // Adds the object to the object list if it's of the correct
00661                 // type.
00662                 void addGameObj ( GameObj * obj ) {
00663                     // Try to cast this pointer to the correct type:
00664                     T * t_obj = dynamic_cast<T *> ( obj );
00665                     if ( t_obj ) {
00666                         // Add it:
00667                         objects.add( t_obj );
00668                     }
00669                 }
00670                 
00671                 // Removes the object if it was added to a list:
00672                 void removeGameObj ( GameObj * obj ) {
00673                     // Try to cast this pointer to the correct type:
00674                     T * t_obj = dynamic_cast<T *> ( obj );
00675                     if ( t_obj ) {
00676                         // Remove it:
00677                         objects.removeFirst( t_obj );
00678                     }
00679                 }
00680                 
00681                 // Removes all objects:
00682                 void removeAll () {
00683                     objects.removeAll();
00684                 }
00685                 
00686                 // This is public so the ObjIterator class can see the objects
00687                 // contained in the discriminator.
00688                 Container<T *> objects;
00689         };
00690         
00691         // A Container of object discriminators:
00692         static Container<AbstractObjDiscriminator *> objDiscriminators;
00693         
00694     public:
00695         
00705         template <typename T>
00706         static ObjIterator<T> makeObjIterator () {
00707             // Keep a reference to the discriminator for this class.
00708             static ObjDiscriminator<T> myDiscriminator;
00709             
00710             // This will only be run once:
00711             static bool once = true;
00712             if ( once ) {
00713                 // Add the discriminator to the Environment's discriminator
00714                 // list:
00715                 Environment::objDiscriminators.add( &myDiscriminator );
00716                 
00717                 once = false;
00718             }
00719             
00720             // Create and return an object iterator:
00721             return ObjIterator<T>( &(myDiscriminator.objects) );
00722         }
00723         
00724         
00725     private:
00726         // A generic collision handler:
00727         class AbstractCollisionHandler {
00728             public:
00729                 virtual void checkCollisions () = 0;
00730                 virtual ~AbstractCollisionHandler () {}
00731         };
00732         
00733         // A type-specific collision handler:
00734         template <typename T1, typename T2>
00735         class CollisionHandler : public AbstractCollisionHandler {
00736             public:
00737                 // The constructor receives a pointer to the handler function:
00738                 CollisionHandler ( void (*_pfHandler) (T1 *, T2 *) ) {
00739                     pfHandler = _pfHandler;
00740                 }
00741                 
00742                 // Checks collisions between the objects:
00743                 // From back to front, so objects that were added later are
00744                 // checked first...
00745                 void checkCollisions () {
00746                     ObjIterator<T1> objects1 = makeObjIterator<T1>();
00747                     while ( objects1.hasNext() ) {
00748                         // Get first object:
00749                         T1 * obj1 = objects1.next();
00750                         
00751                         ObjIterator<T2> objects2 = makeObjIterator<T2>();
00752                         while ( objects2.hasNext() ) {
00753                             // Get second object:
00754                             T2 * obj2 = objects2.next();
00755                             
00756                             // Both objects have collision structures?
00757                             CollisionStruct * cs1 = obj1->getCollisionStruct();
00758                             CollisionStruct * cs2 = obj2->getCollisionStruct();
00759                             
00760                             if ( cs1 && cs2 ) {
00761                                 // The structures collide?
00762                                 if ( cs1->collidesWith( cs2 ) ) {
00763                                     // Invoke the handler:
00764                                     pfHandler( obj1, obj2 );
00765                                 }
00766                             }
00767                         }
00768                     }
00769                 }
00770                 
00771             private:
00772                 void (*pfHandler) (T1 *, T2 *);
00773         };
00774         
00775         // A Container of collision handlers:
00776         static Container<AbstractCollisionHandler *> collisionHandlers;
00777         
00778     public:
00779         
00815         template <typename T1, typename T2>
00816         static void registerCollisionHandler ( void (*pfHandler) (T1 *, T2 *) ) {
00817             // Create the collision handler:
00818             AbstractCollisionHandler * newHandler = new CollisionHandler<T1, T2>( pfHandler );
00819             
00820             // Add the handler:
00821             collisionHandlers.add( newHandler );
00822         }
00823         
00824         
00846         class DebugConsole {
00847         public:
00848             inline DebugConsole & operator << ( char c ) {
00849                 data += c;
00850                 
00851                 return *this;
00852             }
00853             
00854             inline DebugConsole & operator << ( const char * str ) {
00855                 data += str;
00856                 
00857                 return *this;
00858             }
00859             
00860             inline DebugConsole & operator << ( const std::string & str ) {
00861                 data += str;
00862                 
00863                 return *this;
00864             }
00865             
00866             inline DebugConsole & operator << ( int val ) {
00867                 sprintf( temp, "%d", val );
00868                 data += temp;
00869                 
00870                 return *this;
00871             }
00872             
00873             inline DebugConsole & operator << ( float val ) {
00874                 sprintf( temp, "%f", val );
00875                 data += temp;
00876                 
00877                 return *this;
00878             }
00879             
00880             inline DebugConsole & operator << ( bool b ) {
00881                 data += ( b ? "true" : "false" );
00882                 
00883                 return *this;
00884             }
00885             
00886             inline DebugConsole & operator << ( const Vector2D & v2D ) {
00887                 sprintf( temp, "(%f, %f)", v2D.x, v2D.y );
00888                 data += temp;
00889                 
00890                 return *this;
00891             }
00892             
00893             inline DebugConsole & operator << ( const Vector3D & v3D ) {
00894                 sprintf( temp, "(%f, %f, %f)", v3D.x, v3D.y, v3D.z );
00895                 data += temp;
00896                 
00897                 return *this;
00898             }
00899             
00900             inline DebugConsole & operator << ( const void * ptr ) {
00901                 sprintf( temp, "%p", ptr );
00902                 data += temp;
00903                 
00904                 return *this;
00905             }
00906             
00907             inline const char * getData () {
00908                 return data.c_str();
00909             }
00910             
00911             inline void clear () {
00912                 data = "";
00913             }
00914             
00915         private:
00916             char temp[500];
00917             std::string data;
00918         };
00919         
00920         static DebugConsole cout;
00921         
00922         
00937         static Container<DebugVector> debugVectors;
00938         
00939         
00940     private:
00941         
00942         // Draws the entire environment -- room, game objs, water, etc.
00943         static void render ();
00944         
00945         // Performs pending operations in operation buffer.
00946         static void doOpBuffer ();
00947         
00948         // Performs the actual room loading/unloading:
00949         static void doLoadRoom ( Room * newRoom, void * objInfo );
00950         static void doUnloadRoom ();
00951         
00952         // Frees "dead" textures from the BigTexture cache.
00953         static void enforceBigTexCacheSize ();
00954         
00955         
00956     };
00957     
00958 }
00959 
00960 #endif

Generated on Sun Mar 25 12:32:12 2007 for Qaf Framework by  doxygen 1.5.1-p1