How do I link these files correctly?

Hi I am construction a prototype game engine from the book SDL game development. So far I have managed to get an animated sprite on the screen but when I move on to the next section, animating it and having it move and adding TextureManager.h and TextureManager.cpp files I am am getting a lot of errors when I try to debug the code. Can anyone tell me in which files I should place the include directives and preprocessor directives. I know I have not got my includes right because of the amount of errors I am getting but I am a noob in C++ so can someone please show me how to set up the right includes in these files so I can debug them.

Thanks

main.cpp

#include <SDL2/SDL.h>
#include <SDL2/SDL_image.h>
#include <iostream>
#include <string>
#include "TextureManager.cpp"
#include "Game.cpp"



int main(int argc, char * args[])
{
Game * g_game = new Game;

g_game->init("Chapter 1", 100,100,640,480,false);

while(g_game->running())
{
	g_game->handleEvents();
	g_game->update();
	g_game->render();
}
g_game->clean();

return 0;

}

Game.h

#ifndef Game
#define Game

class Game
{
public:
Game() {}
~Game() {}

bool init(const char* title, int xpos, int ypos, int width,
int height, bool fullscreen);
void renderer();
void render();
void update();
void handleEvents();
void clean();

// a function to access the private running variable
bool running() {return m_bRunning;}

private:

SDL_Window * m_pWindow;
SDL_Renderer * m_pRenderer;
int m_currentFrame;
TextureManager m_textureManager;

bool m_bRunning;
};

#endif /* defined(Game_h) */

Game.cpp

#include “Game.h”

bool Game::init(const char* title, int xpos, int ypos, int width,
int height, bool fullscreen)
{

int flags = 0;

if (fullscreen)
{
flags = SDL_WINDOW_FULLSCREEN;
}

// attempt to initialize SDL
if(SDL_Init(SDL_INIT_EVERYTHING) == 0)
{
std::cout<<“SDL Init Success\n”;
// init the window
m_pWindow = SDL_CreateWindow(title, xpos, ypos, width, height, flags);

  if(m_pWindow != 0) //window init success
  {
  std::cout<<"Window Creation Success\n";
  m_pRenderer = SDL_CreateRenderer(m_pWindow, -1, 0);

  	if(m_pRenderer !=0) // render init success
  	{
  	std::cout<<"Renderer Creation Success\n";
  	SDL_SetRenderDrawColor(m_pRenderer, 255,0,0,255);
  	}	
  	else
  	{
  	std::cout<<"Renderer Init Fail\n";
  	return false; // renderer init fail
  	}

m_textureManager.load(“assets/animate-alpha.png”,“animate”, m_pRenderer);
//SDL_Surface * pTempSurface = IMG_Load(“assets/animate-alpha.png”);
//if(pTempSurface !=0)
//{
//std::cout<<“LoadBMP Success!\n”;
//}
//else
//{
//printf(“LoadBMP failed: %s\n”, SDL_GetError());
//}
m_pTexture = SDL_CreateTextureFromSurface(m_pRenderer,pTempSurface);
if(m_pTexture !=0)
{
std::cout<<“CreateTextureFromSurface Success!\n”;
}
else
{
printf(“CreateTextureFromSurface failed: %s\n”, SDL_GetError());
}
SDL_FreeSurface(pTempSurface);
//SDL_QueryTexture(m_pTexture, NULL,NULL,&m_sourceRectangle.w,&m_sourceRectangle.h);
m_destinationRectangle.x = m_sourceRectangle.x =0;
m_destinationRectangle.y = m_sourceRectangle.y =0;
m_destinationRectangle.w = m_sourceRectangle.w =128;
m_destinationRectangle.h = m_sourceRectangle.h =82;

}

else
{
std::cout<<“Window Init Fail\n”;
return false; //window init fail
}

}

else
{
std::cout<<“SDL Init Fail\n”;
return false; // SDL init fail
}

std::cout<<“Init success\n”;
m_bRunning = true; // everything inited successfully
// start the main loop

return true;

}

void Game::renderer()
{
SDL_RenderClear(m_pRenderer); // clears the renderer
// to the draw colour

SDL_RenderCopyEx(m_pRenderer, m_pTexture, &m_sourceRectangle,&m_destinationRectangle, 0, 0, SDL_FLIP_HORIZONTAL);

SDL_RenderPresent(m_pRenderer); // draw to the screen
}

void Game::render()
{
SDL_RenderClear(m_pRenderer);

m_textureManager.draw(“animate”, 0,0, 128, 82, m_pRenderer);

m_textureManager.drawFrame(“animate”, 100, 100, 128, 82, 1, m_currentFrame, m_pRenderer);

SDL_RenderPresent(m_pRenderer);

}

void Game::update()
{
m_currentFrame = int(((SDL_GetTicks() / 100) % 6));
}

void Game::clean()
{
std::cout<<“Cleaning game\n”;
SDL_DestroyWindow(m_pWindow);
SDL_DestroyRenderer(m_pRenderer);
SDL_Quit();
}

void Game::handleEvents()
{
SDL_Event event;
if(SDL_PollEvent(&event))
{
switch (event.type)
{
case SDL_QUIT:
m_bRunning = false;
break;
}
}
}

TextureManager.cpp

#include “TextureManager.h”

bool TextureManager::load(std::string fileName, std::string id, SDL_Renderer* pRenderer)
{
SDL_Surface* pTempSurface = IMG_Load(fileName.c_str());

if(pTempSurface == 0)
{
return false;
}

SDL_Texture* pTexture =
SDL_CreateTextureFromSurface(pRenderer, pTempSurface);

SDL_FreeSurface(pTempSurface);

// everything went ok, add texture to our list
if(pTexture !=0)
{
m_textureMap[id] = pTexture;
return true;
}

// reaching here means something went wrong
return false;
}

void TextureManager::draw(std::string id, int x, int y, int width, int height, SDL_Renderer* pRenderer, SDL_RendererFlip flip)
{
SDL_Rect srcRect;
SDL_Rect destRect;

srcRect.x =0;
srcRect.y =0;
srcRect.w = destRect.w = width;
srcRect.h = destRect.h = height;
destRect.x =x;
destRect.y =y;

SDL_RenderCopyEx(pRenderer, m_textureMap[id], &srcRect, &destRect, 0, 0, flip);
}

void TextureManager::drawFrame(std::string id, int x, int y, int width, int height, int currentRow,
int currentFrame, SDL_Renderer *pRenderer, SDL_RendererFlip flip)
{
SDL_Rect srcRect;
SDL_Rect destRect;
srcRect.x = width * currentFrame;
srcRect.y = height * (currentRow -1);
srcRect.w = destRect.w = width;
srcRect.h = destRect.h = height;
destRect.x = x;
destRect.y = y;

SDL_RenderCopyEx(pRenderer, m_textureMap[id], &srcRect, &destRect, 0,0, flip);
}

TextureManager.h

#ifndef TextureManager
#define TextureManager

class TextureManager
{
public:
TextureManager(){}
~TextureManager(){}

bool load(std::string fileName, std::string id, SDL_Renderer* pRenderer);

//draw
void draw(std::string id, int x, int y, int width, int height, SDL_Renderer* pRenderer, SDL_RendererFlip flip = SDL_FLIP_NONE);

// drawframe
void drawFrame(std::string id, int x, int y, int width, int height, int currentRow, int currentFrame, SDL_Renderer* pRenderer, SDL_RendererFlip flip = SDL_FLIP_NONE);

std::map<std::string, SDLTexture*> m_textureMap;

private:
};

#endif /* defined(TextureManager_h) */

That is a LOT of code right there, so there may be some other issues, but here is one I notice immediately at the very top of your post.

I notice you have a lot of #include "filename.cpp" whereas you most likely want #include "filename.h". The entire purpose of the headers is so that definitions (what’s in a class, what arguments are taken by a function, etc.) are inserted into other source files. Under normal circumstances, the content of a .cpp is only meant to ever show up once in compilation.

So here is a brief demonstration of what the purpose is of a header (.h) file versus a source file (.cpp).

Let’s say you have three files with the following contents (by the way to be clear, this very next code block is the one representing the “correct” solution):

// main.cpp
#include "myclass.h"
int main () 
{
	MyClass m;
	float n = m.AddNumbers(1.2f,0.5f);
	return 0;
};

// myclass.cpp
#include "myclass.h"
float MyClass::DoSomething (float a, float b)
{
	return a + b;
};

// myclass.h
class MyClass 
{
	float DoSomething (float a, float b);
};

The reason myclass.h has only definitions, and no code that actually “does anything” is because this is what the source files look like after the #include statements are processed:

// main.cpp after the preprocessor is done 
class MyClass 
{
	float DoSomething (float a, float b);
};
int main () 
{
	MyClass m;
	float n = m.AddNumbers(1.2f,0.5f);
	return 0;
};

// myclass.cpp after the preprocessor is done
class MyClass 
{
	float DoSomething (float a, float b);
}; 
float MyClass::DoSomething (float a, float b)
{
	return a + b;
};

Instead, if you were to #include "myclass.cpp" into main.cpp for example, you’d get this result:

// main.cpp after including myclass.cpp instead of myclass.h 
float MyClass::DoSomething (float a, float b)
{
	return a + b;
};
int main () 
{
	MyClass m;
	float n = m.AddNumbers(1.2f,0.5f);
	return 0;
};

This is not going to work since MyClass hasn’t actually been defined within this compilation unit.

What if we don’t use a header at all and put a whole class definition (layout and functions implemented) into the .cpp file?

// myclass_v2.cpp v2
class MyClass 
{
	float DoSomething (float a, float b) 
	{
		return a + b;
	};
};

// main.cpp after including myclass_v2.cpp
class MyClass 
{
	float DoSomething (float a, float b) 
	{
		return a + b;
	};
};
int main () 
{
	MyClass m;
	float n = m.AddNumbers(1.2f,0.5f);
	return 0;
};

This might seem intuitive for a moment but the compiler is already going to compile myclass_v2.cpp itself, and then it’s also going to compile main.cpp, and then it’s going to link them together before it’s done producing your program. And if so, float DoSomething (float a, float b) has been defined in two places, which results in a conflict the linker can’t resolve, so it will throw some errors.

Here is the general idea: the actual code of functions goes into .cpp files, class definitions and function declarations (just the prototype) go into .h files, and you should pretty much never #include "anything.cpp". There are some exceptions to these rules, for example if a function is inline then the function’s code goes into the header.

Thanks for your help guys I got it running in the end.