C:/DevKitPro/!MDuel/source/spriteObject.h

Go to the documentation of this file.
00001 /*
00002  * Marshmallow Duel DS v2
00003  * Copyright © 2007 Sam Pospischil http://pospi.spadgos.com
00004  * 
00005  * This program is free software; you can redistribute it and/or modify
00006  * it under the terms of the GNU General Public License as published by
00007  * the Free Software Foundation; either version 2 of the License, or
00008  * (at your option) any later version.
00009  * 
00010  * This program is distributed in the hope that it will be useful,
00011  * but WITHOUT ANY WARRANTY; without even the implied warranty of
00012  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
00013  * GNU General Public License for more details.
00014  * 
00015  * You should have received a copy of the GNU General Public License
00016  * along with this program; if not, write to the Free Software
00017  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
00018  */
00019 
00020 #ifndef _SPRITEOBJECT_H
00021 #define _SPRITEOBJECT_H
00022 
00023 #include <PA9.h>
00024 #include <vector>
00025 #include <typeinfo>
00026 #include <string>
00027         using namespace std;
00028 #include "macros.h"
00029 #include "spriteManager.h"
00030 
00056 class spriteObject
00057 {
00058         public:
00059                 spriteObject(spriteManager* newsm);
00060                 virtual ~spriteObject();
00061 
00062                 spriteObject(const spriteObject &s);
00063                 
00064                 /* 
00065                         upon initialising, ensure you set the following:
00066                                 pallete, sprite, center, bounds, position, collision
00067                         optionally set the following (order is important, do the above first!):
00068                                 layer, flipped, animation / frame, speed, sound channel
00069                         
00070                         movement vars (x, y, vx, vy, accel etc) are in fixed point format (256 = 1 pixel).
00071                         all others (bounds, center etc) are in pixel values.
00072                         All inputs to this class are pixel values, the conversion should be maintained internally.
00073                 */
00074                 
00079                 virtual void setPallete(u8 id)
00080                 {
00081                         palleteID = id;
00082                         #ifdef __MDDEBUG
00083                         char buffer[255];
00084                         sprintf(buffer, "pallete set (#%d)", palleteID);
00085                         macros::debugMessage(className, buffer);
00086                         #endif
00087                 }
00088                 
00089                 //only works for GFX created sprites becase we need a GFX id
00090                 bool updatePallete(s8 newPalID, u8 sizex, u8 sizey, u8 colorMode = 1);
00091                 
00092                 s8 getPalleteID() const {return palleteID;}
00093                 s8 getSpriteID() const {return spriteID;}
00094                 u8 getFrame() const {return frame;}
00095                 
00105                 void setBounds(s8 t, s8 r, s8 b, s8 l) {bounds.t = t; bounds.r = r; bounds.b = b; bounds.l = l;}
00110                 void setBounds(s8 arr[4]) {bounds.t = arr[0]; bounds.r = arr[1]; bounds.b = arr[2]; bounds.l = arr[3];}
00111                 void setCenter(u8 x, u8 y) {centerx = x; centery = y;}
00118                 void setLayer(u8 newLayer) {UPDATEDlayer = true; layer = newLayer;}
00119                 
00120                 //'give' makes a new sprite from some data
00121                 //@pre: palleteID has been set
00122                 s8 giveSprite(const unsigned char* spriteData, u8 sizex, u8 sizey, u8 cx = 16, u8 cy = 16, u8 minIndex = 0, s16 nx = 0, s16 ny = 0, u8 colorMode = 1);
00123                 s8 givePallete(const unsigned short* palleteData);
00124                 s8 giveGFX(u16 GFXid, u8 sizex, u8 sizey, u8 cx = 16, u8 cy = 16, u8 minIndex = 0, s16 nx = 0, s16 ny = 0, u8 colorMode = 1);
00125                 
00126                 //hide an object's visuals without actually deleting it
00127                 void deleteSprite();
00128                 
00129                 //work out whether this object has gfx associated with it
00130                 bool hasGraphics() const;
00131                 
00132                 //basic animation
00133                 virtual void setPos(s16 nx, s16 ny) {x = (nx-centerx)<<8; y = (ny-centery)<<8;}
00140                 void setBasePos(s16 ny) {y = (ny-centery-bounds.b)<<8;}
00141                 
00142                 void setSpeed(float nvx, float nvy) {vx = (s32)(nvx*256); vy = (s32)(nvy*256);}
00143                 void setSpeed(s32 nvx, s32 nvy) {vx = (nvx<<8); vy = (nvy<<8);}
00144                 void setvx(s32 nvx) {vx = (nvx<<8);}
00145                 void setvy(s32 nvy) {vy = (nvy<<8);}
00157                 void setRawSpeed(s32 nvx, s32 nvy) {vx = nvx; vy = nvy;}
00158                 void setFlipped(bool fh, bool fv = false);
00159                 
00160                 void setTransparency(u8 transLevel = 15);       //0=0%, 15=100%
00161                 
00162                 virtual void turnAround();
00163                 
00168                 void setFrame(u8 fr)
00169                 {
00170                         frame = fr;
00171                         arbitraryAnim = 0;
00172                         PA_SetSpriteAnim(sm->screen, spriteID, frame);
00173                 }
00186                 void setAnim(u8 f1, u8 f2, u8 s, u8 type = ANIM_LOOP, u8 times = -1)
00187                 {
00188                         //regular PAlib animation isn't fast or responsive enough for me, so I'm using arbitraryAnims for everything
00189                         vector<u8> frames;
00190                         for (int i=0; i <= f2-f1; ++i)
00191                                 frames.push_back(f1+i);
00192                         
00193                         setArbitraryAnim(frames, (type == ANIM_LOOP), 60/s);    //TICKSPERFRAME = 60/ANIMSPEED
00194                 }
00203                 void setArbitraryAnim(vector<u8> frames, bool loop, u8 ticksPerFrame = TICKSPERFRAME)
00204                 {
00205                         arbitraryAnim = 1+loop;
00206                         arbitrarySpeed = ticksPerFrame;
00207                         arbitraryTimeCounter = 0;
00208                         arbitraryFrameCounter = 0;
00209                         arbFrames = frames;
00210                         PA_SetSpriteAnim(sm->screen, spriteID, frames[0]);      //makes the first frame update happen straight away
00211                 }
00216                 bool isInAnim() const {return (arbitraryAnim != 0);}
00217                 
00218                 //totally bitching collision detection
00219                 virtual bool isColliding(const spriteObject* other, bool checkReverse = true) const;
00220                 bool inHorizPlaneOf(const spriteObject* other) const;
00221                 bool inVertPlaneOf(const spriteObject* other) const;
00222                 bool isUnder(const spriteObject* other) const;
00223                 bool isOver(const spriteObject* other) const;
00224                 bool isStandingOn(const spriteObject* other) const;
00225                 bool isFacing(const spriteObject* other) const;
00226                 
00240                 enum collisionInfo
00241                 {
00242                         COL_NONE = 0,
00243                         COL_BASEABLE = 1,               //COL_BASEABLE
00244                         COL_DOWNONLY = 2,
00245                         COL_DOWNBASEABLE = 3,   //COL_DOWNONLY & COL_BASEABLE
00246                         COL_SOLID = 4,
00247                         COL_SOLIDBASEABLE = 5,  //COL_SOLID & COL_BASEABLE
00248                         COL_CENTERPOINT = 8,            //collides if middle of sprite is within other sprite's bounds
00249                         COL_PIXELPERFECT = 16           //exhaustive pixel-precise collision, only for really important stuff that doesnt animate too much (pickups)
00250                 };
00251                 void setCollision(collisionInfo c) {collision = c;}
00257                 void setCheckCollision(bool ch) {checkCollision = ch;}
00258                 bool isBaseable() const;
00259                 
00266                 spriteObject* getIgnored() {return ignoreUntilUntouched;}
00272                 void setIgnored(spriteObject* o) {ignoreUntilUntouched = o;}
00273                 
00274                 //update actual sprite object to which this object relates
00275                 //@pre: palleteID and spriteID are set
00276                 virtual void updateSprite();
00277                 
00278                 //check for collision. Check will start from sm->gameSprites[indexToCheckFrom],
00279                 //since checks are bidirectional and must only be done once for each object pair.
00280                 virtual void checkCollisions(u8 indexToCheckFrom = 0);
00281                 
00289                 virtual void collidingWith(spriteObject* other) {}
00290                 
00297                 bool pointCollision(s16 x, s16 y) {return (x < getRight() && x > getLeft() && y < getBottom() && y > getTop());}
00298                 
00299                 //getters
00300                 s16 getx() const {return (x>>8)+centerx;}
00301                 s16 gety() const {return (y>>8)+centery;}
00302                 s32 getvx() const {return (vx>>8);}
00303                 s32 getvy() const {return (vy>>8);}
00304                 s32 getRawvx() const {return vx;}
00305                 s32 getRawvy() const {return vy;}
00306                 s16 getTop() const {return (y>>8)+centery+bounds.t;}
00307                 s16 getRight() const {return (x>>8)+centerx+bounds.r;}
00308                 s16 getBottom() const {return (y>>8)+centery+bounds.b;}
00309                 s16 getLeft() const {return (x>>8)+centerx+bounds.l;}
00310                 
00311                 bool getFlippedh() const {return flippedh;}
00312                 bool getFlippedv() const {return flippedv;}
00313                 
00314                 #ifdef __WITHSOUND
00315                 //sound stuff
00316                 void setSoundChannel(s8 channel) {soundChannel = channel;}
00317                 void playSound(const u8* sound, const u32* size, bool repeat = false, u8 vol = 127);
00318                 void playSound(spriteManager::soundData* sound, bool repeat = false, u8 vol = 127);
00323                 void stopSound()
00324                 {
00325                         if (hasSoundLooping()) sm->stopSound(soundChannel);
00326                 }
00327                 bool hasSoundLooping() {return sm->soundLooping(soundChannel);}
00328                 #endif
00329                 
00331                 static const u32 SCREENW = 65536;
00333                 static const u32 SCREENH = 49152;
00335                 static const u8 TICKSPERFRAME = 6;
00337                 static const u8 ANIMSPEED = 10;
00338                 
00339                 //heriachies
00340                 void setParent(spriteObject* other);    //only ever called by parent's addChild()
00341                 void addChild(spriteObject* other);             //add another spriteObject to me
00342                 bool removeChild(/*spriteObject* other*/);      //unparent child spriteObject
00343                 
00349                 virtual void makeStatic() {updateSprite(); staticSprite = true;}
00350                 
00357                 spriteObject* getAttachment() const {return attachment;}
00366                 void setAttachment(spriteObject* o) {attachment = o; o->isAttachment = true;}
00367                 
00377                 void setRotSet(u8 rs) {rotSetID = rs;}
00381                 bool enableRotation() {if (rotSetID != -1) {PA_SetSpriteRotEnable(sm->screen, spriteID, rotSetID); bRotating=true;} return (rotSetID != -1);}
00385                 void disableRotation() {bRotating=false; PA_SetSpriteRotDisable(sm->screen, spriteID);}
00389                 bool setRotation(u16 newRot) {if (rotSetID == -1 || !bRotating) return false; rotAngle = newRot; rotAngle &= 511; return true;}
00390                 
00392                 bool bNeedsGFXCleanup;
00398                 s32 getGFXid() const {return gfxID;}
00399                 
00408                 void setLifetime(u16 numSecs) {framesToLive = numSecs*ANIMSPEED*TICKSPERFRAME;}
00409                 s16 getLifetime() {return framesToLive;}
00410                 void disableLifetime() {framesToLive = -1;}
00411                 
00417                 bool markedForDeletion() {return framesToLive == 0;}
00418                 
00422                 void destroy()
00423                 {
00424                         framesToLive = 0;
00425                         #ifdef __MDDEBUG
00426                         char buffer[255];
00427                         sprintf(buffer, "flagged for deletion (gfx #%d, sprite #%d, pallete #%d)", gfxID, spriteID, palleteID);
00428                         macros::debugMessage(className, buffer);
00429                         #endif
00430                 }
00431         protected:
00432                 void swapHBounds() {u8 btemp = bounds.r; bounds.r = bounds.l*-1; bounds.l = btemp*-1;}
00433                 void swapVBounds() {u8 btemp = bounds.t; bounds.t = bounds.b*-1; bounds.b = btemp*-1;}
00434                         //this could fuck stuff up if I happen to make a btemp variable near this function call :S
00435                 
00437                 spriteObject* attachment;
00438                 bool isAttachment;                      //TODO! if unattached, this should be set back to false..
00439                 
00441                 bool staticSprite;
00442                 
00444                 spriteManager* sm;
00445                 
00446                 //very simple sprite hierachy
00447                 spriteObject* parentSprite;
00448                 //vector<spriteObject*> childSprites;
00449                 spriteObject* childSprite;
00450                 
00452                 s8 spriteID;
00454                 s8 palleteID;
00456                 s32 gfxID;
00457 
00458                 #ifdef __WITHSOUND
00459                 //channel to play all my sounds in (1 at a time per sprite!)
00460                 s8 soundChannel;
00461                 #endif
00462                 
00463                 //position and velocity variables, in fixed point format
00464                 s32 x, y, vx, vy;
00465                 s32 oldx, oldy;
00466                 bool flippedh, flippedv, oldFliph, oldFlipv;
00467                 u8 layer;
00468                 u8 frame, oldFrame;
00469                 
00471                 u8 arbitraryAnim;
00473                 u8 arbitrarySpeed;
00474                 u8 arbitraryFrameCounter;
00475                 u8 arbitraryTimeCounter;
00477                 vector<u8> arbFrames;
00478                 
00480                 struct boundingbox
00481                 {
00482                         s8 t, r, b, l;
00483                 };
00484                 boundingbox bounds;
00485                 u8 centerx, centery;    //offsets to sprite center (half width)
00486                 
00487                 collisionInfo collision;
00488                 bool checkCollision;            //only active objects (players, pickups etc) should check collision
00490                 spriteObject* ignoreUntilUntouched;
00491                 
00492                 //rotation variables
00493                 s8 rotSetID;
00494                 u16 rotAngle;
00495                 bool bRotating;
00496                 
00497                 #ifdef __MDDEBUG
00498                 string className;
00499                 #endif
00500                 
00501                 //if any of the following are set, the relevant PAlib() updating functions are called
00502                 bool UPDATEDlayer;
00503                 bool UPDATEDflip;
00504                 
00505                 //if this reaches 0, destroy self
00506                 s16 framesToLive;
00507 };
00508 
00509 #endif

Generated on Tue Mar 13 23:27:53 2007 for MDuel DS by  doxygen 1.5.1-p1