TapestryEngine

A 2D Platformer Game Engine
Log | Files | Refs

ec4a113b1a215f0ebdb7290ee00cdcb566214bf9.svn-base (25119B)


      1 #include <time.h>
      2 #include <stdio.h>
      3 #include <string.h>
      4 #include <assert.h>
      5 #include <stdarg.h>
      6 #include "SDL.h"
      7 #include "SDL_ttf.h"
      8 
      9 //Time Defines
     10 #define FRAMES_PER_SECOND 60.0
     11 #define CLOCKS_PER_FRAME (CLOCKS_PER_SEC/FRAMES_PER_SECOND)
     12 #define MS_PER_FRAME 1/(FRAMES_PER_SECOND/1000)
     13 //
     14 
     15 //World/Screen size defines
     16 #define WORLD_W 1920
     17 #define WORLD_H 1080
     18 
     19 #define SCREEN_W 1280
     20 #define SCREEN_H 720
     21 //
     22 
     23 // Console Defines
     24 #define LINE_LIMIT 40
     25 #define LINE_SIZE 100
     26 #define CONSOLE_TEXT_LIMIT ((LINE_LIMIT+1)*LINE_SIZE)
     27 //
     28 
     29 //Actor Direction Defines
     30 #define LEFT  1
     31 #define RIGHT 0
     32 //
     33 
     34 //Actor State Defines
     35 #define IDLE      10
     36 #define RUN		  20
     37 
     38 #define RUN_LEFT  1
     39 #define RUN_RIGHT 2
     40 #define RUN_DOWN  3
     41 #define RUN_UP    4
     42 //
     43 
     44 //Terrain type defines
     45 #define AIR			0x00
     46 #define GROUND		0x01
     47 #define PLATFORM	0x02
     48 #define WATER		0x04
     49 
     50 class Console;
     51 Console* gCons = NULL;
     52 Console* rCons = NULL;
     53 
     54 class ConsoleStringManager
     55 {
     56 public:
     57 	ConsoleStringManager()
     58 	{
     59 		mEndPointer = mText;
     60 		mNextLineIndex = 0;
     61 		memset(mLines, 0, sizeof(mLines));
     62 	}
     63 
     64 	void AddLine(char* string, int CharCount)
     65 	{
     66 
     67 		if (((mEndPointer - mText) + CharCount + 1) > CONSOLE_TEXT_LIMIT)
     68 		{
     69 			mEndPointer = mText;
     70 		}
     71 
     72 		memcpy(mEndPointer, string, CharCount);
     73 		mEndPointer[CharCount] = '\0';
     74 
     75 		mLines[mNextLineIndex] = mEndPointer;
     76 		mEndPointer = (mEndPointer + CharCount + 1);
     77 
     78 		mNextLineIndex = mNextLineIndex + 1;
     79 		if (mNextLineIndex == LINE_LIMIT)
     80 		{
     81 			mNextLineIndex = 0;
     82 		}
     83 	}
     84 
     85 	void ConsoleLog(char* msg)
     86 	{
     87 		while (1)
     88 		{
     89 			char* TermChar = strchr(msg, '\n');
     90 			if (TermChar == NULL) break;
     91 
     92 			AddLine(msg, (TermChar - msg));
     93 			msg = TermChar + 1;
     94 		}
     95 	}
     96 
     97 	void ConsolePrintf(char* fmt, ...)
     98 	{
     99 		char msgf[256];
    100 
    101 		va_list args;
    102 		va_start(args, fmt);
    103 		sprintf(msgf, fmt, args);
    104 		va_end(args);
    105 
    106 		ConsoleLog(msgf);
    107 	}
    108 
    109 	char* GetLine(int x)
    110 	{
    111 		return mLines[x];
    112 	}
    113 
    114 	int GetNextLineIndex()
    115 	{
    116 		return mNextLineIndex;
    117 	}
    118 
    119 protected:
    120 
    121 	char* mLines[LINE_LIMIT];
    122 	int mNextLineIndex;
    123 
    124 	char  mText[CONSOLE_TEXT_LIMIT];
    125 	char* mEndPointer;
    126 
    127 
    128 };
    129 
    130 class Console
    131 {
    132 public:
    133 	Console(char* filename, int ptsize, SDL_Color Text, SDL_Color BG)
    134 	{
    135 		mTextRect.w = 0;
    136 		mTextRect.h = 0;
    137 		mTextRect.x = 0;
    138 		mTextRect.y = 0;
    139 
    140 		mLinePosRect.w = 0;
    141 		mLinePosRect.h = 0;
    142 		mLinePosRect.x = 0;
    143 		mLinePosRect.y = 0;
    144 
    145 		char* basepath = "C:\\Users\\baptistac1\\Documents\\Visual Studio 2013\\Projects\\TapestryEngine\\TapestryEngine\\fonts\\";
    146 
    147 		char pathbuffer[1024];
    148 		strcpy(pathbuffer, basepath);
    149 		char* fullpath = strcat(pathbuffer, filename);
    150 
    151 		mFont = TTF_OpenFont(fullpath, ptsize);
    152 
    153 		assert(mFont != NULL);
    154 
    155 		mText = Text;
    156 		mBG = BG;
    157 	}
    158 
    159 	void ConsPrintf(char* fmt, ...)
    160 	{
    161 		char msgf[256];
    162 
    163 		va_list args;
    164 		va_start(args, fmt);
    165 		vsprintf(msgf, fmt, args);
    166 		va_end(args);
    167 
    168 		mCSM.ConsoleLog(msgf);
    169 	}
    170 
    171 	void DrawConsole(SDL_Renderer* ren)
    172 	{
    173 
    174 		int PrintIndex = mCSM.GetNextLineIndex();
    175 
    176 		for (int i = 0; i < LINE_LIMIT; i++)
    177 		{
    178 
    179 			int NextLineIndex = (PrintIndex + i);
    180 			if (NextLineIndex >= LINE_LIMIT)
    181 			{
    182 				NextLineIndex = NextLineIndex - LINE_LIMIT;
    183 			}
    184 
    185 
    186 			char* line = mCSM.GetLine(NextLineIndex);
    187 
    188 			if (line != NULL)
    189 			{
    190 				const char* error;
    191 
    192 				SDL_Surface* LineSur = TTF_RenderText_Shaded(mFont, line, mText, mBG);
    193 				if (!LineSur)
    194 				{
    195 					error = SDL_GetError();
    196 				}
    197 				SDL_Texture* LineTex = SDL_CreateTextureFromSurface(ren, LineSur);
    198 				if (!LineTex)
    199 				{
    200 					error = SDL_GetError();
    201 				}
    202 				SDL_FreeSurface(LineSur);
    203 				if (SDL_QueryTexture(LineTex, NULL, NULL, &mTextRect.w, &mTextRect.h))
    204 				{
    205 					error = SDL_GetError();
    206 				}
    207 
    208 				mLinePosRect.w = mTextRect.w;
    209 				mLinePosRect.h = mTextRect.h;
    210 				mLinePosRect.x = 0;
    211 				mLinePosRect.y = (mTextRect.h * i);
    212 
    213 				if (SDL_RenderCopy(ren, LineTex, &mTextRect, &mLinePosRect))
    214 				{
    215 					error = SDL_GetError();
    216 				}
    217 				SDL_DestroyTexture(LineTex);
    218 			}
    219 		}
    220 	}
    221 
    222 	void DrawConsoleReadout(SDL_Renderer* ren, int x,int y)
    223 	{
    224 		int PrintIndex = mCSM.GetNextLineIndex();
    225 
    226 		for (int i = 0; i < LINE_LIMIT; i++)
    227 		{
    228 
    229 			int NextLineIndex = (PrintIndex + i);
    230 			if (NextLineIndex >= LINE_LIMIT)
    231 			{
    232 				NextLineIndex = NextLineIndex - LINE_LIMIT;
    233 			}
    234 
    235 
    236 			char* line = mCSM.GetLine(NextLineIndex);
    237 
    238 			if (line != NULL)
    239 			{
    240 				const char* error;
    241 
    242 				SDL_Surface* LineSur = TTF_RenderText_Shaded(mFont, line, mText, mBG);
    243 				if (!LineSur)
    244 				{
    245 					error = SDL_GetError();
    246 				}
    247 				SDL_Texture* LineTex = SDL_CreateTextureFromSurface(ren, LineSur);
    248 				if (!LineTex)
    249 				{
    250 					error = SDL_GetError();
    251 				}
    252 				SDL_FreeSurface(LineSur);
    253 				if (SDL_QueryTexture(LineTex, NULL, NULL, &mTextRect.w, &mTextRect.h))
    254 				{
    255 					error = SDL_GetError();
    256 				}
    257 
    258 				mLinePosRect.w = mTextRect.w;
    259 				mLinePosRect.h = mTextRect.h;
    260 				mLinePosRect.x = x;
    261 				mLinePosRect.y = y;
    262 
    263 				if (SDL_RenderCopy(ren, LineTex, &mTextRect, &mLinePosRect))
    264 				{
    265 					error = SDL_GetError();
    266 				}
    267 				SDL_DestroyTexture(LineTex);
    268 			}
    269 		}
    270 	}
    271 protected:
    272 	TTF_Font* mFont;
    273 	SDL_Color mText;
    274 	SDL_Color mBG;
    275 	SDL_Rect mTextRect;
    276 	SDL_Rect mLinePosRect;
    277 	ConsoleStringManager mCSM;
    278 };
    279 
    280 int GetTimeF() //measures in frames
    281 {
    282 	int time = (clock() / CLOCKS_PER_FRAME);
    283 	return time;
    284 }
    285 
    286 int GetTimeMS() //measures in milliseconds
    287 {
    288 	int time = (clock() / (CLOCKS_PER_SEC/1000));
    289 	return time;
    290 }
    291 
    292 SDL_Surface* LoadSurfaceBMP(const char* filename)
    293 {
    294 	char* basepath = "C:\\Users\\baptistac1\\Documents\\Visual Studio 2013\\Projects\\TapestryEngine\\TapestryEngine\\imgs\\";
    295 
    296 	char pathbuffer[1024];
    297 	strcpy(pathbuffer, basepath);
    298 
    299 	SDL_Surface* surface = SDL_LoadBMP(strcat(pathbuffer, filename));
    300 	if (surface == NULL)
    301 	{
    302 		gCons->ConsPrintf("SDL_LoadBMP Error: %s", SDL_GetError());
    303 	}
    304 
    305 	SDL_SetColorKey(surface, SDL_TRUE, SDL_MapRGB(surface->format, 0xFF, 0x00, 0xFF));
    306 
    307 	return surface;
    308 }
    309 
    310 struct Frame
    311 {
    312 	SDL_Rect FrameRect;
    313 	SDL_Texture* FrameSource;
    314 };
    315 
    316 class FrameSet
    317 {
    318 public:
    319 	FrameSet() : mFrameCount(0), mFrames() {}
    320 
    321 	FrameSet(SDL_Renderer* ren, const char* SourcePath, int FrameCount, int FRate, int frameH, int frameW)
    322 	{
    323 		memset(mFrames, 0, 256);
    324 		mframesource = SDL_CreateTextureFromSurface(ren,LoadSurfaceBMP(SourcePath));
    325 		mFrameCount = (FrameCount - 1);
    326 		mDefaultFrameRate = FRate;
    327 
    328 		SDL_Rect framerect;
    329 		framerect.h = frameH;
    330 		framerect.w = frameW;
    331 		framerect.x = 0;
    332 		framerect.y = 0;
    333 
    334 		int i = 0;
    335 		while (i <= mFrameCount)
    336 		{
    337 			
    338 			framerect.x = ((i)*frameW);
    339 			
    340 			mFrames[i] = framerect;
    341 
    342 			i++;
    343 		}
    344 	}
    345 
    346 	int GetNumberOfFrames()
    347 	{
    348 		return mFrameCount;
    349 	}
    350 
    351 	int GetDefaultFrameRate()
    352 	{
    353 		return mDefaultFrameRate;
    354 	}
    355 
    356 	SDL_Texture* GetFrameSource()
    357 	{
    358 		return mframesource;
    359 	}
    360 
    361 	SDL_Rect GetFrameRect(int framenumber)
    362 	{
    363 		//gCons->ConsPrintf("Frame Number = %i\n", framenumber);
    364 		return mFrames[framenumber];
    365 	}
    366 
    367 protected:
    368 	int mFrameCount;
    369 	int mDefaultFrameRate;
    370 	SDL_Texture* mframesource;
    371 	SDL_Rect mFrames[256];
    372 };
    373 
    374 class animation
    375 {
    376 public:
    377 
    378 	animation() : mFrameSet(), mCurrentFrameNumber(0) {}
    379 
    380 	animation(FrameSet* set, bool flip = true)
    381 	{
    382 		mFrameSet = set;
    383 		mCurrentFrameNumber = 0;
    384 		mFrameRate = set->GetDefaultFrameRate();
    385 		mTimer = 0;
    386 		mIsFlippable = flip;
    387 		mIsPlaying = false;
    388 		mCurrentFrame.FrameSource = mFrameSet->GetFrameSource();
    389 		mCurrentFrame.FrameRect = mFrameSet->GetFrameRect(mCurrentFrameNumber);
    390 	}
    391 
    392 	Frame GetCurrentFrame()
    393 	{
    394 		mCurrentFrame.FrameRect = mFrameSet->GetFrameRect(mCurrentFrameNumber);
    395 		if (mIsPlaying == true)
    396 		{
    397 			if ((GetTimeMS() - mTimer) >= mFrameRate)
    398 			{
    399 				if (mCurrentFrameNumber == mFrameSet->GetNumberOfFrames())
    400 				{
    401 					mCurrentFrameNumber = 0;
    402 				}
    403 				else
    404 				{
    405 					mCurrentFrameNumber = (mCurrentFrameNumber + 1);
    406 				}
    407 				mTimer = GetTimeMS();
    408 			}
    409 		}
    410 		return mCurrentFrame;
    411 	}
    412 
    413 	bool SetPlaySpeed(int speed)
    414 	{
    415 		mFrameRate = speed;
    416 	}
    417 
    418 	bool IsFlippable()
    419 	{
    420 		return mIsFlippable;
    421 	}
    422 
    423 	bool Play()
    424 	{
    425 		return mIsPlaying = true;
    426 	}
    427 	bool Stop()
    428 	{
    429 		mCurrentFrameNumber = 0;
    430 		return mIsPlaying = false;
    431 	}
    432 
    433 protected:
    434 
    435 	FrameSet* mFrameSet;
    436 	int mCurrentFrameNumber;
    437 	Frame mCurrentFrame;
    438 	int mTimer;
    439 	int mFrameRate;
    440 	bool mIsFlippable;
    441 	bool mIsPlaying;
    442 };
    443 
    444 class animPack
    445 {
    446 public:
    447 	animPack() : mIndexer(), mAnimData() {}
    448 
    449 	animPack(int AnimCount, FrameSet** AnimData, int* Index)
    450 	{
    451 		mAnimData   = AnimData;
    452 		mIndexer = Index;
    453 		mAnimCount = AnimCount;
    454 
    455 		mAnims = new animation[AnimCount];
    456 		for ( int i = 0; i < mAnimCount; i++)
    457 		{
    458 			mAnims[i] = animation( mAnimData[i] );
    459 		}
    460 	}
    461 
    462 	FrameSet* GetAnimationData(int AnimationID)
    463 	{
    464 		for (int i = 0; i < mAnimCount; i++)
    465 		{
    466 			if (mIndexer[i] == AnimationID)
    467 			{
    468 				return mAnimData[i];
    469 			}
    470 		}
    471 	}
    472 
    473 	animation* GetAnimation(int AnimationID)
    474 	{
    475 		for (int i = 0; i < mAnimCount; i++)
    476 		{
    477 			if (mIndexer[i] == AnimationID)
    478 			{
    479 				if (mLastIndex != i)
    480 				{
    481 					mAnims[mLastIndex].Stop();
    482 					mLastIndex = i;
    483 				}
    484 
    485 				mAnims[i].Play();
    486 				return &mAnims[i];
    487 			}
    488 		}
    489 	}
    490 
    491 protected:
    492 
    493 	int		    mAnimCount;
    494 	int*        mIndexer;
    495 	int			mLastIndex;
    496 	FrameSet**  mAnimData;
    497 	animation*  mAnims;
    498 };
    499 
    500 
    501 class Terrain
    502 {
    503 public:
    504 	Terrain(SDL_Surface* Col_Map)
    505 	{
    506 		mCol_Map = Col_Map;
    507 	}
    508 
    509 	bool DetectGroundIntersect(SDL_Rect* Bounds)
    510 	{
    511 		if (mCol_Map->format->format != SDL_PIXELFORMAT_INDEX8)
    512 		{
    513 			gCons->ConsPrintf("Non-INDEX8 Collision Map Detected\n");
    514 		}
    515 
    516 		Uint8* PixMap = (Uint8*)mCol_Map->pixels;
    517 		if (Bounds->y < 0)
    518 		{
    519 			Bounds->y = 0;
    520 		}
    521 		for (int y = Bounds->y; y <= (Bounds->y + Bounds->h); y++)
    522 		{
    523 			if (Bounds->x < 0)
    524 			{
    525 				Bounds->x = 0;
    526 			}
    527 			for (int x = Bounds->x; x <= (Bounds->x + Bounds->w); x++)
    528 			{
    529 				if (PixMap[(y*mCol_Map->w) + x] == GROUND)
    530 				{
    531 					//gCons->ConsPrintf("ground collision detected \n");
    532 					return true;
    533 				}
    534 				else
    535 				{
    536 					//gCons->ConsPrintf("no collision detected \n");
    537 				}
    538 			}
    539 		}
    540 		return false;
    541 	}
    542 
    543 	bool DetectEdgeCollision(SDL_Rect* Bounds, int EdgeThickness)
    544 	{
    545 		//SDL_Rect LowerBounder;
    546 		LowerBounder.w = Bounds->w;
    547 		LowerBounder.x = Bounds->x;
    548 		LowerBounder.h = EdgeThickness;
    549 		LowerBounder.y = ((Bounds->y + Bounds->h) - EdgeThickness );
    550 
    551 		//SDL_Rect UpperBounder;
    552 		UpperBounder.w = Bounds->w;
    553 		UpperBounder.x = Bounds->x;
    554 		UpperBounder.h = EdgeThickness;
    555 		UpperBounder.y = Bounds->y;
    556 
    557 		//SDL_Rect RightBounder;
    558 		RightBounder.w = EdgeThickness;
    559 		RightBounder.x = ((Bounds->x + Bounds->w) - EdgeThickness);
    560 		RightBounder.h = Bounds->h;
    561 		RightBounder.y = Bounds->y;
    562 
    563 		//SDL_Rect LeftBounder;
    564 		LeftBounder.w = EdgeThickness;
    565 		LeftBounder.x = Bounds->x;
    566 		LeftBounder.h = Bounds->h;
    567 		LeftBounder.y = Bounds->y;
    568 
    569 		if ((DetectGroundIntersect(&LowerBounder) == true) ||
    570 			(DetectGroundIntersect(&UpperBounder) == true) ||
    571 			(DetectGroundIntersect(&RightBounder) == true) ||
    572 			(DetectGroundIntersect(&LeftBounder ) == true)  )
    573 		{
    574 			return true;
    575 		}
    576 		else
    577 		{
    578 			return false;
    579 		}
    580 	}
    581 
    582 	SDL_Rect LeftBounder;
    583 	SDL_Rect RightBounder;
    584 	SDL_Rect UpperBounder;
    585 	SDL_Rect LowerBounder;
    586 protected:
    587 
    588 	SDL_Surface* mCol_Map;
    589 
    590 };
    591 
    592 class Actor
    593 {
    594 public:
    595 
    596 	Actor() : mTex(), mHeight(0), mWidth(0), mX(0), mY(0) {}
    597 
    598 	Actor(SDL_Renderer* ren, Terrain* ter, animPack Anims, char* file, int Height, int Width, int X, int Y)
    599 	{
    600 		mTerrain = ter;
    601 		SDL_Surface* surface = LoadSurfaceBMP(file);
    602 		mTex = SDL_CreateTextureFromSurface(ren, surface); 
    603 		mAnimPack = Anims;
    604 		mHeight = Height;
    605 		mWidth = Width;
    606 		mX = X;
    607 		mY = Y;
    608 		mState = IDLE;
    609 	}
    610 
    611 	int MoveActorCollision(float xspd, float yspd)
    612 	{
    613 		SDL_Rect Destination;
    614 		Destination.h = mHeight;
    615 		Destination.w = mWidth;
    616 		Destination.x = (int)( (float)mX + (xspd*(GetTimeF() - mLastMoveUpdate)) );
    617 		Destination.y = (int)( (float)mY + (yspd*(GetTimeF() - mLastMoveUpdate)) );
    618 	
    619 		
    620 		if (mTerrain->DetectEdgeCollision(&Destination,5) == true)
    621 		{
    622 			MoveActorCollision( (int)((xspd)*(0.5)), (int)((yspd)*(0.5)) );
    623 		}
    624 		else
    625 		{
    626 			mX = Destination.x;
    627 			mY = Destination.y;
    628 		}
    629 		mLastMoveUpdate = GetTimeF();
    630 		return 0;
    631 	}
    632 
    633 	int MoveActor(float xspd, float yspd)
    634 	{
    635 		mX = mX + xspd*(GetTimeF() - mLastMoveUpdate);
    636 		mY = mY + yspd*(GetTimeF() - mLastMoveUpdate);
    637 		mLastMoveUpdate = GetTimeF();
    638 		return 0;
    639 	}
    640 
    641 	int walk(int spd)
    642 	{
    643 		
    644 		if (mDir == RIGHT)
    645 		{
    646 			MoveActorCollision( spd, 0);
    647 		}
    648 		else //mDIR == LEFT
    649 		{
    650 			MoveActorCollision(-spd, 0);
    651 		}
    652 		MoveActorCollision(0, 4);
    653 		return 0;
    654 	}
    655 
    656 	bool ControlActor(int xspd, int yspd, SDL_Event* eve)
    657 	{
    658 		if (eve->key.type == SDL_KEYUP)
    659 		{
    660 			mState = IDLE;
    661 			return 0;
    662 		}
    663 
    664 		switch (eve->key.keysym.sym)
    665 		{
    666 		case  SDLK_DOWN:
    667 			mState = RUN_DOWN;
    668 			break;
    669 		case    SDLK_UP:
    670 			mState = RUN_UP;
    671 			break;
    672 		case  SDLK_LEFT:
    673 			mState = RUN_LEFT;
    674 			mDir = LEFT;
    675 			break;
    676 		case SDLK_RIGHT:
    677 			mState = RUN_RIGHT;
    678 			mDir = RIGHT;
    679 			break;
    680 		}
    681 
    682 
    683 		//mLastMoveUpdate = GetTimeF();
    684 		return 0;
    685 	}
    686 
    687 	bool ActorUpdate()
    688 	{
    689 		int xspd = 3;
    690 		int yspd = 3;
    691 		
    692 		switch (mState)
    693 		{
    694 		case RUN_DOWN:
    695 			MoveActorCollision(0, yspd);
    696 			mFrame = mAnimPack.GetAnimation(RUN)->GetCurrentFrame();
    697 			//gCons->ConsPrintf("down\n");
    698 			break;
    699 		case RUN_UP:
    700 			MoveActorCollision(0, -yspd);
    701 			mFrame = mAnimPack.GetAnimation(RUN)->GetCurrentFrame();
    702 			//gCons->ConsPrintf("up\n");
    703 			break;
    704 		case RUN_LEFT:
    705 			walk(xspd);
    706 			mFrame = mAnimPack.GetAnimation(RUN)->GetCurrentFrame();
    707 			//gCons->ConsPrintf("left\n");
    708 			break;
    709 		case RUN_RIGHT:
    710 			walk(xspd);
    711 			mFrame = mAnimPack.GetAnimation(RUN)->GetCurrentFrame();
    712 			//gCons->ConsPrintf("right\n");
    713 			break;
    714 		case IDLE:
    715 			mFrame = mAnimPack.GetAnimation(IDLE)->GetCurrentFrame();
    716 			//gCons->ConsPrintf("idle\n");
    717 			mLastMoveUpdate = GetTimeF();
    718 			break;
    719 		default:
    720 			return false;
    721 		}
    722 		return true;
    723 	}
    724 
    725 	int GetX()
    726 	{
    727 		return mX;
    728 	}
    729 
    730 	int GetY()
    731 	{
    732 		return mY;
    733 	}
    734 
    735 	int GetHeight()
    736 	{
    737 		return mHeight;
    738 	}
    739 
    740 	int GetWidth()
    741 	{
    742 		return mWidth;
    743 	}
    744 
    745 	SDL_Rect GetRect()
    746 	{
    747 		SDL_Rect Bounds;
    748 		Bounds.x = mX;
    749 		Bounds.y = mY;
    750 		Bounds.h = mHeight;
    751 		Bounds.w = mWidth;
    752 
    753 		return Bounds;
    754 	}
    755 
    756 	SDL_Texture* GetTex()
    757 	{
    758 		return mTex;
    759 	}
    760 
    761 	Frame GetFrame()
    762 	{
    763 		return mFrame;
    764 	}
    765 
    766 	int GetState()
    767 	{
    768 		return mState;
    769 	}
    770 
    771 	int GetDir()
    772 	{
    773 		return mDir;
    774 	}
    775 
    776 protected:
    777 	
    778 	SDL_Texture* mTex;
    779 	Terrain* mTerrain;
    780 	animPack mAnimPack;
    781 	Frame mFrame;
    782 	int mState;
    783 	int mDir;
    784 	int mHeight;
    785 	int mWidth;
    786 	int mX;
    787 	int mY;
    788 	int mLastMoveUpdate;
    789 };
    790 
    791 
    792 class Camera
    793 {
    794 public:
    795 	Camera() : view(), wrldX(), wrldY()  {}
    796 
    797 	Camera(int H, int W, int X, int Y)
    798 	{
    799 		view.h = H;
    800 		view.w = W;
    801 
    802 		wrldX = X;
    803 		wrldY = Y;
    804 		view.x = wrldX;
    805 		view.y = wrldY;
    806 	}
    807 
    808 	int GetCamX()
    809 	{
    810 		return wrldX;
    811 	}
    812 
    813 	int GetCamY()
    814 	{
    815 		return wrldY;
    816 	}
    817 
    818 	SDL_Rect* GetCamView()
    819 	{
    820 		return &view;
    821 	}
    822 
    823 	void CamResize(int H, int W)
    824 	{
    825 		view.h = H;
    826 		view.w = W;
    827 	}
    828 
    829 	SDL_Rect SetCameraPos(SDL_Renderer* ren, int Xpos, int Ypos)
    830 	{
    831 		wrldX = Xpos;
    832 		wrldY = Ypos;
    833 
    834 		if (Xpos < 0)
    835 		{
    836 			wrldX = 0;
    837 		}
    838 		else if ( (Xpos + view.w) > WORLD_W)
    839 		{
    840 			wrldX = WORLD_W - view.w;
    841 		}
    842 
    843 		if (Ypos < 0)
    844 		{
    845 			wrldY = 0;
    846 		}
    847 		else if ((Ypos + view.h) > WORLD_H)
    848 		{
    849 			wrldY = WORLD_H - view.h;
    850 		}
    851 
    852 		view.x = wrldX;
    853 		view.y = wrldY;
    854 
    855 		//gCons->ConsPrintf("cam bounds: x= %i - %i, y= %i - %i \n", view.x, (view.x + view.w), view.y, (view.y + view.h));
    856 
    857 		return view;
    858 	}
    859 
    860 	SDL_Rect SetCameraPosUnbounded(SDL_Renderer* ren, int Xpos, int Ypos)
    861 	{
    862 		wrldX = Xpos;
    863 		wrldY = Ypos;
    864 
    865 		view.x = wrldX;
    866 		view.y = wrldY;
    867 
    868 		//gCons->ConsPrintf("cam bounds: x= %i - %i, y= %i - %i \n", view.x, (view.x + view.w), view.y, (view.y + view.h));
    869 
    870 		return view;
    871 	}
    872 
    873 	bool ArrowKeyMove(SDL_Renderer* ren, int xspd, int yspd, SDL_Event* eve)
    874 	{
    875 		if (eve->key.type == SDL_KEYUP) return 0;
    876 
    877 		switch (eve->key.keysym.sym)
    878 		{
    879 		case  SDLK_DOWN: 
    880 			wrldY = wrldY + yspd;
    881 			break;
    882 		case    SDLK_UP: 
    883 			wrldY = wrldY + -yspd;
    884 			break;
    885 		case  SDLK_LEFT: 
    886 			wrldX = wrldX + -xspd;
    887 			break;
    888 		case SDLK_RIGHT: 
    889 			wrldX = wrldX + xspd;
    890 			break;
    891 		}
    892 		mLastMoveUpdate = GetTimeF();
    893 		SetCameraPos(ren, wrldX, wrldY);
    894 		return 0;
    895 	}
    896 
    897 	bool ActorFollow(SDL_Renderer* ren, Actor act, int Xbound, int Ybound)
    898 	{
    899 		if (act.GetX() < (wrldX + Xbound))
    900 		{
    901 			wrldX = (act.GetX() - Xbound);
    902 			//gCons->ConsPrintf("LEFT\n");
    903 		}
    904 		if (act.GetX() + act.GetWidth() > ((wrldX + view.w) - Xbound))
    905 		{
    906 			wrldX = act.GetX() + act.GetWidth() - view.w + Xbound ;
    907 			//gCons->ConsPrintf("RIGHT\n");
    908 		}
    909 		
    910 		if (act.GetY() < (wrldY + Ybound))
    911 		{
    912 			wrldY = (act.GetY() - Ybound);
    913 			//gCons->ConsPrintf("LEFT\n");
    914 		}
    915 		if (act.GetY() + act.GetHeight() > ((wrldY + view.h) - Ybound))
    916 		{
    917 			wrldY = act.GetY() + act.GetHeight() - view.h + Ybound;
    918 			//gCons->ConsPrintf("RIGHT\n");
    919 		}
    920 		mLastMoveUpdate = GetTimeF();
    921 		SetCameraPos(ren, wrldX, wrldY);
    922 		return 0;
    923 	}
    924 
    925 protected:
    926 	SDL_Rect view;
    927 	int wrldX;
    928 	int wrldY;
    929 	int mLastMoveUpdate;
    930 };
    931 
    932 SDL_Rect GetScreenPos(Actor act, Camera cam)
    933 {
    934 	SDL_Rect ScreenPos;
    935 	ScreenPos.h = (int)((float)(act.GetHeight())*((float)(SCREEN_H) / (float)( cam.GetCamView()->h )));
    936 	ScreenPos.w = (int)((float)(act.GetWidth())*((float)(SCREEN_W) / (float)( cam.GetCamView()->w )));
    937 
    938 	ScreenPos.x = (int)((float)(act.GetX() - cam.GetCamX())*((float)(SCREEN_W) / (float)( cam.GetCamView()->w )));
    939 	ScreenPos.y = (int)((float)(act.GetY() - cam.GetCamY())*((float)(SCREEN_H) / (float)( cam.GetCamView()->h )));
    940 
    941 	return ScreenPos;
    942 }
    943 
    944 SDL_Rect DrawActorTex(SDL_Renderer* ren, Actor act, Camera cam)
    945 {
    946 	SDL_Rect ScreenPos = GetScreenPos(act, cam);
    947 	
    948 	SDL_RenderCopy(ren, act.GetTex(), NULL, &ScreenPos);
    949 	return ScreenPos;
    950 }
    951 
    952 SDL_Rect DrawActorAnim(SDL_Renderer* ren, Actor act, animation* anim, Camera cam, int dir)
    953 {
    954 	SDL_Rect ScreenPos = GetScreenPos(act, cam);
    955 
    956 	Frame RenderFrame = anim->GetCurrentFrame();
    957 
    958 	SDL_RendererFlip flip;
    959 
    960 	if (anim->IsFlippable() == true)
    961 	{
    962 		flip = (SDL_RendererFlip)act.GetDir();
    963 	}
    964 	else
    965 	{
    966 		flip = SDL_FLIP_NONE;
    967 	}
    968 	SDL_RenderCopyEx(ren, RenderFrame.FrameSource, &(RenderFrame.FrameRect), &ScreenPos, 0, NULL, flip);
    969 
    970 	return ScreenPos;
    971 }
    972 
    973 SDL_Rect DrawActor(SDL_Renderer* ren, Actor act, Camera cam)
    974 {
    975 	SDL_Rect ScreenPos = GetScreenPos(act, cam);
    976 
    977 	Frame RenderFrame = act.GetFrame();
    978 
    979 	SDL_RendererFlip flip;
    980 	flip = (SDL_RendererFlip)act.GetDir();
    981 	
    982 	SDL_RenderCopyEx(ren, RenderFrame.FrameSource, &(RenderFrame.FrameRect), &ScreenPos, 0, NULL, flip);
    983 
    984 	return ScreenPos;
    985 }
    986 
    987 bool DrawRect(SDL_Renderer* ren, SDL_Rect WrldPos, Camera cam)
    988 {
    989 	SDL_Rect ScreenPos;
    990 	ScreenPos.h = (int)((float)(WrldPos.h)*((float)(SCREEN_H) / (float)(cam.GetCamView()->h)));
    991 	ScreenPos.w = (int)((float)(WrldPos.w)*((float)(SCREEN_W) / (float)(cam.GetCamView()->w)));
    992 
    993 	ScreenPos.x = (int)((float)(WrldPos.x - cam.GetCamX())*((float)(SCREEN_W) / (float)(cam.GetCamView()->w)));
    994 	ScreenPos.y = (int)((float)(WrldPos.y - cam.GetCamY())*((float)(SCREEN_H) / (float)(cam.GetCamView()->h)));
    995 
    996 	SDL_Surface* Bounds    = LoadSurfaceBMP("BoundingBox.bmp");
    997 	SDL_Texture* BoundsTex = SDL_CreateTextureFromSurface(ren, Bounds);
    998 
    999 	SDL_RenderCopy(ren, BoundsTex, NULL, &ScreenPos);
   1000 
   1001 	return false;
   1002 }
   1003 
   1004 int main(int argc, char *argv[])
   1005 {
   1006 	if (SDL_Init(SDL_INIT_VIDEO & SDL_INIT_EVENTS) != 0)
   1007 	{
   1008 		gCons->ConsPrintf("SDL_Init Error: %s\n", SDL_GetError());
   1009 		SDL_Quit();
   1010 		return 1;
   1011 	}
   1012 
   1013 	if (TTF_Init() != 0)
   1014 	{
   1015 		gCons->ConsPrintf("TTF_Init Error: %s\n", TTF_GetError());
   1016 		TTF_Quit();
   1017 		SDL_Quit();
   1018 		return 1;
   1019 	}
   1020 	
   1021 	SDL_Window* window = SDL_CreateWindow("Bandana Marathon", 10, 30, SCREEN_W, SCREEN_H, SDL_WINDOW_SHOWN);
   1022 	if (window == NULL)
   1023 	{
   1024 		gCons->ConsPrintf("SDL_CreateWindow Error: %s", SDL_GetError());
   1025 		SDL_Quit();
   1026 		return 1;
   1027 	}
   1028 	
   1029 	SDL_Color fg = { 255, 255, 255 };
   1030 	SDL_Color bg = { 0, 0, 255 };
   1031 	
   1032 	gCons = new Console("ARIAL.TTF", 12, fg, bg);
   1033 	rCons = new Console("ARIAL.TTF", 12, fg, bg);
   1034 
   1035 	Camera cam = Camera(468, 832, 700, 0);
   1036 
   1037 	SDL_Renderer* ren = SDL_CreateRenderer(window, -1, SDL_RENDERER_ACCELERATED | SDL_RENDERER_PRESENTVSYNC);
   1038 	if (ren == NULL)
   1039 	{
   1040 		gCons->ConsPrintf("SDL_CreateRenderer Error: %s", SDL_GetError());
   1041 		SDL_Quit();
   1042 		return 1;
   1043 	}
   1044 
   1045 	FrameSet  RunManSet     = FrameSet(ren, "BandanaManRun.bmp", 14, 50, 150, 75);
   1046 	animation RunMan        = animation(&RunManSet, 1000);
   1047 	FrameSet  RunManPlusSet = FrameSet(ren, "BandanaManPlus.bmp", 14, 50, 150, 75);
   1048 	animation RunManPlus    = animation(&RunManPlusSet, 50);
   1049 	FrameSet  RunWomanSet	= FrameSet(ren, "BandanaWomanRun.bmp", 14, 50, 150, 75);
   1050 	animation RunWoman      = animation(&RunWomanSet, 50);
   1051 	
   1052 	
   1053 	FrameSet  PlayerRunSet = FrameSet(ren, "player_run.bmp", 15, 50, 30, 30);
   1054 	FrameSet  PlayerTempIdle = FrameSet(ren, "player_idle_standin.bmp", 15, 50, 30, 30);
   1055 
   1056 	//NULL Animation Pack Construction
   1057 	int NULL_AnimCount = 2;
   1058 	FrameSet** NullPack = (FrameSet**)malloc(NULL_AnimCount * sizeof(FrameSet*));
   1059 	int* NullIndex = (int*)malloc(NULL_AnimCount * sizeof(int));
   1060 	NullPack[0] = &PlayerTempIdle;
   1061 	NullPack[1] = &PlayerRunSet;
   1062 	NullIndex[0] = IDLE;
   1063 	NullIndex[1] = RUN;
   1064 	animPack NULLPack = animPack(NULL_AnimCount, NullPack, NullIndex);
   1065 	//
   1066 
   1067 	//Player Animation Pack Construction
   1068 	int Player_AnimCount = 2;
   1069 	FrameSet** PlayerAnimPack = (FrameSet**)malloc(Player_AnimCount * sizeof(FrameSet*));
   1070 	int* PlayerIndex = (int*)malloc(Player_AnimCount * sizeof(int));
   1071 	PlayerAnimPack[0] = &PlayerTempIdle;
   1072 	PlayerAnimPack[1] = &PlayerRunSet;
   1073 	PlayerIndex[0] = IDLE;
   1074 	PlayerIndex[1] = RUN;
   1075 	animPack PlayerPack = animPack(Player_AnimCount,PlayerAnimPack,PlayerIndex);
   1076 	//
   1077 
   1078 	TTF_Font* arial = TTF_OpenFont("C:\\Users\\baptistac1\\Documents\\Visual Studio 2013\\Projects\\LearnEngine\\LearnEngine\\fonts\\ARIAL.TTF", 12);
   1079 
   1080 	SDL_Surface* surface = LoadSurfaceBMP("FloatingDirtLand.bmp");
   1081 
   1082 	SDL_Texture* Back = SDL_CreateTextureFromSurface(ren, surface);
   1083 
   1084 
   1085 	int w;
   1086 	int h;
   1087 	SDL_QueryTexture(Back, NULL, NULL, &w, &h);
   1088 
   1089 
   1090 	Terrain ter = Terrain(surface);
   1091 
   1092 	Actor bandanaman         = Actor(ren, &ter, NULLPack, "RedBox.bmp", 290, 160, 740, 640);
   1093 	Actor bandanamanplus	 = Actor(ren, &ter, NULLPack, "RedBox.bmp", 290, 160, 460, 640);
   1094 	Actor minibandanamanplus = Actor(ren, &ter, PlayerPack, "RedBox.bmp", 30, 30, 460, 675);
   1095 	Actor bandanawoman		 = Actor(ren, &ter, NULLPack, "RedBox.bmp", 290, 160, 300, 640);
   1096 	Actor redbox1			 = Actor(ren, &ter, NULLPack, "RedBoxWithTrans.bmp", 200, 200, 0, 0);
   1097 	Actor bluebox1			 = Actor(ren, &ter, NULLPack, "BlueBox.bmp", 200, 200, 100, 400);
   1098 	Actor lilred		 	 = Actor(ren, &ter, NULLPack, "lilred.bmp", 1, 1, 1, 1); //It's lil' red, the debug pixel!
   1099 
   1100 	//Actor Cast[100];
   1101 	//for (int i = 0; i < 100; i++)
   1102 	//{
   1103 	//	Cast[i] = Actor(ren, "RedBox.bmp", 290, 160, i*70, 340);
   1104 	//}
   1105 
   1106 	SDL_Rect wrldrect;
   1107 	wrldrect.w = (int)(((float)SCREEN_W));
   1108 	wrldrect.h = (int)(((float)SCREEN_H));
   1109 	wrldrect.x = 0;
   1110 	wrldrect.y = 0;
   1111 
   1112 	int cycle = 0;
   1113 
   1114 	SDL_Event e;
   1115 
   1116 	bool quit = false;
   1117 	bool forward = true;
   1118 	while (!quit)
   1119 	{
   1120 		int CycleStart = GetTimeMS();
   1121 		//gCons->ConsPrintf("HELLO WORLD! %i\n", cycle);
   1122 		//gCons->ConsPrintf("Blu pos: x = %i, y = %i\n", bluebox1.GetX(), bluebox1.GetY());
   1123 		//gCons->ConsPrintf("Red Wrld pos: x = %i, y = %i\n", redbox1.GetX(), redbox1.GetY());
   1124 		//gCons->ConsPrintf("Red Wrld pos: x = %i, y = %i\n", lilred.GetX(), lilred.GetY());
   1125 
   1126 		//gCons->ConsPrintf("time(ms) = %i \n", GetTimeMS());
   1127 
   1128 		SDL_RenderClear(ren);
   1129 		SDL_RenderCopy(ren, Back, cam.GetCamView(), NULL);
   1130 
   1131 		//cam.SetCameraPos(ren, (redbox1.GetX()-0), redbox1.GetY()-0);
   1132 		//cam.ArrowKeyMove(ren, 10, 10, &e);
   1133 		minibandanamanplus.ControlActor(6, 6, &e);
   1134 		minibandanamanplus.ActorUpdate();
   1135 		cam.ActorFollow(ren, minibandanamanplus, 200 , 150);
   1136 
   1137 		DrawActorTex(ren, bluebox1, cam);
   1138 		//SDL_Rect ScrPos = DrawActorTex(ren, redbox1, cam);
   1139 		//SDL_Rect ScrPos = DrawActorTex(ren, lilred, cam);
   1140 		//gCons->ConsPrintf("Red Scrn Pos: x = %i, y = %i\n", ScrPos.x, ScrPos.y);
   1141 		//rCons->ConsPrintf("Red Scrn Pos: x = %i, y = %i\n", ScrPos.x, ScrPos.y);
   1142 
   1143 //		DrawActorAnim(ren, bandanaman, &RunMan, cam, SDL_FLIP_NONE);
   1144 //		DrawActorAnim(ren, bandanawoman, &RunWoman, cam, SDL_FLIP_NONE);
   1145 //		DrawActorAnim(ren, bandanamanplus, &RunManPlus, cam, SDL_FLIP_NONE);
   1146 
   1147 		//DrawActorTex(ren, minibandanamanplus, cam);
   1148 		DrawActor(ren, minibandanamanplus, cam);
   1149 		DrawRect(ren, ter.LowerBounder, cam);
   1150 		DrawRect(ren, ter.UpperBounder, cam);
   1151 		DrawRect(ren, ter.LeftBounder, cam);
   1152 		DrawRect(ren, ter.RightBounder, cam);
   1153 		//DrawActorAnim(ren, minibandanamanplus, &PlayerTempIdleTest, cam, minibandanamanplus.GetDir());
   1154 
   1155 		ter.DetectGroundIntersect(&minibandanamanplus.GetRect());
   1156 
   1157 		rCons->DrawConsoleReadout(ren, 400, 0);
   1158 		gCons->DrawConsole(ren);
   1159 		
   1160 
   1161 		SDL_RenderPresent(ren);
   1162 		
   1163 		if ((redbox1.GetX() + (redbox1.GetWidth())) > WORLD_W)
   1164 		{
   1165 			forward = false;
   1166 		}
   1167 		if (redbox1.GetX() < 0)
   1168 		{
   1169 			forward = true;
   1170 		}
   1171 
   1172 		if (forward == true)
   1173 		{
   1174 			//redbox1.MoveActorCollision(5, 2);
   1175 			//bluebox1.MoveActorCollision(5, -2);
   1176 		}
   1177 		else
   1178 		{
   1179 			//redbox1.MoveActorCollision(-5, -2);
   1180 			//bluebox1.MoveActorCollision(-5, 2);
   1181 		}
   1182 
   1183 		SDL_PollEvent(&e);
   1184 
   1185 		if (e.type == SDL_QUIT)
   1186 		{
   1187 			quit = true;
   1188 		}
   1189 		cycle = cycle + 1;
   1190 		
   1191 		int DeltaTime = (GetTimeMS() - CycleStart);
   1192 		assert(DeltaTime >= 0);
   1193 
   1194 		int DelayTime = MS_PER_FRAME - DeltaTime;
   1195 
   1196 		if (DelayTime >= 0)
   1197 		{
   1198 			//gCons->ConsPrintf("Delay Time: %i \n", DelayTime);
   1199 			SDL_Delay(DelayTime);
   1200 		}
   1201 		else
   1202 		{
   1203 			//gCons->ConsPrintf("Delay Time: %i FRAME DROP\n", DelayTime);
   1204 		}
   1205 	}
   1206 
   1207 	delete gCons;
   1208 	SDL_FreeSurface(surface);
   1209 	SDL_DestroyWindow(window);
   1210 	SDL_Quit();
   1211 	return 0;
   1212 }