00001 #include "flGlobal.h"
00002 #if FL_SPRITE != 0
00003 #include <stdlib.h>
00004 #include <stdio.h>
00005 #include <pspgu.h>
00006 #include <pspgum.h>
00007
00008 #if FL_INCLUDE_ALL_C == 0
00009 #include "flSprite.h"
00010 #include "flTexture.h"
00011 #include "flMemory.h"
00012 #include "flMath.h"
00013 #endif
00014
00015 Sprite* spriteCreate(Texture* inTex, int inFrameWidth, int inFrameHeight) {
00016 if(!inTex) {
00017 #if FL_DEBUG_WARNING != 0
00018 debugWarning("Trying to create sprite from NULL texture.");
00019 #endif
00020 return NULL;
00021 }
00022 Sprite* tempOut = memAlloc(sizeof(Sprite));
00023 if(!tempOut) {
00024 #if FL_DEBUG_ERROR != 0
00025 debugError("Couldn't create sprite, out of memory.");
00026 #endif
00027 return NULL;
00028 }
00029
00030 tempOut->spriteTex = inTex;
00031 tempOut->spriteX = 0;
00032 tempOut->spriteY = 0;
00033 tempOut->spriteWidth = inFrameWidth;
00034 tempOut->spriteHeight = inFrameHeight;
00035 tempOut->spriteAngle = 0.0f;
00036 tempOut->spriteScaleX = 1.0f;
00037 tempOut->spriteScaleY = 1.0f;
00038 tempOut->spriteFrame = 0;
00039 tempOut->spriteFrameCount = ((inTex->texWidth / inFrameWidth) * (inTex->texHeight / inFrameHeight));
00040
00041 return tempOut;
00042 }
00043
00044 void spriteFree(Sprite* inSprite) {
00045 if(!inSprite) {
00046 #if FL_DEBUG_WARNING != 0
00047 debugWarning("Trying to free a NULL sprite.");
00048 #endif
00049 return;
00050 }
00051 memFree(inSprite);
00052 }
00053
00054 void spriteRotate(Sprite* inSprite, float inAngle) {
00055 inSprite->spriteAngle += inAngle;
00056 }
00057
00058 void spriteResize(Sprite* inSprite, float inWidth, float inHeight) {
00059 inSprite->spriteScaleX = (inWidth / inSprite->spriteWidth);
00060 inSprite->spriteScaleY = (inHeight / inSprite->spriteHeight);
00061 }
00062
00063 void spriteMove(Sprite* inSprite, int inX, int inY) {
00064 inSprite->spriteX += inX;
00065 inSprite->spriteY += inY;
00066 }
00067
00068 void spriteMoveTo(Sprite* inSprite, int inX, int inY) {
00069 inSprite->spriteX = inX;
00070 inSprite->spriteY = inY;
00071 }
00072
00073 void spriteDraw2d(Sprite* inSprite) {
00074 spriteDraw2dFrame(inSprite, inSprite->spriteFrame);
00075 inSprite->spriteFrame++;
00076 while(inSprite->spriteFrame >= inSprite->spriteFrameCount)
00077 inSprite->spriteFrame -= inSprite->spriteFrameCount;
00078 while(inSprite->spriteFrame < 0)
00079 inSprite->spriteFrame += inSprite->spriteFrameCount;
00080 }
00081
00082 void spriteDraw2dFrame(Sprite* inSprite, int inFrame) {
00083 while(inFrame >= inSprite->spriteFrameCount)
00084 inFrame -= inSprite->spriteFrameCount;
00085 while(inFrame < 0)
00086 inFrame += inSprite->spriteFrameCount;
00087
00088 int tempFrameX = (inFrame * inSprite->spriteWidth);
00089 int tempFrameY = 0;
00090 while(tempFrameX >= inSprite->spriteTex->texWidth) {
00091 tempFrameX -= (inSprite->spriteTex->texWidth / inSprite->spriteWidth);
00092 tempFrameY += inSprite->spriteHeight;
00093 }
00094
00095 sceGuDisable(GU_DEPTH_TEST);
00096 sceGuDisable(GU_CULL_FACE);
00097
00098 texBind(inSprite->spriteTex);
00099 sceGuTexFilter(GU_LINEAR, GU_LINEAR);
00100 sceGuTexFunc(GU_TFX_REPLACE, GU_TCC_RGBA);
00101
00102 vertTsVf* tempVerts = (vertTsVf*)sceGuGetMemory(sizeof(vertTsVf) << 2);
00103
00104 float tempWidth = inSprite->spriteWidth * inSprite->spriteScaleX;
00105 float tempHeight = inSprite->spriteHeight * inSprite->spriteScaleY;
00106 float tempRad = mathPythag2f(((float)tempWidth * 0.5f), ((float)tempHeight * 0.5f));
00107 float tempAngle = mathATanf(tempWidth / tempHeight);
00108
00109 tempVerts[0].vertX = inSprite->spriteX + (tempRad * mathSinf(inSprite->spriteAngle - tempAngle));
00110 tempVerts[0].vertY = inSprite->spriteY - (tempRad * mathCosf(inSprite->spriteAngle - tempAngle));
00111 tempVerts[1].vertX = inSprite->spriteX + (tempRad * mathSinf(inSprite->spriteAngle + tempAngle));
00112 tempVerts[1].vertY = inSprite->spriteY - (tempRad * mathCosf(inSprite->spriteAngle + tempAngle));
00113 tempVerts[2].vertX = inSprite->spriteX + (tempRad * mathSinf(inSprite->spriteAngle + MATH_PI - tempAngle));
00114 tempVerts[2].vertY = inSprite->spriteY - (tempRad * mathCosf(inSprite->spriteAngle + MATH_PI - tempAngle));
00115 tempVerts[3].vertX = inSprite->spriteX + (tempRad * mathSinf(inSprite->spriteAngle + MATH_PI + tempAngle));
00116 tempVerts[3].vertY = inSprite->spriteY - (tempRad * mathCosf(inSprite->spriteAngle + MATH_PI + tempAngle));
00117
00118 tempVerts[0].vertZ = 0.0f;
00119 tempVerts[0].vertU = tempFrameX;
00120 tempVerts[0].vertV = tempFrameY;
00121 tempVerts[1].vertZ = 0.0f;
00122 tempVerts[1].vertU = (tempFrameX + inSprite->spriteWidth);
00123 tempVerts[1].vertV = tempFrameY;
00124 tempVerts[2].vertZ = 0.0f;
00125 tempVerts[2].vertU = (tempFrameX + inSprite->spriteWidth);
00126 tempVerts[2].vertV = (tempFrameY + inSprite->spriteHeight);
00127 tempVerts[3].vertZ = 0.0f;
00128 tempVerts[3].vertU = tempFrameX;
00129 tempVerts[3].vertV = (tempFrameY + inSprite->spriteHeight);
00130
00131 sceGuDrawArray(GU_TRIANGLE_FAN, GU_TEXTURE_16BIT | GU_VERTEX_32BITF | GU_TRANSFORM_2D, 4, 0, tempVerts);
00132
00133 sceGuEnable(GU_CULL_FACE);
00134 sceGuEnable(GU_DEPTH_TEST);
00135 }
00136
00137 #endif